diff options
Diffstat (limited to 'openecomp-ui')
427 files changed, 11147 insertions, 4799 deletions
diff --git a/openecomp-ui/.eslintrc b/openecomp-ui/.eslintrc index 63da329372..baa1391245 100644 --- a/openecomp-ui/.eslintrc +++ b/openecomp-ui/.eslintrc @@ -32,6 +32,7 @@ "DEV": true, "Blob": true, "XMLHttpRequest": true, + "WebSocket": true, "URL": true, "PunchOutRegistry": true, "it": true, diff --git a/openecomp-ui/devConfig.defaults.json b/openecomp-ui/devConfig.defaults.json index 99380b1e50..059d380618 100644 --- a/openecomp-ui/devConfig.defaults.json +++ b/openecomp-ui/devConfig.defaults.json @@ -1,6 +1,7 @@ { "port": 9000, "proxyCatalogTarget": null, + "proxyWebsocketTarget": null, "proxyTarget": null, "bundles": { "bundle": ["sdc-app/sdc.app.jsx"], diff --git a/openecomp-ui/gulpfile.js b/openecomp-ui/gulpfile.js index 6d45a0b374..8ca9a233aa 100644 --- a/openecomp-ui/gulpfile.js +++ b/openecomp-ui/gulpfile.js @@ -38,7 +38,7 @@ const path = { // output output: dist, css: dist + '/css', - svg: dist + '/resources/images/svg', +// svg: dist + '/resources/images/svg', appinf_output: dist + '/webapp-onboarding', healthCheckOutput: dist + '/v1.0', // war @@ -48,8 +48,8 @@ const path = { // storybook storybookFonts: './.storybook/fonts/*', storybookDist: './.storybook-dist', - storybookResources: './.storybook/resources/onboarding/resources/images/svg', - storybookDistResources: './.storybook-dist/onboarding/resources/images/svg' + //storybookResources: './.storybook/resources/onboarding/resources/images/svg', + //storybookDistResources: './.storybook-dist/onboarding/resources/images/svg' }; // cleans up the output directory taskMaker.defineTask('clean', {taskName: 'clean', src: path.output}); @@ -57,10 +57,10 @@ 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}); +//taskMaker.defineTask('copy', {taskName: 'copy-svg', src: path.svgSrc, dest: path.svg}); 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}); +//taskMaker.defineTask('copy', {taskName: 'copy-storybook-resources', src: path.svgSrc, dest: path.storybookResources}); +//taskMaker.defineTask('copy', {taskName: 'copy-storybook-resources-prod', src: path.svgSrc, dest: path.storybookDistResources}); // used for compressing war files taskMaker.defineTask('compress', {taskName: 'compress-war', src: path.war, filename: appName + '.war', dest: path.wardest}); taskMaker.defineTask('compress', {taskName: 'compress-heat-war', src: path.heatWar, filename: 'heat-validation.war', dest: path.wardest}); @@ -94,7 +94,7 @@ gulp.task('app-context', function(){ }) }); // aggregates all copy tasks -gulp.task('copy-stuff', callback => runSequence(['copy-json', 'copy-index.html', 'copy-heat.html', 'copy-svg', 'app-context'], callback)); +gulp.task('copy-stuff', callback => runSequence(['copy-json', 'copy-index.html', 'copy-heat.html', 'app-context'], callback)); // minimum build for dev gulp.task('dev', callback => runSequence('clean', 'copy-stuff', callback)); diff --git a/openecomp-ui/package.json b/openecomp-ui/package.json index 6e13e269d2..c3875ab5d0 100644 --- a/openecomp-ui/package.json +++ b/openecomp-ui/package.json @@ -14,14 +14,16 @@ "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", + "test-build": "jest --coverage", + "storybook": "start-storybook -p 9090 -c .storybook -s .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" + "build-storybook": "build-storybook -c .storybook -o .storybook-dist && gulp copy-storybook-fonts" }, "dependencies": { + "attr-accept": "^1.1.0", "classnames": "^2.2.5", "core-js": "^2.4.0", - "d3": "^3.5.16", + "d3": "^4.9.1", "dox-sequence-diagram-ui": "file:../dox-sequence-diagram-ui", "intl": "^1.0.1", "intl-format-cache": "^2.0.5", @@ -29,17 +31,20 @@ "intl-relativeformat": "^1.2.0", "lodash": "^4.13.1", "md5": "^2.1.0", + "prop-types": "^15.6.0", "randomstring": "^1.1.5", "react": "~15.3.2", "react-bootstrap": "^0.30.1", + "react-click-outside": "^2.3.1", "react-dom": "~15.3.2", "react-dropzone": "3.7.3", "react-redux": "^4.4.1", "react-select": "1.0.0-rc.5", + "react-show-more": "^1.1.1", "react-sortable": "^1.2.0", "redux": "^3.3.1", "restful-js": "0.7.0", - "sdc-ui": "1.6.8", + "sdc-ui": "1.6.9", "uuid-js": "^0.7.5", "validator": "^4.3.0" }, @@ -76,7 +81,7 @@ "gulp-replace": "^0.5.4", "gulp-tap": "^1.0.1", "html-loader": "^0.4.3", - "http-proxy-middleware": "^0.8.2", + "http-proxy-middleware": "^0.17.4", "ignore-loader": "^0.1.1", "jasmine-core": "^2.5.2", "jest": "^19.0.2", @@ -88,6 +93,7 @@ "node-watch": "^0.3.5", "prompt": "^0.2.14", "react-addons-test-utils": "~15.3.2", + "react-click-outside": "^2.3.1", "react-datepicker": "^0.48.0", "react-hot-loader": "^1.3.1", "rosie": "^1.6.0", @@ -110,6 +116,7 @@ "\\.(css|scss)$": "<rootDir>/test-utils/styleMock.js", "^nfvo-utils/RestAPIUtil.js$": "<rootDir>/test-utils/MockRest.js", "^sdc-ui/lib/react/SVGIcon.js$": "<rootDir>/test-utils/MockSVGIcon.js", + "^react-show-more$": "<rootDir>/test-utils/ShowMore.js", "^nfvo-utils(.*)$": "<rootDir>/src/nfvo-utils$1", "^nfvo-components(.*)$": "<rootDir>/src/nfvo-components$1", "^sdc-app(.*)$": "<rootDir>/src/sdc-app$1", @@ -131,6 +138,10 @@ "collectCoverageFrom": [ "src/**/*.{js,jsx}" ], + "coveragePathIgnorePatterns": [ + "/node_modules/", + "(.)*.stories.js" + ], "coverageReporters": [ "lcov" ] diff --git a/openecomp-ui/pom.xml b/openecomp-ui/pom.xml index a5eaeef39a..df86ce7748 100644 --- a/openecomp-ui/pom.xml +++ b/openecomp-ui/pom.xml @@ -40,6 +40,9 @@ <!--<directory>${basedir}/node_modules</directory>--> <!--</fileset>--> <fileset> + <directory>${basedir}/coverage</directory> + </fileset> + <fileset> <directory>${basedir}/../dox-sequence-diagram-ui/dist </directory> </fileset> @@ -141,6 +144,16 @@ <arguments>run build -- --version=${project.version}</arguments> </configuration> </execution> + <execution> + <id>ui test</id> + <goals> + <goal>npm</goal> + </goals> + <configuration> + <arguments>run test-build</arguments> + </configuration> + <phase>test</phase> + </execution> </executions> </plugin> diff --git a/openecomp-ui/resources/images/angle-left.svg b/openecomp-ui/resources/images/angle-left.svg deleted file mode 100644 index b2d2f81b3d..0000000000 --- a/openecomp-ui/resources/images/angle-left.svg +++ /dev/null @@ -1,9 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Generator: Adobe Illustrator 21.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> -<svg version="1.1" id="angle-left_icon" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" - viewBox="0 0 6.3 9.9" style="enable-background:new 0 0 6.3 9.9;" xml:space="preserve"> -<g transform="translate(0,-952.36218)"> - <path d="M5.8,952.4c-0.1,0-0.2,0-0.2,0.1l-5.5,4.6c-0.2,0.1-0.2,0.4,0,0.5l0,0l5.5,4.6c0.2,0.1,0.4,0.1,0.5,0 - c0.1-0.2,0.1-0.4,0-0.5l0,0l-5.2-4.3l5.2-4.3c0.2-0.1,0.2-0.4,0.1-0.5C6,952.4,5.9,952.4,5.8,952.4z"/> -</g> -</svg> diff --git a/openecomp-ui/resources/images/angle-right.svg b/openecomp-ui/resources/images/angle-right.svg deleted file mode 100644 index f8e6efc3a6..0000000000 --- a/openecomp-ui/resources/images/angle-right.svg +++ /dev/null @@ -1,9 +0,0 @@ -<?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/artifacts_icon.png b/openecomp-ui/resources/images/artifacts_icon.png Binary files differdeleted file mode 100644 index 584f78d33a..0000000000 --- a/openecomp-ui/resources/images/artifacts_icon.png +++ /dev/null diff --git a/openecomp-ui/resources/images/base_icon.png b/openecomp-ui/resources/images/base_icon.png Binary files differdeleted file mode 100644 index 439a517e03..0000000000 --- a/openecomp-ui/resources/images/base_icon.png +++ /dev/null diff --git a/openecomp-ui/resources/images/download_icon.png b/openecomp-ui/resources/images/download_icon.png Binary files differdeleted file mode 100644 index 307d0eff9e..0000000000 --- a/openecomp-ui/resources/images/download_icon.png +++ /dev/null diff --git a/openecomp-ui/resources/images/icons/ZIP_blue_icon.png b/openecomp-ui/resources/images/icons/ZIP_blue_icon.png Binary files differdeleted file mode 100644 index a36d2473fc..0000000000 --- a/openecomp-ui/resources/images/icons/ZIP_blue_icon.png +++ /dev/null diff --git a/openecomp-ui/resources/images/icons/ZIP_icon.png b/openecomp-ui/resources/images/icons/ZIP_icon.png Binary files differdeleted file mode 100644 index 82822d5727..0000000000 --- a/openecomp-ui/resources/images/icons/ZIP_icon.png +++ /dev/null diff --git a/openecomp-ui/resources/images/icons/artifacts_blue_icon.png b/openecomp-ui/resources/images/icons/artifacts_blue_icon.png Binary files differdeleted file mode 100644 index 46bc14884b..0000000000 --- a/openecomp-ui/resources/images/icons/artifacts_blue_icon.png +++ /dev/null diff --git a/openecomp-ui/resources/images/icons/artifacts_grey_icon.png b/openecomp-ui/resources/images/icons/artifacts_grey_icon.png Binary files differdeleted file mode 100644 index 6f3e8a2ebf..0000000000 --- a/openecomp-ui/resources/images/icons/artifacts_grey_icon.png +++ /dev/null diff --git a/openecomp-ui/resources/images/icons/back_icon.png b/openecomp-ui/resources/images/icons/back_icon.png Binary files differdeleted file mode 100644 index 305080a807..0000000000 --- a/openecomp-ui/resources/images/icons/back_icon.png +++ /dev/null diff --git a/openecomp-ui/resources/images/icons/checked_in.png b/openecomp-ui/resources/images/icons/checked_in.png Binary files differdeleted file mode 100644 index 44112ced13..0000000000 --- a/openecomp-ui/resources/images/icons/checked_in.png +++ /dev/null diff --git a/openecomp-ui/resources/images/icons/checked_out.png b/openecomp-ui/resources/images/icons/checked_out.png Binary files differdeleted file mode 100644 index ac73c732bb..0000000000 --- a/openecomp-ui/resources/images/icons/checked_out.png +++ /dev/null diff --git a/openecomp-ui/resources/images/icons/down_chevron.png b/openecomp-ui/resources/images/icons/down_chevron.png Binary files differdeleted file mode 100644 index 257f036646..0000000000 --- a/openecomp-ui/resources/images/icons/down_chevron.png +++ /dev/null diff --git a/openecomp-ui/resources/images/icons/env_icon.png b/openecomp-ui/resources/images/icons/env_icon.png Binary files differdeleted file mode 100644 index 83d6852a14..0000000000 --- a/openecomp-ui/resources/images/icons/env_icon.png +++ /dev/null diff --git a/openecomp-ui/resources/images/icons/env_icon_blue.png b/openecomp-ui/resources/images/icons/env_icon_blue.png Binary files differdeleted file mode 100644 index bb30e26382..0000000000 --- a/openecomp-ui/resources/images/icons/env_icon_blue.png +++ /dev/null diff --git a/openecomp-ui/resources/images/icons/error_icon_big.png b/openecomp-ui/resources/images/icons/error_icon_big.png Binary files differdeleted file mode 100644 index 35dfeb318c..0000000000 --- a/openecomp-ui/resources/images/icons/error_icon_big.png +++ /dev/null diff --git a/openecomp-ui/resources/images/icons/error_icon_small.png b/openecomp-ui/resources/images/icons/error_icon_small.png Binary files differdeleted file mode 100644 index 059aa9b201..0000000000 --- a/openecomp-ui/resources/images/icons/error_icon_small.png +++ /dev/null diff --git a/openecomp-ui/resources/images/icons/favicon.ico b/openecomp-ui/resources/images/icons/favicon.ico Binary files differdeleted file mode 100644 index c59a7aa0a3..0000000000 --- a/openecomp-ui/resources/images/icons/favicon.ico +++ /dev/null diff --git a/openecomp-ui/resources/images/icons/favicon.png b/openecomp-ui/resources/images/icons/favicon.png Binary files differdeleted file mode 100644 index c59a7aa0a3..0000000000 --- a/openecomp-ui/resources/images/icons/favicon.png +++ /dev/null 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 Binary files differdeleted file mode 100644 index 98bf1d92d8..0000000000 --- a/openecomp-ui/resources/images/icons/go_to_overview_disable_icon.png +++ /dev/null diff --git a/openecomp-ui/resources/images/icons/go_to_overview_icon.png b/openecomp-ui/resources/images/icons/go_to_overview_icon.png Binary files differdeleted file mode 100644 index e996377fec..0000000000 --- a/openecomp-ui/resources/images/icons/go_to_overview_icon.png +++ /dev/null diff --git a/openecomp-ui/resources/images/icons/nested_HEAT_icon_blue.png b/openecomp-ui/resources/images/icons/nested_HEAT_icon_blue.png Binary files differdeleted file mode 100644 index 21383bf4c1..0000000000 --- a/openecomp-ui/resources/images/icons/nested_HEAT_icon_blue.png +++ /dev/null diff --git a/openecomp-ui/resources/images/icons/nested_heat_icon.png b/openecomp-ui/resources/images/icons/nested_heat_icon.png Binary files differdeleted file mode 100644 index beeaf20264..0000000000 --- a/openecomp-ui/resources/images/icons/nested_heat_icon.png +++ /dev/null diff --git a/openecomp-ui/resources/images/icons/network_blue_icon.png b/openecomp-ui/resources/images/icons/network_blue_icon.png Binary files differdeleted file mode 100644 index 5ed223d214..0000000000 --- a/openecomp-ui/resources/images/icons/network_blue_icon.png +++ /dev/null diff --git a/openecomp-ui/resources/images/icons/network_icon.png b/openecomp-ui/resources/images/icons/network_icon.png Binary files differdeleted file mode 100644 index ec0f9208e4..0000000000 --- a/openecomp-ui/resources/images/icons/network_icon.png +++ /dev/null diff --git a/openecomp-ui/resources/images/icons/orphans_blue_icon-n.png b/openecomp-ui/resources/images/icons/orphans_blue_icon-n.png Binary files differdeleted file mode 100644 index 64a5949a6a..0000000000 --- a/openecomp-ui/resources/images/icons/orphans_blue_icon-n.png +++ /dev/null diff --git a/openecomp-ui/resources/images/icons/orphans_grey_icon.png b/openecomp-ui/resources/images/icons/orphans_grey_icon.png Binary files differdeleted file mode 100644 index f761ae71b8..0000000000 --- a/openecomp-ui/resources/images/icons/orphans_grey_icon.png +++ /dev/null diff --git a/openecomp-ui/resources/images/icons/others_blue_icon.png b/openecomp-ui/resources/images/icons/others_blue_icon.png Binary files differdeleted file mode 100644 index e3953151dd..0000000000 --- a/openecomp-ui/resources/images/icons/others_blue_icon.png +++ /dev/null diff --git a/openecomp-ui/resources/images/icons/others_icon.png b/openecomp-ui/resources/images/icons/others_icon.png Binary files differdeleted file mode 100644 index cc498053d2..0000000000 --- a/openecomp-ui/resources/images/icons/others_icon.png +++ /dev/null diff --git a/openecomp-ui/resources/images/icons/pencil_icon-01.svg b/openecomp-ui/resources/images/icons/pencil_icon-01.svg deleted file mode 100644 index 50e38aa6a2..0000000000 --- a/openecomp-ui/resources/images/icons/pencil_icon-01.svg +++ /dev/null @@ -1,17 +0,0 @@ -<?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 Binary files differdeleted file mode 100644 index dcd8081e74..0000000000 --- a/openecomp-ui/resources/images/icons/plus_vlm_summary_disabled_icon.png +++ /dev/null diff --git a/openecomp-ui/resources/images/icons/plus_vlm_summary_icon.png b/openecomp-ui/resources/images/icons/plus_vlm_summary_icon.png Binary files differdeleted file mode 100644 index e50ce02a92..0000000000 --- a/openecomp-ui/resources/images/icons/plus_vlm_summary_icon.png +++ /dev/null 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 Binary files differdeleted file mode 100644 index 09ecc4a2ea..0000000000 --- a/openecomp-ui/resources/images/icons/plus_vlm_summary_icon_blue.png +++ /dev/null diff --git a/openecomp-ui/resources/images/icons/revert_icon_disabled.png b/openecomp-ui/resources/images/icons/revert_icon_disabled.png Binary files differdeleted file mode 100644 index e0f55de1fd..0000000000 --- a/openecomp-ui/resources/images/icons/revert_icon_disabled.png +++ /dev/null diff --git a/openecomp-ui/resources/images/icons/reverticon.png b/openecomp-ui/resources/images/icons/reverticon.png Binary files differdeleted file mode 100644 index 813f036788..0000000000 --- a/openecomp-ui/resources/images/icons/reverticon.png +++ /dev/null diff --git a/openecomp-ui/resources/images/icons/save_icon_disable.png b/openecomp-ui/resources/images/icons/save_icon_disable.png Binary files differdeleted file mode 100644 index 5eb6513027..0000000000 --- a/openecomp-ui/resources/images/icons/save_icon_disable.png +++ /dev/null diff --git a/openecomp-ui/resources/images/icons/saveicon.png b/openecomp-ui/resources/images/icons/saveicon.png Binary files differdeleted file mode 100644 index 64ada85cdb..0000000000 --- a/openecomp-ui/resources/images/icons/saveicon.png +++ /dev/null diff --git a/openecomp-ui/resources/images/icons/submit_icon_disable.png b/openecomp-ui/resources/images/icons/submit_icon_disable.png Binary files differdeleted file mode 100644 index ccb5775e8c..0000000000 --- a/openecomp-ui/resources/images/icons/submit_icon_disable.png +++ /dev/null diff --git a/openecomp-ui/resources/images/icons/submiticonactive.png b/openecomp-ui/resources/images/icons/submiticonactive.png Binary files differdeleted file mode 100644 index d0d36a1870..0000000000 --- a/openecomp-ui/resources/images/icons/submiticonactive.png +++ /dev/null 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 Binary files differdeleted file mode 100644 index da2b5bb027..0000000000 --- a/openecomp-ui/resources/images/icons/vlm_list_view_blue_icon.png +++ /dev/null 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 Binary files differdeleted file mode 100644 index 582cf8eab4..0000000000 --- a/openecomp-ui/resources/images/icons/vlm_list_view_grey_icon.png +++ /dev/null diff --git a/openecomp-ui/resources/images/icons/volume_blue_icon.png b/openecomp-ui/resources/images/icons/volume_blue_icon.png Binary files differdeleted file mode 100644 index 34e47ac97e..0000000000 --- a/openecomp-ui/resources/images/icons/volume_blue_icon.png +++ /dev/null diff --git a/openecomp-ui/resources/images/icons/volume_icon.png b/openecomp-ui/resources/images/icons/volume_icon.png Binary files differdeleted file mode 100644 index ca2a2f8fcc..0000000000 --- a/openecomp-ui/resources/images/icons/volume_icon.png +++ /dev/null diff --git a/openecomp-ui/resources/images/icons/warning_icon_big.png b/openecomp-ui/resources/images/icons/warning_icon_big.png Binary files differdeleted file mode 100644 index c44d24021e..0000000000 --- a/openecomp-ui/resources/images/icons/warning_icon_big.png +++ /dev/null diff --git a/openecomp-ui/resources/images/icons/warning_icon_small.png b/openecomp-ui/resources/images/icons/warning_icon_small.png Binary files differdeleted file mode 100644 index 1592ec5045..0000000000 --- a/openecomp-ui/resources/images/icons/warning_icon_small.png +++ /dev/null diff --git a/openecomp-ui/resources/images/module_icon.png b/openecomp-ui/resources/images/module_icon.png Binary files differdeleted file mode 100644 index fd71a747db..0000000000 --- a/openecomp-ui/resources/images/module_icon.png +++ /dev/null diff --git a/openecomp-ui/resources/images/pencil_icon-01.svg b/openecomp-ui/resources/images/pencil_icon-01.svg deleted file mode 100644 index 50e38aa6a2..0000000000 --- a/openecomp-ui/resources/images/pencil_icon-01.svg +++ /dev/null @@ -1,17 +0,0 @@ -<?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/plus-circle-icon.svg b/openecomp-ui/resources/images/plus-circle-icon.svg deleted file mode 100644 index 352dcad5e8..0000000000 --- a/openecomp-ui/resources/images/plus-circle-icon.svg +++ /dev/null @@ -1,18 +0,0 @@ -<?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="Isolation_Mode" 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"> -<style type="text/css"> - .st0{fill:#009fdb;} -</style> -<g> - <g> - <path class="st0" 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 class="st0" 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/angle-double-left.svg b/openecomp-ui/resources/images/svg/angle-double-left.svg deleted file mode 100644 index 9e1591a11d..0000000000 --- a/openecomp-ui/resources/images/svg/angle-double-left.svg +++ /dev/null @@ -1,15 +0,0 @@ -<?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 deleted file mode 100644 index e77031aa70..0000000000 --- a/openecomp-ui/resources/images/svg/angle-double-right.svg +++ /dev/null @@ -1,11 +0,0 @@ -<?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 deleted file mode 100644 index b2d2f81b3d..0000000000 --- a/openecomp-ui/resources/images/svg/angle-left.svg +++ /dev/null @@ -1,9 +0,0 @@ -<?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 deleted file mode 100644 index f8e6efc3a6..0000000000 --- a/openecomp-ui/resources/images/svg/angle-right.svg +++ /dev/null @@ -1,9 +0,0 @@ -<?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 deleted file mode 100644 index 287355fa95..0000000000 --- a/openecomp-ui/resources/images/svg/back.svg +++ /dev/null @@ -1,6 +0,0 @@ -<?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/calendar.svg b/openecomp-ui/resources/images/svg/calendar.svg deleted file mode 100644 index 9c059024d5..0000000000 --- a/openecomp-ui/resources/images/svg/calendar.svg +++ /dev/null @@ -1 +0,0 @@ -<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 17 18" id="calendar_icon"><title>Asset 1</title><g data-name="Layer 2"><g id="Layer_1-2" data-name="Layer 1"><path d="M15.5,2H13V0H12V2H9V0H8V2H5V0H4V2H1.5A1.5,1.5,0,0,0,0,3.5v13A1.5,1.5,0,0,0,1.5,18h14A1.5,1.5,0,0,0,17,16.5V3.5A1.5,1.5,0,0,0,15.5,2ZM16,16.5a.5.5,0,0,1-.5.5H1.5a.5.5,0,0,1-.5-.5V8H16ZM1,7V3.5A.5.5,0,0,1,1.5,3H4V5H5V3H8V5H9V3h3V5h1V3h2.5a.5.5,0,0,1,.5.5V7Z"/><path d="M4.52,13.65l.7-.09a1.55,1.55,0,0,0,.41.86,1,1,0,0,0,.71.26,1.14,1.14,0,0,0,.84-.34,1.16,1.16,0,0,0,.34-.85,1.08,1.08,0,0,0-.32-.8,1.09,1.09,0,0,0-.8-.31,2,2,0,0,0-.5.08L6,11.84H6.1a1.45,1.45,0,0,0,.81-.23.8.8,0,0,0,.36-.72A.85.85,0,0,0,7,10.25.93.93,0,0,0,6.33,10a1,1,0,0,0-.68.26A1.29,1.29,0,0,0,5.3,11l-.7-.12a1.81,1.81,0,0,1,.59-1.1,1.69,1.69,0,0,1,1.14-.39,1.86,1.86,0,0,1,.86.2,1.45,1.45,0,0,1,.6.55A1.41,1.41,0,0,1,8,10.9a1.21,1.21,0,0,1-.2.68,1.36,1.36,0,0,1-.59.48,1.33,1.33,0,0,1,.79.49,1.48,1.48,0,0,1,.28.92,1.69,1.69,0,0,1-.55,1.27,1.92,1.92,0,0,1-1.38.52,1.8,1.8,0,0,1-1.25-.45A1.74,1.74,0,0,1,4.52,13.65Z"/><path d="M11.62,15.17h-.7V10.69a3.68,3.68,0,0,1-.67.48,4.77,4.77,0,0,1-.74.36v-.68a4.26,4.26,0,0,0,1-.67,2.66,2.66,0,0,0,.63-.77h.45Z"/></g></g></svg>
\ No newline at end of file diff --git a/openecomp-ui/resources/images/svg/caret-down.svg b/openecomp-ui/resources/images/svg/caret-down.svg deleted file mode 100644 index cfd3c57eb1..0000000000 --- a/openecomp-ui/resources/images/svg/caret-down.svg +++ /dev/null @@ -1,6 +0,0 @@ -<?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 deleted file mode 100644 index 313657e4a1..0000000000 --- a/openecomp-ui/resources/images/svg/check-circle.svg +++ /dev/null @@ -1 +0,0 @@ -<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 deleted file mode 100644 index 43d18814b1..0000000000 --- a/openecomp-ui/resources/images/svg/check.svg +++ /dev/null @@ -1,9 +0,0 @@ -<?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 deleted file mode 100644 index 1ebd094459..0000000000 --- a/openecomp-ui/resources/images/svg/chevron-down.svg +++ /dev/null @@ -1,9 +0,0 @@ -<?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 deleted file mode 100644 index 7fce935e14..0000000000 --- a/openecomp-ui/resources/images/svg/chevron-up.svg +++ /dev/null @@ -1,9 +0,0 @@ -<?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 deleted file mode 100644 index 0decc7c2b6..0000000000 --- a/openecomp-ui/resources/images/svg/close.svg +++ /dev/null @@ -1,10 +0,0 @@ -<?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 deleted file mode 100644 index 8234753bd4..0000000000 --- a/openecomp-ui/resources/images/svg/error-circle.svg +++ /dev/null @@ -1 +0,0 @@ -<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 deleted file mode 100644 index 7cab121861..0000000000 --- a/openecomp-ui/resources/images/svg/exclamation-triangle-full.svg +++ /dev/null @@ -1,9 +0,0 @@ -<?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 deleted file mode 100644 index eae682503d..0000000000 --- a/openecomp-ui/resources/images/svg/exclamation-triangle-line.svg +++ /dev/null @@ -1,25 +0,0 @@ -<?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 deleted file mode 100644 index 245661242a..0000000000 --- a/openecomp-ui/resources/images/svg/exclamation-triangle.svg +++ /dev/null @@ -1,11 +0,0 @@ -<?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 deleted file mode 100644 index 1c493f4653..0000000000 --- a/openecomp-ui/resources/images/svg/filter.svg +++ /dev/null @@ -1,9 +0,0 @@ -<?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 deleted file mode 100644 index 9785f8df11..0000000000 --- a/openecomp-ui/resources/images/svg/locked.svg +++ /dev/null @@ -1,39 +0,0 @@ -<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 deleted file mode 100644 index 6701a3aba0..0000000000 --- a/openecomp-ui/resources/images/svg/pencil.svg +++ /dev/null @@ -1,17 +0,0 @@ -<?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 deleted file mode 100644 index 9a0f023be7..0000000000 --- a/openecomp-ui/resources/images/svg/plus-circle.svg +++ /dev/null @@ -1,15 +0,0 @@ -<?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 deleted file mode 100644 index 36f3486717..0000000000 --- a/openecomp-ui/resources/images/svg/plus.svg +++ /dev/null @@ -1,9 +0,0 @@ -<?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 deleted file mode 100644 index ce8310429a..0000000000 --- a/openecomp-ui/resources/images/svg/search.svg +++ /dev/null @@ -1,8 +0,0 @@ -<?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 deleted file mode 100644 index ade9de2435..0000000000 --- a/openecomp-ui/resources/images/svg/sliders.svg +++ /dev/null @@ -1,19 +0,0 @@ -<?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 deleted file mode 100644 index 26336f172f..0000000000 --- a/openecomp-ui/resources/images/svg/trash-o.svg +++ /dev/null @@ -1,17 +0,0 @@ -<?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 deleted file mode 100644 index 6d94a94247..0000000000 --- a/openecomp-ui/resources/images/svg/unlocked.svg +++ /dev/null @@ -1,39 +0,0 @@ -<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 deleted file mode 100644 index a3b8f5f0a3..0000000000 --- a/openecomp-ui/resources/images/svg/vendor.svg +++ /dev/null @@ -1 +0,0 @@ -<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 deleted file mode 100644 index 73aae7dbf2..0000000000 --- a/openecomp-ui/resources/images/svg/version-controller-lock-closed.svg +++ /dev/null @@ -1,17 +0,0 @@ -<?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 deleted file mode 100644 index 52e0b8bf71..0000000000 --- a/openecomp-ui/resources/images/svg/version-controller-lock-open.svg +++ /dev/null @@ -1,17 +0,0 @@ -<?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 deleted file mode 100644 index f9f02f94be..0000000000 --- a/openecomp-ui/resources/images/svg/version-controller-revert.svg +++ /dev/null @@ -1,14 +0,0 @@ -<?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 deleted file mode 100644 index 4a05425ed7..0000000000 --- a/openecomp-ui/resources/images/svg/version-controller-save.svg +++ /dev/null @@ -1,10 +0,0 @@ -<?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 deleted file mode 100644 index 9909ab3c6e..0000000000 --- a/openecomp-ui/resources/images/svg/version-controller-submit.svg +++ /dev/null @@ -1,10 +0,0 @@ -<?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 deleted file mode 100644 index 79b4625a09..0000000000 --- a/openecomp-ui/resources/images/svg/vlm.svg +++ /dev/null @@ -1 +0,0 @@ -<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 deleted file mode 100644 index 344755c2ab..0000000000 --- a/openecomp-ui/resources/images/svg/vsp.svg +++ /dev/null @@ -1 +0,0 @@ -<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 Binary files differdeleted file mode 100644 index ebc17aef38..0000000000 --- a/openecomp-ui/resources/images/trash_icon.png +++ /dev/null diff --git a/openecomp-ui/resources/images/upload_icon.png b/openecomp-ui/resources/images/upload_icon.png Binary files differdeleted file mode 100644 index 55f60f654e..0000000000 --- a/openecomp-ui/resources/images/upload_icon.png +++ /dev/null diff --git a/openecomp-ui/resources/images/v_icon.png b/openecomp-ui/resources/images/v_icon.png Binary files differdeleted file mode 100644 index 387e3037fc..0000000000 --- a/openecomp-ui/resources/images/v_icon.png +++ /dev/null diff --git a/openecomp-ui/resources/scss/_components.scss b/openecomp-ui/resources/scss/_components.scss index 7c726aa8dd..7f73047c91 100644 --- a/openecomp-ui/resources/scss/_components.scss +++ b/openecomp-ui/resources/scss/_components.scss @@ -1,5 +1,4 @@ @import "components/punchOut"; -@import "components/buttons"; @import "components/forms"; @import "components/validationForm"; @import "components/dualListBox"; @@ -19,6 +18,10 @@ @import "components/activityLog"; @import "components/selectActionTable"; @import "components/datepicker"; +@import "components/tree"; +@import "components/commitModal"; +@import "components/userNotifications"; +@import "components/overlay"; %noselect { -webkit-touch-callout: none; @@ -70,10 +73,6 @@ } } -.warning-icon { - margin-left: 50%; - color: $yellow; -} .chevron::before { border-style: solid; diff --git a/openecomp-ui/resources/scss/_modules.scss b/openecomp-ui/resources/scss/_modules.scss index 405e91a61b..6fe6e30ab6 100644 --- a/openecomp-ui/resources/scss/_modules.scss +++ b/openecomp-ui/resources/scss/_modules.scss @@ -23,4 +23,8 @@ @import "modules/uploadScreen"; @import "modules/vspHeatSetup"; @import "modules/softwareProductDependencies"; +@import "modules/_permissions.scss"; +@import "modules/_revisions.scss"; @import "modules/softwareProductDeployment"; +@import "modules/versionsPage"; +@import "modules/mergeEditor"; diff --git a/openecomp-ui/resources/scss/bootstrap-cust/_buttons.scss b/openecomp-ui/resources/scss/bootstrap-cust/_buttons.scss deleted file mode 100644 index bf58006d89..0000000000 --- a/openecomp-ui/resources/scss/bootstrap-cust/_buttons.scss +++ /dev/null @@ -1,13 +0,0 @@ - -.btn { - height: 30px; - min-width: 95px; -} - -.btn-default .fa { - color: $brand-primary; -} - -.btn-info { - @include button-variant($text-black, $tlv-gray, $light-gray); -} diff --git a/openecomp-ui/resources/scss/bootstrap-cust/_forms.scss b/openecomp-ui/resources/scss/bootstrap-cust/_forms.scss index 60fd7ab07d..4ec2341011 100644 --- a/openecomp-ui/resources/scss/bootstrap-cust/_forms.scss +++ b/openecomp-ui/resources/scss/bootstrap-cust/_forms.scss @@ -1,6 +1,7 @@ .form-group { .control-label { @extend .body-2-semibold; + font-weight: normal; } &.required { label:before { @@ -28,6 +29,15 @@ label { margin-bottom: 8px; } +.sdc-radio { + label { + font-weight: normal; + margin-bottom: 0; + } + input[type="radio"] { + margin: 0; + } +} select.form-control { display: block; width: 215px; @@ -37,7 +47,7 @@ select[multiple] { background: none; } -input[type="radio"], input[type="checkbox"] { +input[type="checkbox"] { margin: 0; &:before { @@ -77,14 +87,6 @@ input[type="radio"], input[type="checkbox"] { border-radius: 2px; } -input[type=radio]:checked:before { - content: "\2022"; - color: $blue; - font-size: 30px; - text-align: center; - line-height: 11px; - font-family: $radio-font-family; -} input[type=checkbox]:checked:before { font-family: $icon-font-family; diff --git a/openecomp-ui/resources/scss/bootstrap-cust/_modals.scss b/openecomp-ui/resources/scss/bootstrap-cust/_modals.scss index ad6b4f8aca..1f132043ab 100644 --- a/openecomp-ui/resources/scss/bootstrap-cust/_modals.scss +++ b/openecomp-ui/resources/scss/bootstrap-cust/_modals.scss @@ -11,9 +11,13 @@ padding: 0; .validation-form-content { padding: 50px; + padding-bottom: 30px; overflow-y: auto; max-height: 490px; } + .validation-buttons { + padding-right: 50px; + } } .modal-footer { diff --git a/openecomp-ui/resources/scss/bootstrap-cust/_navbar.scss b/openecomp-ui/resources/scss/bootstrap-cust/_navbar.scss deleted file mode 100644 index acf2024b56..0000000000 --- a/openecomp-ui/resources/scss/bootstrap-cust/_navbar.scss +++ /dev/null @@ -1,3 +0,0 @@ -.navbar { - border: none; -} diff --git a/openecomp-ui/resources/scss/bootstrap-cust/_navs.scss b/openecomp-ui/resources/scss/bootstrap-cust/_navs.scss deleted file mode 100644 index 914a7794f1..0000000000 --- a/openecomp-ui/resources/scss/bootstrap-cust/_navs.scss +++ /dev/null @@ -1,30 +0,0 @@ -.nav { - > li { - > a { - padding: 10px 10px 3px; - } - } -} - -.nav-tabs { - @include box-shadow(0px 2px 1px -1px $gray); - padding: 0 28px; - - > li { - @extend .body-1; - - > a { - color: $dark-gray; - text-transform: uppercase; - } - - &.active > a { - &, - &:hover, - &:focus { - @extend .body-1-semibold; - border-bottom: 3px solid $blue; - } - } - } -} diff --git a/openecomp-ui/resources/scss/bootstrap.scss b/openecomp-ui/resources/scss/bootstrap.scss index 777f490a89..32890b35f0 100644 --- a/openecomp-ui/resources/scss/bootstrap.scss +++ b/openecomp-ui/resources/scss/bootstrap.scss @@ -20,18 +20,12 @@ @import "bootstrap-cust/tables"; @import "bootstrap/forms"; @import "bootstrap-cust/forms"; -//@import "bootstrap/buttons"; -//@import "bootstrap-cust/buttons"; // Components @import "bootstrap/component-animations"; @import "bootstrap/dropdowns"; @import "bootstrap-cust/dropdowns"; @import "bootstrap/button-groups"; @import "bootstrap/input-groups"; -@import "bootstrap/navs"; -@import "bootstrap-cust/navs"; -@import "bootstrap/navbar"; -@import "bootstrap-cust/navbar"; @import "bootstrap/breadcrumbs"; @import "bootstrap/pagination"; @import "bootstrap/pager"; diff --git a/openecomp-ui/resources/scss/bootstrap/_button-groups.scss b/openecomp-ui/resources/scss/bootstrap/_button-groups.scss index dc2906e44f..14ee0d348c 100644 --- a/openecomp-ui/resources/scss/bootstrap/_button-groups.scss +++ b/openecomp-ui/resources/scss/bootstrap/_button-groups.scss @@ -92,21 +92,9 @@ outline: 0; } -// Sizing -// -// Remix the default button sizing classes into new ones for easier manipulation. -.btn-group-xs > .btn { - @extend .btn-xs; -} -.btn-group-sm > .btn { - @extend .btn-sm; -} -.btn-group-lg > .btn { - @extend .btn-lg; -} // Split button dropdowns // ---------------------- diff --git a/openecomp-ui/resources/scss/common/_base.scss b/openecomp-ui/resources/scss/common/_base.scss index e901db000e..ff3a830e6b 100644 --- a/openecomp-ui/resources/scss/common/_base.scss +++ b/openecomp-ui/resources/scss/common/_base.scss @@ -11,10 +11,14 @@ body { @extend %noselect; } +$scrollbar-width: 8px; +$scrollbar-height: 8px; +/* firefox */ +$ff-scrollbar-width: 17px; /* scrollbar styling for Google Chrome | Safari | Opera */ ::-webkit-scrollbar { - width: 8px; - height: 8px; + width: $scrollbar-width; + height: $scrollbar-height; } ::-webkit-scrollbar-track { diff --git a/openecomp-ui/resources/scss/common/_layout.scss b/openecomp-ui/resources/scss/common/_layout.scss index dc2a33ccc7..6c6a0cf165 100644 --- a/openecomp-ui/resources/scss/common/_layout.scss +++ b/openecomp-ui/resources/scss/common/_layout.scss @@ -26,4 +26,10 @@ .modal-title { text-transform: uppercase; } -}
\ No newline at end of file +} +.page-title { + @extend .heading-1; + @extend .text-uppercase !optional; + margin-bottom: 20px; + color: $blue; +} diff --git a/openecomp-ui/resources/scss/common/_typography.scss b/openecomp-ui/resources/scss/common/_typography.scss index 95d6d88595..c4ae856b5f 100644 --- a/openecomp-ui/resources/scss/common/_typography.scss +++ b/openecomp-ui/resources/scss/common/_typography.scss @@ -31,9 +31,9 @@ $body-font-2: 13px; $body-font-3: 12px; $body-font-4: 10px; -$icon-font-size: 11px; +$icon-font-size: 10px; $icon-font-family: Arial; -$radio-font-family: Arial; + .heading-1 { @include base-font-light; @@ -133,10 +133,6 @@ $radio-font-family: Arial; font-size: $body-font-3; } -.circle-icon-text { - @include base-font-semibold; - font-size: $body-font-1; -} .warning-text { color: $yellow; diff --git a/openecomp-ui/resources/scss/common/_utils.scss b/openecomp-ui/resources/scss/common/_utils.scss index 88a9ece7a8..99b1ff5d9a 100644 --- a/openecomp-ui/resources/scss/common/_utils.scss +++ b/openecomp-ui/resources/scss/common/_utils.scss @@ -118,7 +118,6 @@ $browserPrefixes: webkit moz o ms; max-height: $lineHeight * $lineCount; text-align: justify; word-break: break-all; - white-space: nowrap; // margin-right: -1em; padding-right: 1em; &:before { @@ -215,7 +214,7 @@ $browserPrefixes: webkit moz o ms; } } -@mixin create-circle($size, $bgcolor, $content) { +@mixin create-circle($size, $bgcolor) { border-radius: 50%; width: $size; height: $size; diff --git a/openecomp-ui/resources/scss/common/_variables.scss b/openecomp-ui/resources/scss/common/_variables.scss index 3a3178c6b0..5125b652ea 100644 --- a/openecomp-ui/resources/scss/common/_variables.scss +++ b/openecomp-ui/resources/scss/common/_variables.scss @@ -21,12 +21,10 @@ $white: #ffffff; $red: #cf2a2a; $crimson: #a94442; -$background-alice-blue: #e5f5fb; $background-gray: #f2f2f2; $text-black: #191919; $link-blue: #056bae; $functional-green: #007a3e; -$functional-yellow: #ffb81c; $tlv-gray: #f8f8f8; $tlv-light-gray: #eaeaea; $tlv-hover: #e6f6fb; @@ -34,7 +32,7 @@ $highlight-gray: #eceff3; $content-background-color: $white; -$scroll-bar-color: $text-black;//$light-gray; +$scroll-bar-color: $text-black; $vc-status-text-color: #42b72a; // sizes @@ -45,72 +43,8 @@ $tablet-max-width: 1024px; $laptop-min-width: 1224px; $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"; -/* -$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"; -*/ -$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 index 5e9418ed7d..7a5b77b58c 100644 --- a/openecomp-ui/resources/scss/components/_activityLog.scss +++ b/openecomp-ui/resources/scss/components/_activityLog.scss @@ -23,6 +23,7 @@ $message-info-icon-size: 16px; .list-editor-view-list { border: 1px solid $light-gray; border-bottom: none; + overflow-y: hidden; } .activity-list-item { display: flex; diff --git a/openecomp-ui/resources/scss/components/_buttons.scss b/openecomp-ui/resources/scss/components/_buttons.scss deleted file mode 100644 index 357a799e93..0000000000 --- a/openecomp-ui/resources/scss/components/_buttons.scss +++ /dev/null @@ -1,30 +0,0 @@ -.primary-btn{ - border: 1px solid; - border-color: $blue; - color: $blue; - @extend .body-1-semibold; - text-align: center; - padding: 7px; - border-radius: 5px; - cursor: pointer; - align-self: center; - background-color: $white; - .primary-btn-text { - width: 100%; - } - &:hover { - color: $blue; - border-color: $blue; - background-color: $tlv-hover; - &:active { - color: $blue; - border-color: $blue; - } - } - - &:focus:not(:hover) { - color: $blue; - border-color: $blue; - background-color: $white; - } -} diff --git a/openecomp-ui/resources/scss/components/_commitModal.scss b/openecomp-ui/resources/scss/components/_commitModal.scss new file mode 100644 index 0000000000..e7f5d28933 --- /dev/null +++ b/openecomp-ui/resources/scss/components/_commitModal.scss @@ -0,0 +1,10 @@ + +.comment-commit-form { + .commit-modal-text { + padding-bottom: 30px; + } + .validation-buttons .sdc-button-default{ + min-width: 94px; + width: auto; + } +}
\ No newline at end of file diff --git a/openecomp-ui/resources/scss/components/_dropzone.scss b/openecomp-ui/resources/scss/components/_dropzone.scss index cad752d415..2479ae7f0c 100644 --- a/openecomp-ui/resources/scss/components/_dropzone.scss +++ b/openecomp-ui/resources/scss/components/_dropzone.scss @@ -6,3 +6,26 @@ opacity: 0.5; } } +.file-upload-box { + @extend .body-1; + display: flex; + text-align: center; + flex-direction: column; + justify-content: center; + border: 2px dashed $light-gray; + padding-top: 20px; + padding-bottom: 20px; + width: 382px; + align-items: center; + .upload-btn { + padding: 4px 20px; + } + .drag-text { + color: $blue; + @extend .body-1-semibold; + } + .or-text { + margin-top: 10px; + margin-bottom: 10px; + } +} diff --git a/openecomp-ui/resources/scss/components/_dualListBox.scss b/openecomp-ui/resources/scss/components/_dualListBox.scss index 4353ab39e8..0c7d82e31c 100644 --- a/openecomp-ui/resources/scss/components/_dualListBox.scss +++ b/openecomp-ui/resources/scss/components/_dualListBox.scss @@ -8,10 +8,7 @@ .dual-search-multi-select-section { flex: 1; - .dual-text-box-search-title, .dual-list-box-multi-select-text { - @extend .body-1; - color: $dark-gray; - } + .dual-text-box-search { margin: 5px 0 30px 0; } @@ -30,6 +27,9 @@ padding: 4px 0 4px 10px; } } + option:checked { + background: $blue linear-gradient(0deg, $blue 0%, $blue 100%); + } } } .dual-list-options-bar { diff --git a/openecomp-ui/resources/scss/components/_forms.scss b/openecomp-ui/resources/scss/components/_forms.scss index b662ce873c..58e843047f 100644 --- a/openecomp-ui/resources/scss/components/_forms.scss +++ b/openecomp-ui/resources/scss/components/_forms.scss @@ -1,8 +1,8 @@ .section-title { @extend .heading-3-semibold; - padding: 50px 0 30px 0; + padding: 50px 0 20px 0; &:first-child { - padding: 0 0 30px 0; + padding-top: 0; } } diff --git a/openecomp-ui/resources/scss/components/_grid.scss b/openecomp-ui/resources/scss/components/_grid.scss index 9a76f97546..f210b64df6 100644 --- a/openecomp-ui/resources/scss/components/_grid.scss +++ b/openecomp-ui/resources/scss/components/_grid.scss @@ -1,66 +1,71 @@ -$gridItemSpace: 15%; - .grid-section { - &:not(:last-of-type) { - 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; - } - } + $gridItemSpace: 15%; - .grid-col-1 { - @extend %grid-col-base; - flex-basis: 25%; - &:after { - flex-basis: $gridItemSpace; + @mixin gridCol($numOfCols, $flexBasis) { + .#{grid-col- + $numOfCols} { + @extend %grid-col-base; + flex-basis: $flexBasis; + &:not(.last-col-in-row):after { + flex-basis: $gridItemSpace / $numOfCols; 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: ' '; + @mixin gridColWithLastColumn($numOfCols, $flexBasis, $flexBasisLast) { + .#{grid-col- + $numOfCols} { + @extend %grid-col-base; + &:not(.last-col-in-row) { + flex-basis: $flexBasis; + margin-right: 5%; } - } - .grid-col-4 { - @extend %grid-col-base; - flex-basis: 100%; - &:after { - flex-basis: $gridItemSpace / 4; - content: ' '; + &.last-col-in-row { + flex-basis: $flexBasisLast; } - } + } + } + + &:not(:last-of-type) { + 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; + } + } + + &.has-last-col-set { + @include gridColWithLastColumn(1, 21%, 22%); + @include gridColWithLastColumn(2, 47%, 48%); + @include gridColWithLastColumn(3, 73%, 74%); + @include gridColWithLastColumn(4, 100%, 100%); + } + + &:not(.has-last-col-set) { + @include gridCol(1, 25%); + @include gridCol(2, 50%); + @include gridCol(3, 75%); + @include gridCol(4, 100%); + } } diff --git a/openecomp-ui/resources/scss/components/_icon.scss b/openecomp-ui/resources/scss/components/_icon.scss deleted file mode 100644 index c80055d055..0000000000 --- a/openecomp-ui/resources/scss/components/_icon.scss +++ /dev/null @@ -1,164 +0,0 @@ -$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/_listEditorView.scss b/openecomp-ui/resources/scss/components/_listEditorView.scss index c3e9fa6081..354a6a1f70 100644 --- a/openecomp-ui/resources/scss/components/_listEditorView.scss +++ b/openecomp-ui/resources/scss/components/_listEditorView.scss @@ -17,27 +17,6 @@ .list-editor-view-title { @extend .heading-3-semibold; } - .list-editor-view-add-controller { - @extend .body-1-semibold; - color: $blue; - display: table; - cursor: pointer; - position: relative; - padding-top: 0; - padding-bottom: 0; - 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; - } - } - } } .list-editor-view-list-scroller { @@ -68,9 +47,6 @@ overflow-wrap: break-word; white-space: initial; - .description { - @include multiline-ellipsis(1.3em, 3); - } .number-field { align-content: center; @@ -82,6 +58,9 @@ line-height: 0.9; } } + .description { + @include multiline-ellipsis(1.3em, 3); + } .text { @extend .body-1; } @@ -105,9 +84,8 @@ } } .svg-icon { + margin-top: 5px; transition: fill .3s; - height: 18px; - width: 18px; fill: $white; } } diff --git a/openecomp-ui/resources/scss/components/_navigationSideBar.scss b/openecomp-ui/resources/scss/components/_navigationSideBar.scss index daf5025bee..ab4d15fd90 100644 --- a/openecomp-ui/resources/scss/components/_navigationSideBar.scss +++ b/openecomp-ui/resources/scss/components/_navigationSideBar.scss @@ -18,9 +18,10 @@ .group-name { @extend .heading-4-semibold; @include ellipsis; - min-height: 56px; + min-height: 70px; display: block; - padding: 18px 12px 13px 40px; + height: 70px; + padding: 24px 12px 13px 40px; background-color: $white; border-bottom: 1px solid $tlv-light-gray; } diff --git a/openecomp-ui/resources/scss/components/_overlay.scss b/openecomp-ui/resources/scss/components/_overlay.scss new file mode 100644 index 0000000000..7c310bf1a6 --- /dev/null +++ b/openecomp-ui/resources/scss/components/_overlay.scss @@ -0,0 +1,26 @@ +.onboarding-overlay { + z-index: 1000; + border: 1px solid $light-gray; + position: absolute; + background-color: $white; + border-radius: 2px; + box-shadow: 0 3px 7px 1px rgba(0, 0, 0, 0.2); + display: flex; + flex-direction: column; + justify-content: space-around; + margin-top: 5px; + margin-left: -86px; + .arrow-up { + width: 0; + height: 0; + border-left: 5px solid transparent; + border-right: 5px solid transparent; + background-color: transparent; + border-bottom: 5px solid $blue; + margin-left: 114px; + margin-top: -5px; + } + .arrow-border { + border-top: 5px solid $blue; + } +}
\ No newline at end of file diff --git a/openecomp-ui/resources/scss/components/_tree.scss b/openecomp-ui/resources/scss/components/_tree.scss new file mode 100644 index 0000000000..e03594ee64 --- /dev/null +++ b/openecomp-ui/resources/scss/components/_tree.scss @@ -0,0 +1,56 @@ + +.tree-view { + overflow: hidden; + + &.scrollable { + overflow: auto; + } + + .node { + text-shadow: none; + stroke: none; + + .outer-circle { + stroke: $blue; + stroke-width: 2px; + fill: $white; + } + + .inner-circle { + fill: $blue; + } + + text { + text-anchor: end; + @extend .body-2-semibold; + fill: $blue; + } + + &.clickable { + cursor: pointer; + } + + &.selectedNode { + .outer-circle { + fill: $blue; + } + + .inner-circle { + fill: $blue; + } + + text { + fill: $blue; + } + } + } + + + .link { + fill: none; + stroke: $dark-gray; + stroke-opacity: 0.4; + stroke-width: 1.5px; + } + +} diff --git a/openecomp-ui/resources/scss/components/_userNotifications.scss b/openecomp-ui/resources/scss/components/_userNotifications.scss new file mode 100644 index 0000000000..74cafae438 --- /dev/null +++ b/openecomp-ui/resources/scss/components/_userNotifications.scss @@ -0,0 +1,123 @@ + +.onboarding-notifications { + margin-left: 10px; + .notifications-icon { + display: flex; + @extend .clickable; + .notifications-count { + color: $white; + font-size: 11px; + text-align: center; + width: 16px; + height: 16px; + background-color: $orange; + border-radius: 50%; + position: relative; + right: 7px; + top: -2px; + &.hidden-count { + background-color: transparent; + color: transparent; + } + } + } + .onboarding-overlay { + width: 520px; + right: 39px; + margin-top: 18px; + .arrow-up { + margin-left: 487px; + } + + .user-notifications { + .notifications-title { + color: $blue; + @extend .heading-5-semibold; + @extend .text-uppercase !optional; + padding: 13px 20px 10px 20px; + border-bottom: 1px solid $tlv-light-gray; + } + .notifications-list { + max-height: 600px; + overflow-y: auto; + .notification { + border-bottom: 1px solid $tlv-light-gray; + padding: 16px 20px 18px 20px; + display: flex; + &.unread { + background-color: lighten($gray, 38%); + .item-name { + display: flex; + @include base-font-bold; + } + .unread-circle-icon { + width: 8px; + height: 8px; + border-radius: 50%; + background-color: $blue; + align-self: center; + margin-bottom: 3px; + margin-left: 9px; + } + } + .notification-data { + width: 366px; + margin-right: 30px; + color: $dark-gray; + .item-name { + @extend .body-2-semibold; + @extend .text-uppercase !optional; + margin-bottom: 6px; + } + .flex-items { + display: flex; + margin: 6px 0 11px 0; + @extend .body-3; + line-height: 20px; + @extend .text-uppercase !optional; + color: $gray; + .separator { + border-left: 1px solid $dark-gray; + margin: 5px 8px; + } + } + .description { + @extend .body-3; + margin: 11px 0 8px 0; + .more-less { + font-size: $icon-font-size; + color: $blue; + } + } + .date { + font-size: $icon-font-size; + @include base-font-regular; + color: $gray; + margin-top: 8px; + } + } + + .notification-action .action-button { + @extend .clickable; + width: 74px; + height: 28px; + color: $white; + background-color: $blue; + border-radius: 2px; + text-align: center; + line-height: 2; + margin-top: 4px; + &.active { + background-color: #0091c7; + border: solid 1px #006186; + } + &:hover { + background-color: #1ec2ff; + border: solid 1px #0091c8; + } + } + } + } + } + } +} diff --git a/openecomp-ui/resources/scss/components/_versionController.scss b/openecomp-ui/resources/scss/components/_versionController.scss index 57610986c3..11e5b41675 100644 --- a/openecomp-ui/resources/scss/components/_versionController.scss +++ b/openecomp-ui/resources/scss/components/_versionController.scss @@ -1,102 +1,272 @@ .version-controller-bar { - 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; - justify-content: space-between; - padding-left: 16px; - padding-right: 40px; - .version-status-container { - display: flex; - height: 30px; - .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: 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; - - - .svg-icon { - fill: $dark-gray; - &:hover { - fill: $black; - } - &.__versionControllerLockClosed { - margin-top: -3px; - } - &.__versionControllerLockOpen { - margin-top: -6px; - } - &.__versionControllerSubmit { - fill: $blue; - &:hover { - fill: $dark-blue; - } - &.disabled { - fill: $dark-gray; - } - } - } - } - - - - - } - .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; - } - } - } + display: flex; + min-height: 70px; + border-bottom: 1px solid $tlv-light-gray; + background-color: transparent; + + .vc-container { + display: flex; + flex: 1; + align-self: center; + background-color: transparent; + justify-content: space-between; + align-items: center; + padding-left: 16px; + padding-right: 40px; + + .vc-separator { + border-left: 1px solid $tlv-light-gray; + height: 37px; + margin-left: 5px; + margin-right: 5px; + } + + .version-status-container { + display: flex; + height: 30px; + + .version-selector-more-versions { + color: $blue; + cursor: pointer; + } + + .version-selector { + margin-top: 0px; + padding-right: 10px; + margin-right: 15px; + margin-left: 10px; + border-color: $light-gray; + border-radius: 2px; + width: 243px; + height: 30px; + @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: 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; + align-items: center; + height: 100%; + + .action-buttons, .collaborator-action-buttons, .vc-save-section, .vc-submit-section { + display: flex; + align-items: center; + height: 100%; + + .vc-submit-button { + border: 1px solid $dark-gray; + width: 94px; + height: 30px; + border-radius: 2px; + padding-top: 5px; + padding-left: 10px; + margin-left: 10px; + margin-right: 10px; + + &:hover:not(.disabled) { + cursor: pointer; + background-color: $tlv-light-gray; + } + + &.disabled { + border-color: $light-gray; + } + + .vc-v-submit { + width: 11px; + height: 8px; + margin-right: 10px; + position: relative; + top: -1px; + } + } + + .version-control-buttons { + display: flex; + } + + .action-button-wrapper { + display: flex; + align-items: center; + height: 70px; + + &:hover:not(.disabled) { + background-color: $tlv-light-gray; + } + + &:active:not(.disabled) { + background-color: $light-gray; + } + + .action-buttons-svg { + padding-left: 10px; + padding-right: 10px; + + .svg-icon { + fill: $text-black; + height: 20px; + + &, &.__version-controller-save { width: 20px; } + &.__version-controller-permissions { width: 32px; } + &.__version-controller-undo, &.__version-controller-revert { width: 20px; } + &.__version-controller-sync, &.__version-controller-commit { width: 28px; } + } + } + + .version-controller-permissions { + width: 32px; + height: 20px; + fill: $dark-gray; + } + } + + .action-button-label { + display: block; + font-size: $icon-font-size; + font-family: $icon-font-family; + height: 1em; + margin-top: 5px; + margin-bottom: 0; + } + + .onboarding-overlay { + margin-top: -6px; + .permissions-overlay { + width: 237px; + + .permissions-overlay-header { + text-align: left; + color: $blue; + padding-bottom: 15px; + padding-top: 15px; + border-bottom: 1px solid $light-gray; + .permissions-overlay-header-title { + margin-left: 20px; + } + } + .permissions-overlay-content { + max-height: 290px; + overflow-y: auto; + padding-left: 10px; + padding-right: 10px; + .contributor { + &:last-child { + border-bottom: none; + } + border-bottom: 1px solid $tlv-light-gray; + .contributor-content { + padding-top: 12px; + padding-bottom: 10px; + margin-left: 10px; + display: flex; + .contributor-icon-circle { + &.selected { + border: 1px solid $blue; + } + + border-radius: 65px; + padding: 2px; + width: 32px; + height: 32px; + margin-top: 4px; + .contributer-icon { + width: 26px; + border-radius: 50px; + height: 26px; + margin-top: 0px; + .__user { + height: 18px; + width: 16px; + stroke: $blue; + fill: transparent; + margin-left: 5px; + margin-top: 3px; + } + &.selected { + border: 1px solid $blue; + background-color: $blue; + .__user { + stroke: $white; + margin-left: 4px; + } + } + } + } + + .contributer-info { + padding-left: 11px; + .contributer-name { + @extend .body-2-semibold; + text-transform: uppercase; + color: $dark-gray; + } + .contributer-role { + @extend .body-3; + color: $gray; + display: flex; + text-transform: lowercase; + p:first-letter { + text-transform: uppercase; + } + justify-content: space-between; + } + } + } + } + } + .permissions-overlay-footer { + .manage-permissions-btn { + @extend .body-2-semibold; + margin-top: 20px; + padding-top: 10px; + padding-bottom: 10px; + color: $blue; + text-align: center; + cursor: pointer; + background-color: $tlv-gray; + } + } + + } + } + } + } + .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 ad0bb77e8d..d9919c27e3 100644 --- a/openecomp-ui/resources/scss/modules/_entitlementPools.scss +++ b/openecomp-ui/resources/scss/modules/_entitlementPools.scss @@ -1,51 +1,22 @@ .entitlement-pools-list-editor { - .list-editor-view-list { - .list-editor-item-view { - min-height: 110px; - height: 110px; - } .list-editor-item-view-field { - .entitlement-pools-count, .contract-number, .type{ - color: $purple; - } .entitlement-pools-count { @extend .heading-1; - margin-top: -10px; - - } + color: $purple; } } } .entitlement-pools-modal { - .modal-body { - padding: 0; - } - .sdc-tab-content { - margin: 0; - } .entitlement-pools-form { - .threshold-section { + .threshold-section, .date-section { display: flex; justify-content: space-between; .validation-input-wrapper { flex: 0 0 46%; } } - .date-section { - display: flex; - justify-content: space-between; - .validation-input-wrapper { - flex: 0 0 46%; - } - } - .validation-form-content { - padding: 20px 50px; } - } - .validation-buttons { - padding: 20px 50px; - } } diff --git a/openecomp-ui/resources/scss/modules/_featureGroup.scss b/openecomp-ui/resources/scss/modules/_featureGroup.scss index 5f98ed2c05..cf681b8758 100644 --- a/openecomp-ui/resources/scss/modules/_featureGroup.scss +++ b/openecomp-ui/resources/scss/modules/_featureGroup.scss @@ -37,48 +37,5 @@ } } -.feature-group-modal { - .modal-body { - padding: 0; - } - .feature-group-form { - .no-items-msg { - margin-top: 55px; - color: $dark-gray; - } - .validation-form-content { - padding: 0; - } - .nav.nav-tabs { - padding-left: 50px; - } - .tab-content { - padding: 50px; - .field-section { - @extend .body-2-semibold; - margin-bottom: 23px; - width: 400px; - color: $black; - } - .description-field { - height: 170px; - } - .list-editor-item-view-content { - white-space: nowrap; - overflow: hidden; - > div { - overflow: hidden; - text-overflow: ellipsis; - &:not(:last-of-type) { - margin-right: 24px; - } - } - } - } - .validation-buttons { - padding: 20px 50px; - } - } -} diff --git a/openecomp-ui/resources/scss/modules/_licenseAgreement.scss b/openecomp-ui/resources/scss/modules/_licenseAgreement.scss index 7a7b87677e..579e9bab2b 100644 --- a/openecomp-ui/resources/scss/modules/_licenseAgreement.scss +++ b/openecomp-ui/resources/scss/modules/_licenseAgreement.scss @@ -2,10 +2,6 @@ .license-agreement-list-editor { .list-editor-view-list { - .list-editor-item-view { - min-height: 110px; - height: 110px; - } .list-editor-item-view-field { .list-editor-item-view-field-tight { vertical-align: top; @@ -17,46 +13,14 @@ overflow-wrap: break-word; } } - .feature-groups-count, .contract-number, .type { + .feature-groups-count, .type { color: $light-green; } .feature-groups-count { @extend .heading-1; padding-top: 2px; - text-align: center; - } - .contract-number { - margin-bottom: 8px; } - } - } -} -.license-agreement-modal { - .modal-body { - padding: 0; - } - .license-agreement-form { - .no-items-msg { - margin-top: 55px; - color: $dark-gray; - } - .tab-content { - padding: 50px; - .list-editor-item-view-content { - white-space: nowrap; - overflow: hidden; - > div { - overflow: hidden; - text-overflow: ellipsis; - &:not(:last-of-type) { - margin-right: 24px; - } - } - } - } - .validation-buttons { - padding: 20px 50px; } } } diff --git a/openecomp-ui/resources/scss/modules/_licenseKeyGroup.scss b/openecomp-ui/resources/scss/modules/_licenseKeyGroup.scss index d072849c08..bcb6abc83d 100644 --- a/openecomp-ui/resources/scss/modules/_licenseKeyGroup.scss +++ b/openecomp-ui/resources/scss/modules/_licenseKeyGroup.scss @@ -1,16 +1,11 @@ .license-key-groups-list-editor { .list-editor-view-list { - .list-editor-item-view { - min-height: 110px; - height: 110px; - } .list-editor-item-view-field { .operational-scope, .type { color: $orange; } .operational-scope { - margin-bottom: 0px; @include ellipsis; } } diff --git a/openecomp-ui/resources/scss/modules/_licenseModel.scss b/openecomp-ui/resources/scss/modules/_licenseModel.scss index fab091fe67..e93ea989fd 100644 --- a/openecomp-ui/resources/scss/modules/_licenseModel.scss +++ b/openecomp-ui/resources/scss/modules/_licenseModel.scss @@ -6,9 +6,6 @@ border-bottom: none; padding-bottom: 30px; } - .modal-body { - padding: 0; - } .sdc-tabs-list { padding-left: 50px; border-bottom: 1px solid $tlv-light-gray; @@ -25,10 +22,7 @@ text-align: end; } .license-model-form { - .validation-form-content { - padding: 20px 50px; - } - .validation-buttons { + .validation-form-content, .validation-buttons { padding: 20px 50px; } &.license-agreement-form, &.feature-group-form { @@ -51,3 +45,11 @@ } } } +.license-model-list-editor { + .list-editor-view-list { + .list-editor-item-view { + min-height: 110px; + height: 110px; + } + } +} diff --git a/openecomp-ui/resources/scss/modules/_licenseModelOverview.scss b/openecomp-ui/resources/scss/modules/_licenseModelOverview.scss index 9246b5fcbf..21c5bd8007 100644 --- a/openecomp-ui/resources/scss/modules/_licenseModelOverview.scss +++ b/openecomp-ui/resources/scss/modules/_licenseModelOverview.scss @@ -4,17 +4,14 @@ $icon-margin: 30px; $arrow-element-width: 30px; $list-item-padding: 15px; -@mixin overview-tile-shadow() { - @include box-shadow(0.5px 0.8px 4px 0 rgba(24, 24, 25, 0.05)); -} -// @mixin vlm-list-item-inset($color) { -// @include box-shadow(inset 6px 0 0 0 $color); -// } $la-color: $dark-blue; $fg-color: $blue; $lkg-ep-color: $light-blue; +@mixin overview-tile-shadow() { + @include box-shadow(0.5px 0.8px 4px 0 rgba(24, 24, 25, 0.05)); +} .license-model-overview { .overview-top-section { @@ -185,11 +182,8 @@ $lkg-ep-color: $light-blue; width: 100%; } .svg-icon-wrapper { - .svg-icon { &.__plusCircle { - width: 20px; - height: 20px; margin-top: 3px; margin-left: auto; fill: $dark-gray; @@ -197,7 +191,8 @@ $lkg-ep-color: $light-blue; fill: $blue; } } - } + } + } .summary-name-and-count { @@ -406,7 +401,7 @@ $lkg-ep-color: $light-blue; &.vlm-list-item-la { margin-top: 10px; .la-icon { - @include create-circle($circle-icon-size,$la-color,'LA'); + @include create-circle($circle-icon-size, $la-color); color: $white; } .vlm-list-item-title { @@ -439,7 +434,7 @@ $lkg-ep-color: $light-blue; margin-left: 29px; } .fg-icon { - @include create-circle($circle-icon-size,$fg-color,'FG'); + @include create-circle($circle-icon-size, $fg-color); color: $white; } @@ -467,7 +462,7 @@ $lkg-ep-color: $light-blue; margin-top: 10px; cursor: default; .ep-icon { - @include create-circle($circle-icon-size,$lkg-ep-color,'EP'); + @include create-circle($circle-icon-size, $lkg-ep-color); color: $white; } .vlm-list-item-title { @@ -490,7 +485,7 @@ $lkg-ep-color: $light-blue; margin-left: $list-indentation * 2; cursor: default; .lkg-icon { - @include create-circle($circle-icon-size,$lkg-ep-color,'KG'); + @include create-circle($circle-icon-size, $lkg-ep-color); color: $white; } .vlm-list-item-title { diff --git a/openecomp-ui/resources/scss/modules/_mergeEditor.scss b/openecomp-ui/resources/scss/modules/_mergeEditor.scss new file mode 100644 index 0000000000..96648dd20f --- /dev/null +++ b/openecomp-ui/resources/scss/modules/_mergeEditor.scss @@ -0,0 +1,207 @@ +$yours-bg-color: $tlv-gray; +$theirs-bg-color: $tlv-light-gray; +$error-text-color: $red; +$selected-width: 1px; +$selected-color: $blue; + +@mixin levels { + @for $i from 1 to 6 { + .level-#{$i} { + padding-left: 18px + 10 * $i; + } + } +} + +.merge-editor-modal { + .modal-lg { + width: 1300px; + } +} + +.merge-editor { + margin: 30px 40px; + max-height: 600px; + border: 1px solid $light-gray; + .grid-section { + &.conflict-titles-section { + @extend .body-1; + background-color: $blue; + height: 33px; + padding-top: 6px; + padding-bottom: 3px; + color: $white; + position: sticky; + top: 0; + z-index: 2; + border-bottom: 1px solid $tlv-light-gray; + .grid-item { + padding-left: 10px; + } + .form-group { + margin-bottom: 0; + .checkbox { + label { + margin-right: 0; + } + + text-align: right; + + input[type="checkbox"] { + cursor: pointer; + margin-top: 1px; + } + } + } + } + } + .merge-editor-body { + max-height: 500px; + overflow-y: scroll; + padding: 10px; + .conflict-section { + margin-bottom: 0; + border-left: 0; + border-right: 0; + padding: 5px 0; + + .conflict-resolve-btn { + align-self: flex-end; + } + + .grid-items { + align-items: center; + + input[type="radio"]:not(:checked) { + cursor: pointer; + } + } + } + + .collapsible-section { + display: flex; + cursor: pointer; + + .conflict-title { + @extend .heading-5-semibold; + text-transform: uppercase; + } + } + + .merge-chevron { + margin-right: 7px; + &.right { + transform: rotate(90deg); + } + } + + .grid-section .grid-items .field-col:not(.grid-col-title) { + &.grid-col-yours { + border-top: $selected-width solid $yours-bg-color; + border-bottom: $selected-width solid $yours-bg-color; + } + + &.theirs-color { + border-top: $selected-width solid $theirs-bg-color; + border-bottom: $selected-width solid $theirs-bg-color; + } + } + + .merge-editor-text-field { + display: flex; + justify-content: space-between; + // margin: 0 0 10px 0; + margin: 0; + + .field { + color: $text-black; + + &.field-name:not(.field-object-name) { + color: $gray; + } + } + + &.diff { + .field { + color: $red; + } + } + + &.grid-section { + padding-bottom: 0; + + .grid-items { + flex: 1; + + + .field-col { + padding: 7px 0; + height: 100%; + + &:not(:first-child) { + padding-left: 8px; + } + + &.grid-col-yours { + background-color: $yours-bg-color; + } + + &.grid-col-theirs { + background-color: $theirs-bg-color; + } + + @include levels; + + + .field { + @extend .body-1; + flex: 2; + min-width: 0; + + &.field-name { + @include multiline-ellipsis($bgColor: white); + &.diff { + color: $red; + } + text-transform: uppercase; + &.field-object-name { + @extend .body-1-semibold; + margin-bottom: 5px; + margin-top: 10px; + + } + } + + &.field-yours { + @include multiline-ellipsis($bgColor: $yours-bg-color); + } + + &.field-theirs { + @include multiline-ellipsis($bgColor: $theirs-bg-color); + } + &.field-name, &.field.field-yours, &.field.field-theirs { + word-break: break-word; + text-align: initial; + } + &.empty-field { + padding-top: 2px; + } + } + + *::after { + bottom: 0; + } + } + } + } + + &.field-error { + @extend .body-1; + color: $error-text-color; + min-width: 0; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } + } + } +} diff --git a/openecomp-ui/resources/scss/modules/_onboardingCatalog.scss b/openecomp-ui/resources/scss/modules/_onboardingCatalog.scss index 6c56d11049..4fb0f7c99e 100644 --- a/openecomp-ui/resources/scss/modules/_onboardingCatalog.scss +++ b/openecomp-ui/resources/scss/modules/_onboardingCatalog.scss @@ -8,6 +8,7 @@ $transitionLength: 0.6s; @import "onboardingCatalog/catalogHeader"; @import "onboardingCatalog/vendorPageHeader"; @import "onboardingCatalog/catalogList"; + @import "onboardingCatalog/vspOverlay"; .catalog-wrapper { height: 100%; overflow: auto; @@ -19,6 +20,38 @@ $transitionLength: 0.6s; .catalog-list { overflow: hidden; height: auto; + .sdc-tile { + margin: 9px; + .sdc-tile-header { + position: initial; + display: block; + flex-shrink: initial; + align-items: initial; + flex-direction: initial; + } + .sdc-tile-content { + position: initial; + flex: initial; + display: flex; + align-items: initial; + flex-direction: column; + justify-content: space-between; + overflow: initial; + .sdc-tile-info-line { + .with-overlay { + line-height: 1.2em; + @include ellipsis($width: initial, $max-width: 100%); + } + } + } + .sdc-tile-footer { + position: initial; + flex-shrink: initial; + display: flex; + align-items: center; + flex-direction: row; + } + } } } } diff --git a/openecomp-ui/resources/scss/modules/_permissions.scss b/openecomp-ui/resources/scss/modules/_permissions.scss new file mode 100644 index 0000000000..e652d9d82f --- /dev/null +++ b/openecomp-ui/resources/scss/modules/_permissions.scss @@ -0,0 +1,55 @@ +.modal-content { + .modal-body { + .manage-permissions-page { + .validation-form-content { + overflow-y: visible; + } + + .manage-permissions-title { + @extend .body-1-semibold; + margin-bottom: 10px; + } + .owner-details { + @extend .body-2; + display: flex; + margin-bottom: 30px; + .change-owner { + margin-left: auto; + color: $blue; + cursor: pointer; + &:hover { + color: $dark-blue; + } + } + } + .change-owner-wrapper { + .form-group { + margin-bottom: 30px; + } + + } + .change-owner-title { + display: flex; + align-items: center; + margin-bottom: 10px; + .manage-permissions-title { + margin-bottom: 0; + } + .svg-icon-wrapper { + margin-left: 5px; + .svg-icon { + width: 13px; + height: 13px; + fill: $dark-gray; + } + } + } + .contributors-select { + .Select-menu { + max-height: 150px; + overflow-y: auto + } + } + } + } +} diff --git a/openecomp-ui/resources/scss/modules/_revisions.scss b/openecomp-ui/resources/scss/modules/_revisions.scss new file mode 100644 index 0000000000..2b196c132c --- /dev/null +++ b/openecomp-ui/resources/scss/modules/_revisions.scss @@ -0,0 +1,86 @@ +.manage-revisions-modal { + .modal-dialog { + width: 700px; + } + .modal-content { + .modal-body { + .validation-form-content { + padding-top: 30px; + } + //.selected { + // .selectable { + // border-color: $light-blue; + // } + // .selectable:hover{ + // border-color: hotpink; + // } + //} + + .revision-list-item { + &.selected { + .selectable, .selectable:hover { + border-width: 2px; + border-color: $light-blue; + } + } + .selectable:hover{ + border-color: $gray; + } + .selectable:active { + border-color: $light-blue; + } + } + + .list-editor-view-list-scroller { + margin-top : 0px; + } + + .list-editor-view-header { + border-bottom: none; + .list-editor-view-title { + @extend .heading-5; + text-transform: none; + color: $blue; + } + } + + .list-editor-item-view-content { + background-color: $background-gray; + } + .revision-list-item-fields { + width: 100%; + display: flex; + flex-wrap: wrap; + .revision-user { + flex-basis: 50%; + fill: transparent; + stroke: $blue; + .svg-icon-label { + margin-left: 13px; + } + } + + .revision-date { + flex-basis: 50%; + text-align: right; + @extend .body-3; + color: $gray; + .revision-time { + margin-left: 5px; + } + } + + .revision-message { + flex-basis: 100%; + margin-top: 5px; + @extend .body-2; + .more-less { + @extend .body-3; + color: $blue; + margin-left: 5px; + } + } + } + } + } +} diff --git a/openecomp-ui/resources/scss/modules/_softwareProductAttachmentPage.scss b/openecomp-ui/resources/scss/modules/_softwareProductAttachmentPage.scss index c8d8cf4e0b..0ae3f00a29 100644 --- a/openecomp-ui/resources/scss/modules/_softwareProductAttachmentPage.scss +++ b/openecomp-ui/resources/scss/modules/_softwareProductAttachmentPage.scss @@ -1,21 +1,25 @@ .vsp-attachments-view { position: relative; - #attachments-tabs { - .nav-tabs { + .attachments-tabs { + .sdc-tabs-list { + padding-left: 28px; background-color: $tlv-gray; box-shadow: none; border-bottom: 1px solid $light-gray; - & > li { - & > a { + .sdc-tab { @extend .heading-2; - padding-left: 0; - padding-right: 0; - margin-right: 40px; - }; - &.active > a {color: $blue;}; + padding-top: 10px; + margin-top: 0; + &.sdc-tab-active { + color: $blue; + font-weight: bold; + } } } + .sdc-tab-content { + margin-top: 0; + } } .attachments-view-controllers { position: absolute; @@ -91,6 +95,11 @@ z-index: 1; padding-right: 20px; .counter { + .svg-icon { + &.__exclamationTriangleLine { + fill: $orange; + } + } display: flex; &:first-child { margin-right: 20px; @@ -215,6 +224,7 @@ .svg-icon { width: 20px; height: 20px; + fill: $orange; } } .error-item-file-type { diff --git a/openecomp-ui/resources/scss/modules/_softwareProductComponentGeneral.scss b/openecomp-ui/resources/scss/modules/_softwareProductComponentGeneral.scss index 6c5bcee03c..d31c7f0b92 100644 --- a/openecomp-ui/resources/scss/modules/_softwareProductComponentGeneral.scss +++ b/openecomp-ui/resources/scss/modules/_softwareProductComponentGeneral.scss @@ -10,7 +10,4 @@ } } } - .additional-validation-form { - margin-top: 50px; - } } diff --git a/openecomp-ui/resources/scss/modules/_softwareProductComponentImage.scss b/openecomp-ui/resources/scss/modules/_softwareProductComponentImage.scss index dad837f356..b67c448b54 100644 --- a/openecomp-ui/resources/scss/modules/_softwareProductComponentImage.scss +++ b/openecomp-ui/resources/scss/modules/_softwareProductComponentImage.scss @@ -23,9 +23,6 @@ } .image-modal-edit, .image-modal-new { - .modal-body { - padding: 0; - } .vsp-components-image-editor { .image-format, .image-md5, .image-version { @@ -35,13 +32,19 @@ padding-left: 30px; } .section-title { - text-transform: capitalize; + text-transform: uppercase; font-size: 18px; } } } .vsp-components-image { + .list-editor-view { + margin-top: 50px; + .manual-title { + @extend .body-1-semibold; + } + } .list-editor-item-view-content { flex:1; min-width: 0; diff --git a/openecomp-ui/resources/scss/modules/_softwareProductComponentNetwork.scss b/openecomp-ui/resources/scss/modules/_softwareProductComponentNetwork.scss index 402918bc5e..eaba47acb4 100644 --- a/openecomp-ui/resources/scss/modules/_softwareProductComponentNetwork.scss +++ b/openecomp-ui/resources/scss/modules/_softwareProductComponentNetwork.scss @@ -20,16 +20,7 @@ display: flex; } } -.network-nic-modal-edit, .network-nic-modal-create { - .modal-body { - padding: 0; - } - .validation-form-content { - padding-left: 50px; - padding-right: 50px; - padding-top: 20px; - } -} + .network-nic-modal-edit { .modal-dialog { width: 900px; diff --git a/openecomp-ui/resources/scss/modules/_softwareProductComponentProcessesPage.scss b/openecomp-ui/resources/scss/modules/_softwareProductComponentProcessesPage.scss index be4caacfb5..9476d7043d 100644 --- a/openecomp-ui/resources/scss/modules/_softwareProductComponentProcessesPage.scss +++ b/openecomp-ui/resources/scss/modules/_softwareProductComponentProcessesPage.scss @@ -1,7 +1,4 @@ .edit-process-modal { - .vsp-process-dropzone-view .grid-section { - padding-bottom: 30px !important; - } .component-process-description > textarea { height: 113px; } diff --git a/openecomp-ui/resources/scss/modules/_softwareProductDependencies.scss b/openecomp-ui/resources/scss/modules/_softwareProductDependencies.scss index 8fb739234f..65c558fa0e 100644 --- a/openecomp-ui/resources/scss/modules/_softwareProductDependencies.scss +++ b/openecomp-ui/resources/scss/modules/_softwareProductDependencies.scss @@ -2,14 +2,22 @@ .software-product-dependencies-title { @extend .heading-1; @extend .text-uppercase !optional; + position: sticky; + top: -30px; + z-index: 1; + background: $white; margin-bottom: 20px; color: $blue; } .select-action-table-controllers { + position: sticky; + top: 4px; + z-index: 1; + background: $white; justify-content: flex-end; cursor: pointer; color: $blue; - padding-right: 33px; + padding-right: 27px; margin-bottom: 3px; &:hover { color: $dark-blue; @@ -18,8 +26,23 @@ .select-action-table-view { min-width: 770px; } + .select-action-table-headers { + position: sticky; + top: 27px; + z-index: 1; .select-action-table-header { @extend .body-1-semibold; color: $text-black; + } + } + .select-action-table-row-wrapper { + .svg-icon { + &.__trashO, &.__plusCircle { + fill: $dark-gray; + &:hover { + fill: $black; } + } + } + } } diff --git a/openecomp-ui/resources/scss/modules/_softwareProductDeployment.scss b/openecomp-ui/resources/scss/modules/_softwareProductDeployment.scss index e0de8fc969..b5f9a546d9 100644 --- a/openecomp-ui/resources/scss/modules/_softwareProductDeployment.scss +++ b/openecomp-ui/resources/scss/modules/_softwareProductDeployment.scss @@ -2,9 +2,6 @@ .modal-dialog { width: 780px; } - .grid-section { - padding-bottom: 25px; - } .deployment-feature-groups-section.no-feature-groups { padding-bottom: 0; .form-group { @@ -25,15 +22,12 @@ } .modal-content { .modal-body { - padding: 0; .validation-form-content { + overflow-y: visible; .grid-col-1 { - flex-basis: 35%; + flex-basis: 30%; } - .Select-value, .Select-placeholder { - font-family: omnes-regular, sans-serif; - } .grid-section.vfc-table { padding-bottom: 50px; @@ -46,9 +40,6 @@ .grid-col-3 { flex-basis: 65%; } - padding-left: 54px; - padding-right: 33px; - overflow-y: visible; } } } diff --git a/openecomp-ui/resources/scss/modules/_softwareProductLandingPage.scss b/openecomp-ui/resources/scss/modules/_softwareProductLandingPage.scss index 28b54cc78f..99027d66ed 100644 --- a/openecomp-ui/resources/scss/modules/_softwareProductLandingPage.scss +++ b/openecomp-ui/resources/scss/modules/_softwareProductLandingPage.scss @@ -18,12 +18,7 @@ .description { @extend .body-1; - // overflow: hidden; padding-right: 20px; - // text-overflow: ellipsis; - // display: -webkit-box; - // -webkit-line-clamp: 2; - // -webkit-box-orient: vertical; .missing-license { display: flex; @@ -56,15 +51,9 @@ } } .software-product-landing-view { - transition: border .2s; padding-bottom: 50px; - .list-editor-view { - padding-top: 50px; - padding-left: 0; - padding-right: 0; - } .software-product-landing-view-top { .details-container { @extend .flex-column; @@ -110,6 +99,10 @@ &:last-child { margin-right: 0; } + .software-product-landing-view-top-block-col-upl { + height: 215px; + width: initial; + } } .col-md-6 { padding: 0; @@ -134,16 +127,19 @@ } } .software-product-landing-view-top-block { + &.clickable { cursor: pointer; + &:hover { + @extend .box-hover; + } + } border: 1px solid $light-gray; padding: 20px 18px 0 18px; height: 215px; display: flex; justify-content: space-between; background-color: $white; - &:hover { - @extend .box-hover; - } + .col-md-6 { @extend .body-1; } @@ -164,30 +160,12 @@ color: $light-blue; } } - } .software-product-landing-view-top-block-col-upl { @extend .flex; - height: 215px; - text-align: center; - flex-direction: column; - justify-content: center; - border: 2px dashed $light-gray; margin-bottom: 20px; - @extend .body-1; - align-items: center; - .upload-btn { - padding: 15px 55px; } - .drag-text { - color: $blue; - @extend .body-1-semibold; - } - .or-text { - margin-top: 10px; - margin-bottom: 10px; - } } } } @@ -195,6 +173,9 @@ } .vsp-details-page { + .grid-section-general { + padding-bottom: 30px; + } .vsp-general-tab { .validation-form-content { margin: 0; diff --git a/openecomp-ui/resources/scss/modules/_softwareProductProcessesPage.scss b/openecomp-ui/resources/scss/modules/_softwareProductProcessesPage.scss index d75e7447ab..3f2a2f9a69 100644 --- a/openecomp-ui/resources/scss/modules/_softwareProductProcessesPage.scss +++ b/openecomp-ui/resources/scss/modules/_softwareProductProcessesPage.scss @@ -1,10 +1,5 @@ .edit-process-modal { - background-color: $white; height: 100%; - &.modal-body { - padding: 0; - background-color: $white; - } .vsp-processes-editor { padding-left: 0; padding-right: 0; @@ -23,41 +18,22 @@ padding-top: 20px; padding-bottom: 20px; - align-items: center; - .upload-btn { - padding: 4px 20px; - } - .drag-text { - color: $blue; - @extend .body-1-semibold; - } - .or-text { - margin-top: 10px; - margin-bottom: 10px; + .process-type { + width: 100%; } } .vsp-processes-editor-data { - transition: border .2s; - .vsp-process-dropzone-view { - background-color: transparent; - &.active-dragging { - border: 3px dashed $dark-blue; - border-radius: 20px; - .draggable-wrapper { - opacity: 0.5; - } - } - .grid-section { - .section-title { - padding-bottom: 0; - } - } - } .validation-input-wrapper { .form-group.vsp-process-description > textarea { height: 113px; } } + .process-type { + width: 100%; + } + .process-editor-file-box { + width: 380px; + } } } } diff --git a/openecomp-ui/resources/scss/modules/_softwareproductComponentLoadBalancing.scss b/openecomp-ui/resources/scss/modules/_softwareproductComponentLoadBalancing.scss index d1f3f488bd..440b2424df 100644 --- a/openecomp-ui/resources/scss/modules/_softwareproductComponentLoadBalancing.scss +++ b/openecomp-ui/resources/scss/modules/_softwareproductComponentLoadBalancing.scss @@ -5,12 +5,6 @@ } .halb-data { - .load-balancing-page-title { - @extend .section-title; - &:first-child { - padding: 0 0 40px 0; - } - } .question { padding-top: 10px; &:first-child { diff --git a/openecomp-ui/resources/scss/modules/_uploadScreen.scss b/openecomp-ui/resources/scss/modules/_uploadScreen.scss index 4aa07f1580..23f41c8816 100644 --- a/openecomp-ui/resources/scss/modules/_uploadScreen.scss +++ b/openecomp-ui/resources/scss/modules/_uploadScreen.scss @@ -5,20 +5,6 @@ text-align: center; margin-bottom: 50px; } - .upload-screen-upload-block { - text-align: center; - padding: 50px; - border: 2px dashed lightgray; - } - .upload-screen-drop-zone { - &.active-dragging { - border: 3px dashed $dark-blue; - border-radius: 20px; - .draggable-wrapper { - opacity: 0.5; - } - } - } } .attachments-screen { diff --git a/openecomp-ui/resources/scss/modules/_versionsPage.scss b/openecomp-ui/resources/scss/modules/_versionsPage.scss new file mode 100644 index 0000000000..fa1dc11ec6 --- /dev/null +++ b/openecomp-ui/resources/scss/modules/_versionsPage.scss @@ -0,0 +1,325 @@ +.dox-ui-punch-out { + background-color: $content-background-color; +} + +.dox-ui-punch-out.dox-ui-punch-out-full-page { + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + overflow-y: auto; +} + +@mixin version-page-box-shadow() { + box-shadow: 0 1px 4px 0 rgba(24, 24, 24, 0.06); +} + +@mixin version-page-sub-title(){ + color: $text-black; + text-transform: uppercase; + background-color: $white; + border-bottom: 1px solid $light-gray; + padding: 12px 0 10px 23px; +} + +.versions-tree-modal { + .modal-dialog { + width: 800px; + } + + .tree-view { + display: flex; + align-items: center; + } +} + +.versions-page-view { + height: 100%; + background-color: $background-gray; + overflow: auto; + padding: 35px 50px 20px 50px; + + .svg-icon-wrapper { + justify-content: flex-start; + } + + .versions-page-title { + @extend .heading-1; + text-transform: uppercase; + margin-bottom: 29px; + color: $blue; + } + + .versions-page-permissions-view-wrapper { + @extend .body-1-semibold; + @include version-page-box-shadow(); + + .permissions-view-wrapper-title { + @include version-page-sub-title(); + } + + .svg-icon-wrapper.user-view { + fill: transparent; + stroke: $blue; + .svg-icon { + height: 18px; + width: 16px; + margin: 0 7px; + } + &.current-user { + .svg-icon { + background-color: $blue; + stroke: $white; + padding-top: 5px; + padding-bottom: 3px; + height: 29px; + width: 29px; + border-radius: 20px; + border: 1px solid $blue; + box-shadow: inset 0px 0px 0px 2px $white; + margin: 0; + } + .svg-icon-label { + margin-left: 7px; + } + } + .svg-icon-label { + @extend .body-2; + color: $dark-gray; + margin-left: 6px; + } + } + + .permissions-view-content { + padding: 20px 40px 20px 25px; + background-color: $white; + + height: 120px; + display: flex; + } + + .permissions-view { + display: flex; + flex: 1; + flex-direction: column; + justify-content: space-around; + + .permissions-view-title { + text-transform: uppercase; + color: $dark-gray; + } + + .contributors-view, .owner-view { + display: flex; + height: 16px; + @extend .body-1-semibold; + + .permissions-view-title { + width: 130px; + line-height: 16px; + } + + .extra-contributors { + border-radius: 30px; + background-color: $gray; + width: 26px; + height: 26px; + padding-right: 2px; + display: flex; + align-items: center; + justify-content: center; + color: $white; + cursor: default; + &:hover { + background-color: $dark-gray; + } + } + + .user-view { + margin-right: 38px; + } + + .manage-permissions { + color: $blue; + margin-left: auto; + cursor: pointer; + + &:hover { + color: $dark-blue; + } + } + } + } + } + + .versions-page-list-and-tree { + display: flex; + margin-top: 20px; + + .version-tree-wrapper { + display: flex; + flex-direction: column; + margin-right:10px; + transition: all 1s ease; + @include version-page-box-shadow(); + + .version-tree-title-container { + display: flex; + align-items: center; + height: 40px; + @include version-page-sub-title(); + padding-right: 10px; + + .version-tree-full-screen { + margin-left: auto; + } + } + + .tree-view { + background-color: $white; + flex: 1; + } + } + } + + .version-list { + flex: 1; + @extend .body-1-semibold; + color: $text-black; + display: flex; + flex-direction: column; + + .version-list-items { + flex: 1; + display: flex; + flex-direction: column; + + .version-item-row { + border-bottom: 1px solid $tlv-light-gray; + + &:last-child { + border-bottom: none; + } + } + } + + .version-item-row { + $row-hover-color: lighten($blue, 54%); + $row-active-color: lighten($blue, 51%); + + display: flex; + align-items: center; + padding: 15px 30px; + @include version-page-box-shadow(); + background-color: $white; + height: 70px; + + &:hover { + background-color: $row-hover-color; + } + + &.selected { + box-shadow: 0 1px 4px 0 rgba(24, 24, 24, 0.06), inset 5px 0 0 0 $blue; + background-color: $row-active-color; + &:hover { + background-color: $row-hover-color; + box-shadow: 0 1px 4px 0 rgba(24, 24, 24, 0.06), inset 5px 0 0 0 lighten($blue, 35%); + } + } + + &.header-row { + height: 40px; + + @extend .body-1-semibold; + @include version-page-sub-title(); + padding: 15px 27px; + + &:hover { + background-color: $white; + pointer-events: none; + &:active { + background-color: $white; + @include version-page-box-shadow(); + } + } + .header-field.actions { + margin-right: 57px; + } + } + + .version-item-field { + flex: 1; + display: flex; + margin-right: 10px; + + &.item-version, &.item-status { + flex: 0 1 10%; + @extend .body-1-semibold; + color: $text-black; + } + + &.item-description, &.item-last-edited { + @extend .body-1; + color: $dark-gray; + } + + &.item-description, &.header-description { + flex: 2 1 0; + } + + &.item-description > .description-text { + margin-right: 10px; + @include ellipsis($max-width: 300px); + } + + &.item-actions { + display: flex; + flex: 1 1 3%; + justify-content: space-between; + } + + &.item-select, &.item-create { + @extend .body-1; + flex: 0 1 auto; + margin-right: 0; + + .svg-icon-wrapper { + fill: $blue; + color: $blue; + + &[disabled] { + cursor: default; + } + + .svg-icon { + width: 16px; + height: 16px; + } + + &:hover:not([disabled]) { + fill: $dark-blue; + color: $dark-blue; + } + } + } + + } + + /* To keep ellipsis hider's background the same color as row background */ + &:not(.selected):hover .item-description > .description-text:after { + background: $row-hover-color + } + + &:hover:active .item-description > .description-text:after { + background: $row-active-color; + } + + } + + } + + &.clickable { + cursor: pointer; + } +} diff --git a/openecomp-ui/resources/scss/modules/_vspComponentCompute.scss b/openecomp-ui/resources/scss/modules/_vspComponentCompute.scss index ee8cfa5c7f..9f88e94393 100644 --- a/openecomp-ui/resources/scss/modules/_vspComponentCompute.scss +++ b/openecomp-ui/resources/scss/modules/_vspComponentCompute.scss @@ -1,16 +1,3 @@ -.vsp-component-computeFlavor-view { - .component-questionnaire-validation-form { - .vm-sizing-section { - .section-title { - text-transform: capitalize; - font-size: 18px; - } - .duplicate-title-line label.control-label{ - height: 2.7em; - } - } - } -} .compute-flavor-editor-modal-edit { .modal-lg { diff --git a/openecomp-ui/resources/scss/modules/_vspComponentMonitoring.scss b/openecomp-ui/resources/scss/modules/_vspComponentMonitoring.scss index bda8512f36..14bad18179 100644 --- a/openecomp-ui/resources/scss/modules/_vspComponentMonitoring.scss +++ b/openecomp-ui/resources/scss/modules/_vspComponentMonitoring.scss @@ -1,34 +1,9 @@ .vsp-component-monitoring { .dropzone { - .section-title { - padding-bottom: 20px; - } &:not(:last-child) { padding-bottom: 50px; } - .software-product-landing-view-top-block-col-upl { - @extend .body-1; - width: 400px; - display: flex; - text-align: center; - flex-direction: column; - justify-content: center; - border: 2px dashed $light-gray; - padding: 25px 0; - align-items: center; - .upload-btn { - padding: 4px 20px; - } - .drag-text { - color: $blue; - @extend .body-1-semibold - } - .or-text { - margin-top: 10px; - margin-bottom: 10px; - } - } .monitoring-file { display: flex; @@ -46,7 +21,4 @@ } } - .delete-button { - min-width: 0; - } } diff --git a/openecomp-ui/resources/scss/modules/_vspComponentQuestionnaire.scss b/openecomp-ui/resources/scss/modules/_vspComponentQuestionnaire.scss index 5696b354a7..2a99263285 100644 --- a/openecomp-ui/resources/scss/modules/_vspComponentQuestionnaire.scss +++ b/openecomp-ui/resources/scss/modules/_vspComponentQuestionnaire.scss @@ -1,6 +1,6 @@ .vsp-component-questionnaire-view { - input[type='radio'], input[type='checkbox'] { + input[type='checkbox'] { &:before { border: 1px solid $dark-gray; cursor: pointer; @@ -30,14 +30,13 @@ .radio-options-content-row { display: flex; margin-top: -4px; - .validation-input-wrapper { - width: 240px; - margin-right: 7px; + .validation-radio-wrapper { + margin-right: 20px; & > .form-group { display: flex; } - .form-group .radio { + .form-group .sdc-radio { width: auto; margin-right: 0; } diff --git a/openecomp-ui/resources/scss/modules/onboardingCatalog/_catalogHeader.scss b/openecomp-ui/resources/scss/modules/onboardingCatalog/_catalogHeader.scss index d29a95d3d6..0a234a5a96 100644 --- a/openecomp-ui/resources/scss/modules/onboardingCatalog/_catalogHeader.scss +++ b/openecomp-ui/resources/scss/modules/onboardingCatalog/_catalogHeader.scss @@ -14,7 +14,7 @@ flex-direction: row; .tab-separator { position: relative; - top: 13px; + top: 8px; } .catalog-header-tab { @extend .heading-1; diff --git a/openecomp-ui/resources/scss/modules/onboardingCatalog/_onboardHeader.scss b/openecomp-ui/resources/scss/modules/onboardingCatalog/_onboardHeader.scss index 32ebac98cf..f97641cbe3 100644 --- a/openecomp-ui/resources/scss/modules/onboardingCatalog/_onboardHeader.scss +++ b/openecomp-ui/resources/scss/modules/onboardingCatalog/_onboardHeader.scss @@ -5,15 +5,16 @@ justify-content: flex-end; background-color: $tlv-light-gray; margin-bottom: 2px; + padding-left: 60px; + padding-right: 40px; @include box-shadow(0px 1px 3px 0 rgba(0, 0, 0, 0.2)); .expandable-input-top { - margin-right: 60px; + margin-right: 20px; margin-left: auto; } .onboard-header-tabs { display: flex; flex-direction: row; - margin-left: 60px; .onboard-header-tab { @extend .body-1-semibold; margin-right: 40px; diff --git a/openecomp-ui/resources/scss/modules/onboardingCatalog/_vspOverlay.scss b/openecomp-ui/resources/scss/modules/onboardingCatalog/_vspOverlay.scss index 80ed7385e0..e0b72bf9ff 100644 --- a/openecomp-ui/resources/scss/modules/onboardingCatalog/_vspOverlay.scss +++ b/openecomp-ui/resources/scss/modules/onboardingCatalog/_vspOverlay.scss @@ -54,7 +54,7 @@ &:hover { color: $blue; } - text-transform: uppercase; + text-transform: none; @include ellipsis(auto, block); border-bottom: 1px solid $tlv-light-gray; cursor: pointer; diff --git a/openecomp-ui/resources/scss/onboarding.scss b/openecomp-ui/resources/scss/onboarding.scss index fc05f7493e..2c7c55530d 100644 --- a/openecomp-ui/resources/scss/onboarding.scss +++ b/openecomp-ui/resources/scss/onboarding.scss @@ -130,6 +130,16 @@ div[data-reactroot].tooltip { border-top-color: $dark-gray !important; } } + &.right { + .tooltip-arrow { + border-right-color: $dark-gray !important; + } + } + &.left { + .tooltip-arrow { + border-left-color: $dark-gray !important; + } + } .tooltip-inner { @extend .body-1; max-width: 100%; @@ -149,6 +159,18 @@ div[data-reactroot].tooltip { padding: 3px 12px; } } + // manage permisions modal + &.manage-permissions-owner-tooltip { + .tooltip-inner { + width: 400px; + } + } + // WS/Catalog Tile + &.tile-super-info { + .tooltip-inner { + font-size: $body-font-3; + } + } //dependency table error tooltip &.select-action-table-error-tooltip{ @include base-font-regular; diff --git a/openecomp-ui/src/nfvo-components/SubmitErrorResponse.jsx b/openecomp-ui/src/nfvo-components/SubmitErrorResponse.jsx index 40daeff9c5..c15cd1d0e8 100644 --- a/openecomp-ui/src/nfvo-components/SubmitErrorResponse.jsx +++ b/openecomp-ui/src/nfvo-components/SubmitErrorResponse.jsx @@ -60,7 +60,7 @@ class SubmitErrorResponse extends Component { return ( <ErrorBlock errorType={i18n('VSP Errors')}> <div> - {errors.length && errors.map(error=>{return (<ErrorMessage error={error.message}/>);})} + {errors.length && errors.map((error, i) => {return (<ErrorMessage key={i} error={error.message}/>);})} </div> </ErrorBlock> ); @@ -71,7 +71,7 @@ class SubmitErrorResponse extends Component { return ( <ErrorBlock errorType={i18n('Components Errors')}> <div> - {errors.validationData.length && errors.validationData.map(item =>{ return (<ComponentError item={item}/>);})} + {errors.validationData.length && errors.validationData.map((item, i) =>{ return (<ComponentError key={i} item={item}/>);})} </div> </ErrorBlock> ); @@ -90,11 +90,10 @@ class SubmitErrorResponse extends Component { 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}/>);})} + {item.errors.map((error, i) => {return(<ErrorMessage key={i} error={error}/>);})} </div> ); }; @@ -110,7 +109,7 @@ const UploadErrorList = ({items}) => { let errors = []; for (let item of generator) {errors.push( - <div> + <div key={item.header}> <div className='component-name-header'>{item.header}</div> {item.list.map((error, i) => <ErrorMessage key={i} warning={error.level === 'WARNING'} error={error.message}/> )} </div> diff --git a/openecomp-ui/src/nfvo-components/datepicker/Datepicker.jsx b/openecomp-ui/src/nfvo-components/datepicker/Datepicker.jsx index f4673c1c93..25e7e7e02d 100644 --- a/openecomp-ui/src/nfvo-components/datepicker/Datepicker.jsx +++ b/openecomp-ui/src/nfvo-components/datepicker/Datepicker.jsx @@ -1,4 +1,5 @@ import React from 'react'; +import PropTypes from 'prop-types'; import DatePicker from 'react-datepicker'; import moment from 'moment'; import SVGIcon from 'sdc-ui/lib/react/SVGIcon.js'; @@ -6,10 +7,10 @@ import SVGIcon from 'sdc-ui/lib/react/SVGIcon.js'; class CustomInput extends React.Component { static propTypes = { - placeHolderText: React.PropTypes.string, - onChange: React.PropTypes.func, - onClick: React.PropTypes.func, - value: React.PropTypes.string + placeHolderText: PropTypes.string, + onChange: PropTypes.func, + onClick: PropTypes.func, + value: PropTypes.string }; render() { @@ -32,16 +33,16 @@ const parseDate = (date, format) => { class Datepicker extends React.Component { static propTypes = { - date: React.PropTypes.oneOfType([React.PropTypes.string, React.PropTypes.number]), - format: React.PropTypes.string, - onChange: React.PropTypes.func, - selectsStart: React.PropTypes.bool, - selectsEnd: React.PropTypes.bool, - startDate: React.PropTypes.oneOfType([React.PropTypes.string, React.PropTypes.number]), - endDate: React.PropTypes.oneOfType([React.PropTypes.string, React.PropTypes.number]), - disabled: React.PropTypes.bool, - label: React.PropTypes.string, - isRequired: React.PropTypes.bool + date: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), + format: PropTypes.string, + onChange: PropTypes.func, + selectsStart: PropTypes.bool, + selectsEnd: PropTypes.bool, + startDate: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), + endDate: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), + disabled: PropTypes.bool, + label: PropTypes.string, + isRequired: PropTypes.bool } render() { let {date, format, onChange, selectsStart = false, startDate = null, endDate = null, selectsEnd = false, diff --git a/openecomp-ui/src/nfvo-components/editor/TabulatedEditor.jsx b/openecomp-ui/src/nfvo-components/editor/TabulatedEditor.jsx index 2a0b7d4d2a..3c9ceed0d8 100644 --- a/openecomp-ui/src/nfvo-components/editor/TabulatedEditor.jsx +++ b/openecomp-ui/src/nfvo-components/editor/TabulatedEditor.jsx @@ -22,7 +22,8 @@ import NavigationSideBar from 'nfvo-components/panel/NavigationSideBar.jsx'; export default class TabulatedEditor extends React.Component { render() { - const {navigationBarProps, onToggle, onVersionSwitching, onCreate, onSave, onClose, onVersionControllerAction, onNavigate, children, meta} = this.props; + const {navigationBarProps, onToggle, onVersionSwitching, onMoreVersionsClick, onCreate, onSave, onClose, + onVersionControllerAction, onNavigate, children, meta, onManagePermissions, onOpenCommentCommitModal, onOpenPermissions, onOpenRevisionsModal} = this.props; let {versionControllerProps} = this.props; const {className = ''} = React.Children.only(children).props; const child = this.prepareChild(); @@ -42,7 +43,12 @@ export default class TabulatedEditor extends React.Component { <VersionController {...versionControllerProps} onVersionSwitching={version => onVersionSwitching(version, meta)} - callVCAction={(action, version) => onVersionControllerAction(action, version, meta)} + onMoreVersionsClick={onMoreVersionsClick} + onManagePermissions={onManagePermissions} + onOpenCommentCommitModal={onOpenCommentCommitModal} + onOpenPermissions={onOpenPermissions} + onOpenRevisionsModal={onOpenRevisionsModal} + callVCAction={(action, version, comment) => onVersionControllerAction(action, version, comment, meta)} onCreate={onCreate && this.handleCreate} onSave={onSave && this.handleSave}/> <div className={classnames('content-area', `${className}`)}> diff --git a/openecomp-ui/src/nfvo-components/fileupload/DraggableUploadFileBox.jsx b/openecomp-ui/src/nfvo-components/fileupload/DraggableUploadFileBox.jsx index 629b9449a2..5b4e0a8bee 100644 --- a/openecomp-ui/src/nfvo-components/fileupload/DraggableUploadFileBox.jsx +++ b/openecomp-ui/src/nfvo-components/fileupload/DraggableUploadFileBox.jsx @@ -34,11 +34,10 @@ class DraggableUploadFileBox extends Component { render() { let {className, onClick, dataTestId, isReadOnlyMode} = this.props; return ( - <div - className={`${className}${isReadOnlyMode ? ' disabled' : ''}`}> - <div className={`${'drag-text'}${isReadOnlyMode ? ' disabled' : ''}`}>{i18n('Drag & drop for upload')}</div> + <div className={`file-upload-box ${className} ${isReadOnlyMode ? 'disabled' : ''}`}> + <div className={`drag-text ${isReadOnlyMode ? 'disabled' : ''}`}>{i18n('Drag & drop for upload')}</div> <div className='or-text'>{i18n('or')}</div> - <Button type='button' data-test-id={dataTestId} btnType='outline' onClick={onClick} disabled={isReadOnlyMode === true}>{i18n('Select File')}</Button> + <Button type='button' data-test-id={dataTestId} btnType='outline' onClick={onClick} disabled={isReadOnlyMode}>{i18n('Select File')}</Button> </div> ); } diff --git a/openecomp-ui/src/nfvo-components/grid/GridItem.jsx b/openecomp-ui/src/nfvo-components/grid/GridItem.jsx index 8819ab78a3..c62e042bf4 100644 --- a/openecomp-ui/src/nfvo-components/grid/GridItem.jsx +++ b/openecomp-ui/src/nfvo-components/grid/GridItem.jsx @@ -15,8 +15,8 @@ */ import React from 'react'; -const GridItem = ({colSpan = 1, children, stretch = false}) => ( - <div className={`grid-col-${colSpan}`}> +const GridItem = ({colSpan = 1, children, lastColInRow = false, stretch = false, className = ''}) => ( + <div className={`grid-col-${colSpan} ${lastColInRow ? 'last-col-in-row' : ''} ${className}`}> <div className={`grid-item${stretch ? '-stretch' : ''}`}> {children} </div> diff --git a/openecomp-ui/src/nfvo-components/grid/GridSection.jsx b/openecomp-ui/src/nfvo-components/grid/GridSection.jsx index de8a4f3e64..8f4a024fdb 100644 --- a/openecomp-ui/src/nfvo-components/grid/GridSection.jsx +++ b/openecomp-ui/src/nfvo-components/grid/GridSection.jsx @@ -14,11 +14,12 @@ * permissions and limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import classnames from 'classnames'; -const GridSection = ({title, children, className, titleClassName}) => { +const GridSection = ({title, children, className = '', titleClassName, hasLastColSet = false}) => { return ( - <div className={classnames('grid-section', className)}> + <div className={classnames('grid-section', className, {'has-last-col-set': hasLastColSet})}> {title && <div className={`section-title ${titleClassName || ''}`}>{title}</div>} <div className='grid-items'> {children} @@ -28,7 +29,9 @@ const GridSection = ({title, children, className, titleClassName}) => { }; GridSection.propTypes = { - title: React.PropTypes.string, + title: PropTypes.string, + titleClassName: PropTypes.string, + hasLastColSet: PropTypes.bool }; export default GridSection; diff --git a/openecomp-ui/src/nfvo-components/icon/Icon.jsx b/openecomp-ui/src/nfvo-components/icon/Icon.jsx deleted file mode 100644 index 125577664b..0000000000 --- a/openecomp-ui/src/nfvo-components/icon/Icon.jsx +++ /dev/null @@ -1,45 +0,0 @@ -/*! - * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ -import React, { 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/input/ExpandableInput.jsx b/openecomp-ui/src/nfvo-components/input/ExpandableInput.jsx index eab1d45ef4..82fbe1deed 100644 --- a/openecomp-ui/src/nfvo-components/input/ExpandableInput.jsx +++ b/openecomp-ui/src/nfvo-components/input/ExpandableInput.jsx @@ -14,6 +14,7 @@ * permissions and limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import ReactDOM from 'react-dom'; import SVGIcon from 'sdc-ui/lib/react/SVGIcon.js'; import Input from 'nfvo-components/input/validation/InputWrapper.jsx'; @@ -76,9 +77,9 @@ class ExpandableInputOpened extends React.Component { class ExpandableInput extends React.Component { static propTypes = { - iconType: React.PropTypes.string, - onChange: React.PropTypes.func, - value: React.PropTypes.string + iconType: PropTypes.string, + onChange: PropTypes.func, + value: PropTypes.string }; state = {showInput: false}; diff --git a/openecomp-ui/src/nfvo-components/input/ToggleInput.jsx b/openecomp-ui/src/nfvo-components/input/ToggleInput.jsx index 23af72a26a..31a8a66d86 100644 --- a/openecomp-ui/src/nfvo-components/input/ToggleInput.jsx +++ b/openecomp-ui/src/nfvo-components/input/ToggleInput.jsx @@ -14,15 +14,16 @@ * permissions and limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; export default class ToggleInput extends React.Component { static propTypes = { - label: React.PropTypes.node, - value: React.PropTypes.bool, - onChange: React.PropTypes.func, - disabled: React.PropTypes.bool + label: PropTypes.node, + value: PropTypes.bool, + onChange: PropTypes.func, + disabled: PropTypes.bool } static defaultProps = { diff --git a/openecomp-ui/src/nfvo-components/input/dualListbox/DualListboxView.jsx b/openecomp-ui/src/nfvo-components/input/dualListbox/DualListboxView.jsx index a3be363ba4..a689c50778 100644 --- a/openecomp-ui/src/nfvo-components/input/dualListbox/DualListboxView.jsx +++ b/openecomp-ui/src/nfvo-components/input/dualListbox/DualListboxView.jsx @@ -14,6 +14,7 @@ * permissions and limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import SVGIcon from 'sdc-ui/lib/react/SVGIcon.js'; import Input from 'nfvo-components/input/validation/InputWrapper.jsx'; @@ -21,17 +22,17 @@ class DualListboxView extends React.Component { static propTypes = { - availableList: React.PropTypes.arrayOf(React.PropTypes.shape({ - id: React.PropTypes.string.isRequired, - name: React.PropTypes.string.isRequired + availableList: PropTypes.arrayOf(PropTypes.shape({ + id: PropTypes.string.isRequired, + name: PropTypes.string.isRequired })), - filterTitle: React.PropTypes.shape({ - left: React.PropTypes.string, - right: React.PropTypes.string + filterTitle: PropTypes.shape({ + left: PropTypes.string, + right: PropTypes.string }), - selectedValuesList: React.PropTypes.arrayOf(React.PropTypes.string), + selectedValuesList: PropTypes.arrayOf(PropTypes.string), - onChange: React.PropTypes.func.isRequired + onChange: PropTypes.func.isRequired }; static defaultProps = { diff --git a/openecomp-ui/src/nfvo-components/input/validation/Form.jsx b/openecomp-ui/src/nfvo-components/input/validation/Form.jsx index 8d53322587..6df0bf9009 100644 --- a/openecomp-ui/src/nfvo-components/input/validation/Form.jsx +++ b/openecomp-ui/src/nfvo-components/input/validation/Form.jsx @@ -15,6 +15,7 @@ */ import React from 'react'; +import PropTypes from 'prop-types'; import ValidationButtons from './ValidationButtons.jsx'; class Form extends React.Component { @@ -31,18 +32,18 @@ class Form extends React.Component { }; 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, - submitButtonText: React.PropTypes.string, - cancelButtonText: React.PropTypes.string, - onValidChange : React.PropTypes.func, - onValidityChanged: React.PropTypes.func, - onValidateForm: React.PropTypes.func + isValid : PropTypes.bool, + formReady : PropTypes.bool, + isReadOnlyMode : PropTypes.bool, + hasButtons : PropTypes.bool, + onSubmit : PropTypes.func, + onReset : PropTypes.func, + labledButtons: PropTypes.bool, + submitButtonText: PropTypes.string, + cancelButtonText: PropTypes.string, + onValidChange : PropTypes.func, + onValidityChanged: PropTypes.func, + onValidateForm: PropTypes.func }; constructor(props) { @@ -124,13 +125,21 @@ class Form extends React.Component { export class TabsForm extends Form { render() { // eslint-disable-next-line no-unused-vars - let {isValid, formReady, onValidateForm, isReadOnlyMode, hasButtons, onSubmit, labledButtons, onValidChange, onValidityChanged, onDataChanged, children, ...formProps} = this.props; + let {submitButtonText, cancelButtonText, 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'> {children} </div> - {hasButtons && <ValidationButtons labledButtons={labledButtons} ref={(buttons) => this.buttons = buttons} isReadOnlyMode={isReadOnlyMode}/>} + {hasButtons && + <ValidationButtons + labledButtons={labledButtons} + submitButtonText={submitButtonText} + cancelButtonText={cancelButtonText} + ref={buttons => this.buttons = buttons} + isReadOnlyMode={isReadOnlyMode}/> + } </form> ); } diff --git a/openecomp-ui/src/nfvo-components/input/validation/Input.jsx b/openecomp-ui/src/nfvo-components/input/validation/Input.jsx index eef8fee1ce..9f0e9acca8 100644 --- a/openecomp-ui/src/nfvo-components/input/validation/Input.jsx +++ b/openecomp-ui/src/nfvo-components/input/validation/Input.jsx @@ -17,7 +17,7 @@ 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 Radio from 'sdc-ui/lib/react/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'; @@ -85,7 +85,7 @@ class Input extends React.Component { className={classNames({'required' : isRequired , 'has-error' : !isValid})} onChange={(e)=>this.onChangeCheckBox(e)} disabled={isReadOnlyMode || Boolean(disabled)} - checked={value} + checked={checked} data-test-id={this.props['data-test-id']}>{label}</Checkbox>} {type === 'radio' && @@ -93,9 +93,10 @@ class Input extends React.Component { checked={checked} disabled={isReadOnlyMode || Boolean(disabled)} value={value} - onChange={(e)=>this.onChangeRadio(e)} + onChange={(isChecked)=>this.onChangeRadio(isChecked)} inputRef={(input) => this.input = input} - data-test-id={this.props['data-test-id']}>{label}</Radio>} + label={label} + data-test-id={this.props['data-test-id']} />} {type === 'select' && <FormControl onClick={ (e) => this.optionSelect(e) } componentClass={type} @@ -156,16 +157,17 @@ class Input extends React.Component { onChangeCheckBox(e) { let {onChange} = this.props; + let checked = e.target.checked; this.setState({ - checked: e.target.checked + checked }); - onChange(e.target.checked); + onChange(checked); } - onChangeRadio(e) { + onChangeRadio(isChecked) { let {onChange} = this.props; this.setState({ - checked: e.target.checked + checked: isChecked }); onChange(this.state.value); } diff --git a/openecomp-ui/src/nfvo-components/input/validation/InputOptions.jsx b/openecomp-ui/src/nfvo-components/input/validation/InputOptions.jsx index 9b11d27c2b..11b07ba9da 100644 --- a/openecomp-ui/src/nfvo-components/input/validation/InputOptions.jsx +++ b/openecomp-ui/src/nfvo-components/input/validation/InputOptions.jsx @@ -14,6 +14,7 @@ * permissions and limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import ReactDOM from 'react-dom'; import i18n from 'nfvo-utils/i18n/i18n.js'; import classNames from 'classnames'; @@ -26,27 +27,27 @@ 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 + values: PropTypes.arrayOf(PropTypes.shape({ + enum: PropTypes.string, + title: PropTypes.string })), - isEnabledOther: React.PropTypes.bool, - label: React.PropTypes.string, - selectedValue: React.PropTypes.string, - multiSelectedEnum: React.PropTypes.oneOfType([ - React.PropTypes.string, - React.PropTypes.array + isEnabledOther: PropTypes.bool, + label: PropTypes.string, + selectedValue: PropTypes.string, + multiSelectedEnum: PropTypes.oneOfType([ + PropTypes.string, + 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 + selectedEnum: PropTypes.string, + otherValue: PropTypes.string, + overlayPos: PropTypes.string, + onEnumChange: PropTypes.func, + onOtherChange: PropTypes.func, + onBlur: PropTypes.func, + isRequired: PropTypes.bool, + isMultiSelect: PropTypes.bool, + isValid: PropTypes.bool, + disabled: PropTypes.bool }; state = { diff --git a/openecomp-ui/src/nfvo-components/input/validation/InputWrapper.jsx b/openecomp-ui/src/nfvo-components/input/validation/InputWrapper.jsx index 6c8115deee..e440fcda69 100644 --- a/openecomp-ui/src/nfvo-components/input/validation/InputWrapper.jsx +++ b/openecomp-ui/src/nfvo-components/input/validation/InputWrapper.jsx @@ -17,7 +17,7 @@ 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 Radio from 'sdc-ui/lib/react/Radio.js'; import FormGroup from 'react-bootstrap/lib/FormGroup.js'; import FormControl from 'react-bootstrap/lib/FormControl.js'; @@ -72,8 +72,8 @@ class InputWrapper extends React.Component { disabled={isReadOnlyMode || Boolean(disabled)} value={value} ref={(input) => this.inputWrapper = input} - onChange={(e)=>this.onChangeRadio(e)} - data-test-id={this.props['data-test-id']}>{label}</Radio>} + onChange={(isChecked)=>this.onChangeRadio(isChecked)} label={label} + data-test-id={this.props['data-test-id']} />} {type === 'select' && <FormControl onClick={ (e) => this.optionSelect(e) } componentClass={type} @@ -119,10 +119,10 @@ class InputWrapper extends React.Component { onChange(e.target.checked); } - onChangeRadio(e) { + onChangeRadio(isChecked) { let {onChange} = this.props; this.setState({ - checked: e.target.checked + checked: isChecked }); onChange(this.state.value); } diff --git a/openecomp-ui/src/nfvo-components/input/validation/Tabs.jsx b/openecomp-ui/src/nfvo-components/input/validation/Tabs.jsx index 6f33536b04..0982c133e6 100644 --- a/openecomp-ui/src/nfvo-components/input/validation/Tabs.jsx +++ b/openecomp-ui/src/nfvo-components/input/validation/Tabs.jsx @@ -14,6 +14,7 @@ * permissions and limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import ReactDOM from 'react-dom'; import {default as SDCTabs} from 'sdc-ui/lib/react/Tabs.js'; import Overlay from 'react-bootstrap/lib/Overlay.js'; @@ -25,7 +26,7 @@ export default class Tabs extends React.Component { static propTypes = { - children: React.PropTypes.node + children: PropTypes.node }; cloneTab(element) { diff --git a/openecomp-ui/src/nfvo-components/input/validation/ValidationButtons.jsx b/openecomp-ui/src/nfvo-components/input/validation/ValidationButtons.jsx index c3808dd2c3..151d3fe859 100644 --- a/openecomp-ui/src/nfvo-components/input/validation/ValidationButtons.jsx +++ b/openecomp-ui/src/nfvo-components/input/validation/ValidationButtons.jsx @@ -21,6 +21,7 @@ * labledButtons - whether or not to use labeled buttons or icons only */ import React from 'react'; +import PropTypes from 'prop-types'; import i18n from 'nfvo-utils/i18n/i18n.js'; import Button from 'sdc-ui/lib/react/Button.js'; import SVGIcon from 'sdc-ui/lib/react/SVGIcon.js'; @@ -28,10 +29,10 @@ import SVGIcon from 'sdc-ui/lib/react/SVGIcon.js'; class ValidationButtons extends React.Component { static propTypes = { - labledButtons: React.PropTypes.bool.isRequired, - isReadOnlyMode: React.PropTypes.bool, - submitButtonText: React.PropTypes.string, - cancelButtonText: React.PropTypes.string + labledButtons: PropTypes.bool.isRequired, + isReadOnlyMode: PropTypes.bool, + submitButtonText: PropTypes.string, + cancelButtonText: PropTypes.string }; state = { @@ -45,10 +46,10 @@ class ValidationButtons extends React.Component { <div className='validation-buttons'> {!this.props.isReadOnlyMode ? <div> - <Button type='submit' disabled={!this.state.isValid}>{submitBtn}</Button> - <Button btnType='outline' type='reset'>{closeBtn}</Button> + <Button type='submit' data-test-id='form-submit-button' disabled={!this.state.isValid}>{submitBtn}</Button> + <Button btnType='outline' type='reset' data-test-id='form-close-button'>{closeBtn}</Button> </div> - : <Button btnType='outline' type='reset'>{i18n('Close')}</Button> + : <Button btnType='outline' type='reset' data-test-id='form-close-button'>{i18n('Close')}</Button> } </div> ); diff --git a/openecomp-ui/src/nfvo-components/listEditor/ListEditorItemView.jsx b/openecomp-ui/src/nfvo-components/listEditor/ListEditorItemView.jsx index bed304b756..60c559a3d1 100644 --- a/openecomp-ui/src/nfvo-components/listEditor/ListEditorItemView.jsx +++ b/openecomp-ui/src/nfvo-components/listEditor/ListEditorItemView.jsx @@ -14,6 +14,7 @@ * permissions and limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import classnames from 'classnames'; import i18n from 'nfvo-utils/i18n/i18n.js'; import SVGIcon from 'sdc-ui/lib/react/SVGIcon.js'; @@ -22,11 +23,11 @@ import {actionTypes as modalActionTypes} from 'nfvo-components/modal/GlobalModal class ListEditorItem extends React.Component { static propTypes = { - onSelect: React.PropTypes.oneOfType([React.PropTypes.func, React.PropTypes.bool]), - onDelete: React.PropTypes.oneOfType([React.PropTypes.func, React.PropTypes.bool]), - onEdit: React.PropTypes.oneOfType([React.PropTypes.func, React.PropTypes.bool]), - children: React.PropTypes.node, - isReadOnlyMode: React.PropTypes.bool + onSelect: PropTypes.oneOfType([PropTypes.func, PropTypes.bool]), + onDelete: PropTypes.oneOfType([PropTypes.func, PropTypes.bool]), + onEdit: PropTypes.oneOfType([PropTypes.func, PropTypes.bool]), + children: PropTypes.node, + isReadOnlyMode: PropTypes.bool }; render() { diff --git a/openecomp-ui/src/nfvo-components/listEditor/ListEditorView.jsx b/openecomp-ui/src/nfvo-components/listEditor/ListEditorView.jsx index df7d69b4ff..16823b7dc5 100644 --- a/openecomp-ui/src/nfvo-components/listEditor/ListEditorView.jsx +++ b/openecomp-ui/src/nfvo-components/listEditor/ListEditorView.jsx @@ -14,6 +14,7 @@ * permissions and limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import Button from 'sdc-ui/lib/react/Button.js'; import classnames from 'classnames'; import ExpandableInput from 'nfvo-components/input/ExpandableInput.jsx'; @@ -60,15 +61,15 @@ class ListEditorView extends React.Component { }; static propTypes = { - title: React.PropTypes.string, - plusButtonTitle: React.PropTypes.string, - children: React.PropTypes.node, - filterValue: React.PropTypes.string, - onFilter: React.PropTypes.func, - className: React.PropTypes.string, - isReadOnlyMode: React.PropTypes.bool, - placeholder: React.PropTypes.string, - twoColumns: React.PropTypes.bool + title: PropTypes.string, + plusButtonTitle: PropTypes.string, + children: PropTypes.node, + filterValue: PropTypes.string, + onFilter: PropTypes.func, + className: PropTypes.string, + isReadOnlyMode: PropTypes.bool, + placeholder: PropTypes.string, + twoColumns: PropTypes.bool }; render() { diff --git a/openecomp-ui/src/nfvo-components/listEditor/listEditor.stories.js b/openecomp-ui/src/nfvo-components/listEditor/listEditor.stories.js index 276b05e270..81125c84ba 100644 --- a/openecomp-ui/src/nfvo-components/listEditor/listEditor.stories.js +++ b/openecomp-ui/src/nfvo-components/listEditor/listEditor.stories.js @@ -2,7 +2,7 @@ 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 ListEditorItemField from './ListEditorItemViewField.jsx'; import {text, number} from '@kadira/storybook-addon-knobs'; import {withKnobs} from '@kadira/storybook-addon-knobs'; @@ -13,12 +13,12 @@ function makeChildren({onEdit = false, onDelete = false} = {}) { key={index} onEdit={onEdit ? onEdit : undefined} onDelete={onDelete ? onDelete : undefined}> - <ListEditorItemViewField> + <ListEditorItemField> <div>{text('field 1', 'Lorum Ipsum')}</div> - </ListEditorItemViewField> - <ListEditorItemViewField> + </ListEditorItemField> + <ListEditorItemField> <div>{text('field 2', 'Lorum Ipsum')}</div> - </ListEditorItemViewField> + </ListEditorItemField> </ListEditorItemView>) ) ); diff --git a/openecomp-ui/src/nfvo-components/loader/Loader.jsx b/openecomp-ui/src/nfvo-components/loader/Loader.jsx index 675b04c8ea..cbfed1b214 100644 --- a/openecomp-ui/src/nfvo-components/loader/Loader.jsx +++ b/openecomp-ui/src/nfvo-components/loader/Loader.jsx @@ -14,6 +14,7 @@ * permissions and limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import {connect} from 'react-redux'; const mapStateToProps = ({loader}) => { @@ -25,7 +26,7 @@ const mapStateToProps = ({loader}) => { class Loader extends React.Component { static propTypes = { - isLoading: React.PropTypes.bool.isRequired + isLoading: PropTypes.bool.isRequired }; static defaultProps = { diff --git a/openecomp-ui/src/nfvo-components/modal/GlobalModal.js b/openecomp-ui/src/nfvo-components/modal/GlobalModal.js index 4e7a1a16a4..a47c42a1fb 100644 --- a/openecomp-ui/src/nfvo-components/modal/GlobalModal.js +++ b/openecomp-ui/src/nfvo-components/modal/GlobalModal.js @@ -15,6 +15,7 @@ */ import React from 'react'; +import PropTypes from 'prop-types'; import {connect} from 'react-redux'; import Modal from 'nfvo-components/modal/Modal.jsx'; @@ -25,7 +26,7 @@ import {actionTypes, typeEnum} from './GlobalModalConstants.js'; const typeClass = { - 'default': 'default', + 'default': 'primary', error: 'negative', warning: 'warning', success: 'positive' @@ -47,11 +48,11 @@ const ModalFooter = ({type, onConfirmed, onDeclined, onClose, confirmationButton return ( <Modal.Footer> <div className='sdc-modal-footer'> - {onConfirmed && <Button color={typeClass[type]} onClick={() => { + {onConfirmed && <Button data-test-id='sdc-modal-confirm-button' color={typeClass[type]} onClick={() => { onConfirmed(); onClose(); }}>{confirmationButtonText}</Button>} - <Button {...myPropsForNoConfirmed} color={typeClass[type]} onClick={onDeclined ? () => { + <Button {...myPropsForNoConfirmed} data-test-id='sdc-modal-cancel-button' btnType='outline' color={typeClass[type]} onClick={onDeclined ? () => { onDeclined(); onClose();} : () => onClose()}> {cancelButtonText} @@ -85,15 +86,15 @@ export const mapActionToProps = (dispatch) => { 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 + show: PropTypes.bool, + type: PropTypes.oneOf(['default', 'error', 'warning', 'success']), + title: PropTypes.string, + modalComponentProps: PropTypes.object, + modalComponentName: PropTypes.string, + onConfirmed: PropTypes.func, + onDeclined: PropTypes.func, + confirmationButtonText: PropTypes.string, + cancelButtonText: PropTypes.string }; static defaultProps = { @@ -115,7 +116,7 @@ export class GlobalModalView extends React.Component { {ComponentToRender ? <ComponentToRender {...modalComponentProps}/> : msg && typeof msg === 'string' ? - <div> {msg.split('\n').map(txt => <span> {txt} <br/> </span>)} </div> : + <div> {msg.split('\n').map((txt, i) => <span key={i}> {txt} <br/> </span>)} </div> : msg } </Modal.Body> diff --git a/openecomp-ui/src/sdc-app/onboarding/onboard/CatalogTile.jsx b/openecomp-ui/src/nfvo-components/overlay/Overlay.jsx index c7720a9d0e..054c1e2852 100644 --- a/openecomp-ui/src/sdc-app/onboarding/onboard/CatalogTile.jsx +++ b/openecomp-ui/src/nfvo-components/overlay/Overlay.jsx @@ -13,19 +13,28 @@ * or implied. See the License for the specific language governing * permissions and limitations under the License. */ + import React from 'react'; +import enhanceWithClickOutside from 'react-click-outside'; -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> - ); -}; +class Overlay extends React.Component { + + handleClickOutside() { + if (this.props.onClose) { + this.props.onClose(); + } + } + + render() { + return ( + <div className='onboarding-overlay'> + <div className='arrow-up'></div> + <div className='arrow-border'/> + {this.props.children} + </div> + ); + } -CatalogTile.PropTypes = { - catalogItemTypeClass: React.PropTypes.string, - onSelect: React.PropTypes.func }; -export default CatalogTile; +export default enhanceWithClickOutside(Overlay); diff --git a/openecomp-ui/src/nfvo-components/panel/NavigationSideBar.jsx b/openecomp-ui/src/nfvo-components/panel/NavigationSideBar.jsx index fb3b71f0c8..02552fcb7e 100644 --- a/openecomp-ui/src/nfvo-components/panel/NavigationSideBar.jsx +++ b/openecomp-ui/src/nfvo-components/panel/NavigationSideBar.jsx @@ -14,15 +14,16 @@ * permissions and limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; 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, - onToggle: React.PropTypes.func, - groups: React.PropTypes.array + activeItemId: PropTypes.string.isRequired, + onSelect: PropTypes.func, + onToggle: PropTypes.func, + groups: PropTypes.array }; constructor(props) { @@ -61,9 +62,9 @@ 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 + activeItemId: PropTypes.string.isRequired, + onNavigationItemClick: PropTypes.func, + menu: PropTypes.array }; render() { @@ -80,6 +81,9 @@ function NavigationMenuHeader(props) { return <div className='group-name' data-test-id='navbar-group-name'>{props.title}</div>; } +function getItemDataTestId(itemId) { + return itemId.split('|')[0]; +} function NavigationMenuItems(props) { const {items, activeItemId, onNavigationItemClick} = props; return ( @@ -97,7 +101,7 @@ function NavigationMenuItem(props) { 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}> + {isGroup && <Collapse in={item.expanded} data-test-id={'navigation-group-' + getItemDataTestId(item.id)}> <div> {item.items.map(subItem => (<NavigationMenuItem key={'menuItem_' + subItem.id} item={subItem} onNavigationItemClick={onNavigationItemClick} activeItemId={activeItemId} />)) } </div> @@ -120,7 +124,7 @@ function NavigationLink(props) { 'hidden': item.hidden })} onClick={(event) => onClick(event, item)} - data-test-id={'navbar-group-item-' + item.id}> + data-test-id={'navbar-group-item-' + getItemDataTestId(item.id)}> {item.name} </div> ); diff --git a/openecomp-ui/src/nfvo-components/panel/versionController/VersionController.jsx b/openecomp-ui/src/nfvo-components/panel/versionController/VersionController.jsx index 922db05282..5273785f07 100644 --- a/openecomp-ui/src/nfvo-components/panel/versionController/VersionController.jsx +++ b/openecomp-ui/src/nfvo-components/panel/versionController/VersionController.jsx @@ -14,51 +14,66 @@ * permissions and limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import i18n from 'nfvo-utils/i18n/i18n.js'; -import {actionsEnum, statusEnum, statusBarTextMap } from './VersionControllerConstants.js'; -import SVGIcon from 'sdc-ui/lib/react/SVGIcon.js'; -import Tooltip from 'react-bootstrap/lib/Tooltip.js'; -import OverlayTrigger from 'react-bootstrap/lib/OverlayTrigger.js'; +import {actionsEnum} from './VersionControllerConstants.js'; +import ActionButtons from './components/ActionButtons.jsx'; +import NotificationsView from 'sdc-app/onboarding/userNotifications/NotificationsView.jsx'; class VersionController extends React.Component { static propTypes = { - version: React.PropTypes.object, - viewableVersions: React.PropTypes.array, - onVersionSwitching: React.PropTypes.func, - isCheckedOut: React.PropTypes.bool.isRequired, - status: React.PropTypes.string.isRequired, - callVCAction: React.PropTypes.func, - onSave: React.PropTypes.func, - onClose: React.PropTypes.func, - isFormDataValid: React.PropTypes.bool + version: PropTypes.object, + viewableVersions: PropTypes.array, + onVersionSwitching: PropTypes.func, + callVCAction: PropTypes.func, + onSave: PropTypes.func, + onClose: PropTypes.func, + isFormDataValid: PropTypes.bool, + onOpenCommentCommitModal: PropTypes.func, + isReadOnlyMode: PropTypes.bool + }; + + state = { + showPermissions: false, + showRevisions: false }; render() { - let {status, isCheckedOut, version = {}, viewableVersions = [], onVersionSwitching, callVCAction, onSave, isFormDataValid, onClose} = this.props; - let isCheckedIn = Boolean(status === statusEnum.CHECK_IN_STATUS); - let isLatestVersion = Boolean(version.id === viewableVersions[viewableVersions.length - 1].id); - if (!isLatestVersion) { - status = statusEnum.PREVIOUS_VERSION; - } + let {version = {}, viewableVersions = [], onVersionSwitching, onMoreVersionsClick, callVCAction, onSave, isReadOnlyMode, itemPermission, + isFormDataValid, onClose, onManagePermissions, permissions = {}, userInfo, usersList, itemName, onOpenCommentCommitModal, onOpenRevisionsModal, isManual} = this.props; return ( <div className='version-controller-bar'> <div className='vc-container'> <div className='version-status-container'> - <VersionSelector viewableVersions={viewableVersions} version={version} onVersionSwitching={onVersionSwitching} /> - <StatusBarUpdates status={status}/> + <VersionSelector + viewableVersions={viewableVersions} + version={version} + onVersionSwitching={onVersionSwitching} + onMoreVersionsClick={() => onMoreVersionsClick({itemName, users: usersList})}/> </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} + onRevert={callVCAction ? () => this.revert(callVCAction, version) : undefined} + onOpenRevisionsModal={onOpenRevisionsModal} onSave={onSave ? () => onSave() : undefined} - isLatestVersion={isLatestVersion} - isCheckedOut={isCheckedOut} - isCheckedIn={isCheckedIn} isFormDataValid={isFormDataValid} version={version}/> + permissions={permissions} + userInfo={userInfo} + onManagePermissions={onManagePermissions} + showPermissions={this.state.showPermissions} + onClosePermissions={()=>this.setState({showPermissions: false})} + onClickPermissions={() => this.onClickPermissions()} + onSync={callVCAction ? () => this.sync(callVCAction, version) : undefined} + onOpenCommentCommitModal={onOpenCommentCommitModal} + onCommit={callVCAction ? (comment) => this.commit(callVCAction, version, comment) : undefined} + isFormDataValid={isFormDataValid} + itemPermissions={itemPermission} + isReadOnlyMode={isReadOnlyMode} + isManual={isManual} /> + <div className='vc-separator'></div> + <NotificationsView /> {onClose && <div className='vc-nav-item-close' onClick={() => onClose()} data-test-id='vc-cancel-btn'> X</div>} </div> </div> @@ -66,116 +81,57 @@ class VersionController extends React.Component { ); } + onClickPermissions() { + let {onOpenPermissions, usersList} = this.props; + let {showPermissions} = this.state; + let promise = showPermissions ? Promise.resolve() : onOpenPermissions({users: usersList}); + promise.then(() => this.setState({showPermissions: !showPermissions})); + } + + submit(callVCAction, version) { const action = actionsEnum.SUBMIT; callVCAction(action, version); } - revertCheckout(callVCAction, version) { - const action = actionsEnum.UNDO_CHECK_OUT; + revert(callVCAction, version) { + const action = actionsEnum.REVERT; callVCAction(action, version); } - checkinCheckoutVersion(callVCAction, version) { - if (this.props.isCheckedOut) { - this.checkin(callVCAction, version); - } - else { - this.checkout(callVCAction, version); - } - } - checkin(callVCAction, version) { - const action = actionsEnum.CHECK_IN; - if (this.props.onSave) { - this.props.onSave().then(()=>{ - callVCAction(action, version); - }); - }else{ - callVCAction(action, version); - } - - } - checkout(callVCAction, version) { - const action = actionsEnum.CHECK_OUT; + sync(callVCAction, version) { + const action = actionsEnum.SYNC; callVCAction(action, version); } -} -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 ? - ['versionControllerLockOpen', i18n('Check In')] : - ['versionControllerLockClosed', 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='versionControllerSubmit' tooltipText={i18n('Submit')}/> - <VCButton dataTestId='vc-revert-btn' onClick={onRevert} isDisabled={!isCheckedOut || version.label === '0.1' || !isLatestVersion} - name='versionControllerRevert' tooltipText={i18n('Revert')}/> - </div> - } - {onSave && - <VCButton dataTestId='vc-save-btn' onClick={() => onSave()} isDisabled={!isCheckedOut || !isFormDataValid || !isLatestVersion} - name='versionControllerSave' tooltipText={i18n('Save')}/> - } - </div> - ); + commit(callVCAction, version, comment) { + const action = actionsEnum.COMMIT; + callVCAction(action, version, comment); } -} - -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' : ''; + permissions() { - return ( - <OverlayTrigger placement='top' overlay={<Tooltip id='vc-tooltip'>{tooltipText}</Tooltip>}> - <div disabled={disabled} className='action-buttons-svg'> - <SVGIcon data-test-id={dataTestId} disabled={isDisabled} onClick={onClickAction ? onClickAction : undefined} name={name}/> - </div> - </OverlayTrigger> - ); + } } function VersionSelector(props) { - let {version = {}, viewableVersions = [], onVersionSwitching} = props; + let {version = {}, onMoreVersionsClick, 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}> + onChange={ev => onVersionSwitching && onVersionSwitching(viewableVersions.find(version => version.id === ev.target.value))} + value={version.id} + data-test-id='vc-versions-select-box'> {viewableVersions && viewableVersions.map(viewVersion => { return ( - <option key={viewVersion.id} value={viewVersion.id} data-test-id='vc-version-option'>{`V ${viewVersion.label}`}</option> + <option key={viewVersion.id} value={viewVersion.id} data-test-id='vc-version-option'>{`V ${viewVersion.name} ${viewVersion.status}`}</option> ); }) } {!includedVersions.length && - <option key={version.id} value={version.id}>{`V ${version.label}`}</option>} + <option key={version.id} value={version.id} data-test-id='vc-selected-version-option'>{`V ${version.name} ${version.status}`}</option>} </select> + <span onClick={onMoreVersionsClick} className='version-selector-more-versions' data-test-id='vc-versions-page-link'>{i18n('Versions Page')}</span> </div>); } diff --git a/openecomp-ui/src/nfvo-components/panel/versionController/VersionControllerConstants.js b/openecomp-ui/src/nfvo-components/panel/versionController/VersionControllerConstants.js index c2548e4fb4..ddb428a1e9 100644 --- a/openecomp-ui/src/nfvo-components/panel/versionController/VersionControllerConstants.js +++ b/openecomp-ui/src/nfvo-components/panel/versionController/VersionControllerConstants.js @@ -16,26 +16,9 @@ import keyMirror from 'nfvo-utils/KeyMirror.js'; export const actionsEnum = keyMirror({ - CHECK_IN: 'Checkin', - CHECK_OUT: 'Checkout', - UNDO_CHECK_OUT: 'Undo_Checkout', + REVERT: 'Revert', + SYNC: 'Sync', SUBMIT: 'Submit', + COMMIT: 'Commit', CREATE_PACKAGE: 'Create_Package' }); - -export const statusEnum = keyMirror({ - CHECK_OUT_STATUS: 'Locked', - CHECK_IN_STATUS: 'Available', - SUBMIT_STATUS: 'Final', - LOCK_STATUS: 'LockedByUser', - PREVIOUS_VERSION: 'READ ONLY' -}); - -export const statusBarTextMap = keyMirror({ - 'Locked': 'Checked Out', - 'LockedByUser': 'Locked', - '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 deleted file mode 100644 index e8c12abec3..0000000000 --- a/openecomp-ui/src/nfvo-components/panel/versionController/VersionControllerUtils.js +++ /dev/null @@ -1,52 +0,0 @@ -/*! - * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ -import Configuration from 'sdc-app/config/Configuration.js'; -import {statusEnum} from './VersionControllerConstants.js'; - - -const VersionControllerUtils = { - - getCheckOutStatusKindByUserID(status, 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: returnStatus, - isCheckedOut - }; - }, - - isCheckedOutByCurrentUser(resource) { - 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.id !== latestVersion.id || !VersionControllerUtils.isCheckedOutByCurrentUser(resource); - } -}; - -export default VersionControllerUtils; diff --git a/openecomp-ui/src/nfvo-components/panel/versionController/components/ActionButtons.jsx b/openecomp-ui/src/nfvo-components/panel/versionController/components/ActionButtons.jsx new file mode 100644 index 0000000000..4346a0e5dc --- /dev/null +++ b/openecomp-ui/src/nfvo-components/panel/versionController/components/ActionButtons.jsx @@ -0,0 +1,109 @@ +/*! + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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 PropTypes from 'prop-types'; +import enhanceWithClickOutside from 'react-click-outside'; +import i18n from 'nfvo-utils/i18n/i18n.js'; +import SVGIcon from 'sdc-ui/lib/react/SVGIcon.js'; +import Overlay from 'nfvo-components/overlay/Overlay.jsx'; +import Permissions from './Permissions.jsx'; + +class ClickOutsideWrapper extends Component { + handleClickOutside() { + this.props.onClose(); + } + render() { + return <div>{this.props.children}</div>; + } +} + +const EnhancedClickOutsideWrapper = enhanceWithClickOutside(ClickOutsideWrapper); + +const VCButton = ({name, tooltipText, disabled, onClick, dataTestId}) => { + let onClickAction = disabled ? ()=>{} : onClick; + return ( + <div className={`action-button-wrapper ${disabled ? 'disabled' : 'clickable'}`} onClick={onClickAction}> + <div className='action-buttons-svg'> + <SVGIcon label={tooltipText} labelPosition='bottom' labelClassName='action-button-label' + data-test-id={dataTestId} name={name} disabled={disabled}/> + </div> + </div> + ); +}; + +const Separator = () => (<div className='vc-separator'></div>); + +const SubmitButton = ({onClick, disabled}) => ( + <div onClick={()=>onClick()} data-test-id='vc-submit-btn' className={`vc-submit-button ${disabled ? 'disabled' : ''}`}> + <SVGIcon name='check' iconClassName='vc-v-submit' disabled={disabled} /> + {i18n('Submit')} + </div> +); + + +const ActionButtons = ({isReadOnlyMode, onSubmit, onRevert, onSave, isFormDataValid, onClickPermissions, onSync, onCommit, + onOpenCommentCommitModal, showPermissions, onClosePermissions, permissions, onManagePermissions, userInfo, onOpenRevisionsModal, isManual, + itemPermissions: {isCertified, isCollaborator, isDirty, isOutOfSync, isUpToDate}}) => ( + <div className='action-buttons'> + <EnhancedClickOutsideWrapper onClose={onClosePermissions}> + <VCButton disabled={isManual} dataTestId='vc-permission-btn' onClick={onClickPermissions} + name='version-controller-permissions' tooltipText={i18n('Permissons')} /> + {showPermissions && + <Overlay> + <Permissions userInfo={userInfo} onManagePermissions={onManagePermissions} permissions={permissions} onClosePermissions={onClosePermissions}/> + </Overlay> + } + </EnhancedClickOutsideWrapper> + {isCollaborator && <div className='collaborator-action-buttons'> + <Separator /> + {onSave && <div className='vc-save-section'> + <VCButton dataTestId='vc-save-btn' onClick={() => onSave()} + name='version-controller-save' tooltipText={i18n('Save')} disabled={isReadOnlyMode || !isFormDataValid} /> + <Separator /> + </div> + } + <VCButton dataTestId='vc-sync-btn' onClick={onSync} + name='version-controller-sync' tooltipText={i18n('Sync')} disabled={!isCollaborator || isUpToDate || isCertified} /> + <VCButton dataTestId='vc-commit-btn' onClick={() => onOpenCommentCommitModal({onCommit, title: i18n('Commit')})} + name='version-controller-commit' tooltipText={i18n('Share')} disabled={isReadOnlyMode || !isDirty || isOutOfSync} /> + {onRevert && + <VCButton dataTestId='vc-revert-btn' onClick={onOpenRevisionsModal} + name='version-controller-revert' tooltipText={i18n('Revert')} disabled={isReadOnlyMode || isOutOfSync} /> + } + {onSubmit && (permissions.owner && permissions.owner.userId === userInfo.userId) && + <div className='vc-submit-section'> + <Separator /> + <SubmitButton onClick={onSubmit} + disabled={isReadOnlyMode || isOutOfSync || !isUpToDate || isCertified} /> + </div> + } + </div>} + </div> +); + +ActionButtons.propTypes = { + version: PropTypes.object, + onSubmit: PropTypes.func, + onRevert: PropTypes.func, + onSave: PropTypes.func, + isLatestVersion: PropTypes.bool, + isCheckedIn: PropTypes.bool, + isCheckedOut: PropTypes.bool, + isFormDataValid: PropTypes.bool, + isReadOnlyMode: PropTypes.bool +}; + +export default ActionButtons; diff --git a/openecomp-ui/src/nfvo-components/panel/versionController/components/CommitCommentModal.jsx b/openecomp-ui/src/nfvo-components/panel/versionController/components/CommitCommentModal.jsx new file mode 100644 index 0000000000..600eaeefaa --- /dev/null +++ b/openecomp-ui/src/nfvo-components/panel/versionController/components/CommitCommentModal.jsx @@ -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 React from 'react'; +import {connect} from 'react-redux'; +import i18n from 'nfvo-utils/i18n/i18n.js'; +import Form from 'nfvo-components/input/validation/Form.jsx'; +import Input from 'nfvo-components/input/validation/Input.jsx'; +import {actionTypes as modalActionTypes} from 'nfvo-components/modal/GlobalModalConstants.js'; +import keyMirror from 'nfvo-utils/KeyMirror.js'; + +export const CommitModalType = keyMirror({ + COMMIT: null, + COMMIT_SUBMIT: null + +}); + +export const mapActionToProps = (dispatch) => { + return { + onClose: () => dispatch({ + type: modalActionTypes.GLOBAL_MODAL_CLOSE + }) + }; +}; + +class CommitCommentModal extends React.Component { + + state = { + comment: '' + }; + + render() { + const {onCommit, onClose, type} = this.props; + const [commitButtonText, descriptionText] = type === CommitModalType.COMMIT ? + [i18n('Commit'), i18n('You are about to commit your version')] : + [i18n('Commit & Submit'), i18n('You must commit your changes before the submit')]; + + return ( + <Form + ref='validationForm' + hasButtons={true} + onSubmit={ () => {onCommit(this.state.comment); onClose();} } + onReset={onClose} + submitButtonText={commitButtonText} + labledButtons={true} + isValid={true} + className='comment-commit-form'> + <div className='commit-modal-text'>{descriptionText}</div> + <Input + data-test-id='commit-comment-text' + onChange={comment => this.setState({comment: comment})} + label={i18n('Enter Commit Comment:')} + value={this.state.comment} + type='textarea'/> + </Form> + ); + } +} + +export default connect(null, mapActionToProps)(CommitCommentModal); diff --git a/openecomp-ui/src/nfvo-components/panel/versionController/components/Permissions.jsx b/openecomp-ui/src/nfvo-components/panel/versionController/components/Permissions.jsx new file mode 100644 index 0000000000..952bd4fb58 --- /dev/null +++ b/openecomp-ui/src/nfvo-components/panel/versionController/components/Permissions.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 SVGIcon from 'sdc-ui/lib/react/SVGIcon.js'; + +const Contributor = ({name, role, id, userInfo}) => { + + const selected = id === userInfo.userId ? 'selected' : ''; + + return( + <div className='contributor'> + <div className='contributor-content'> + <div className={`contributor-icon-circle ${selected}`}> + <div className={`contributer-icon ${selected}`}> + <SVGIcon name='user'/> + </div> + </div> + <div className='contributer-info'> + <div className='contributer-name'>{name}</div> + <div className='contributer-role'><p>{role}</p></div> + </div> + </div> + </div> + ); +}; + +const Permissions = ({permissions: {owner, contributors}, onManagePermissions, userInfo, onClosePermissions}) => { + + return ( + <div className='permissions-overlay'> + <div className='permissions-overlay-header'> + <h4 className='permissions-overlay-header-title'>{i18n('PERMISSIONS')}</h4> + </div> + <div className='permissions-overlay-content'> + <Contributor userInfo={userInfo} id={owner.userId} key={owner.fullName} name={owner.fullName} role={owner.role}/> + {contributors.map(item => item.userId !== owner.userId && <Contributor userInfo={userInfo} id={item.userId} key={item.fullName} name={item.fullName} role={item.role}/>)} + </div> + <div className='permissions-overlay-footer'> + { + owner.userId === userInfo.userId && + <div onClick={() => { onClosePermissions(); onManagePermissions(); }} className='manage-permissions-btn'> + {i18n('Manage Permissions')} + </div> + } + </div> + </div> + ); +}; + +export default Permissions; diff --git a/openecomp-ui/src/nfvo-components/progressBar/ProgressBar.jsx b/openecomp-ui/src/nfvo-components/progressBar/ProgressBar.jsx index 40720c39f4..ca5cb3d765 100644 --- a/openecomp-ui/src/nfvo-components/progressBar/ProgressBar.jsx +++ b/openecomp-ui/src/nfvo-components/progressBar/ProgressBar.jsx @@ -14,11 +14,12 @@ * permissions and limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; class ProgressBar extends React.Component { static propTypes = { - label: React.PropTypes.string, - now: React.PropTypes.string.isRequired + label: PropTypes.string, + now: PropTypes.string.isRequired } render() { let {label, now} = this.props; diff --git a/openecomp-ui/src/nfvo-components/table/SelectActionTableRow.jsx b/openecomp-ui/src/nfvo-components/table/SelectActionTableRow.jsx index a03f8441a4..260d39d31c 100644 --- a/openecomp-ui/src/nfvo-components/table/SelectActionTableRow.jsx +++ b/openecomp-ui/src/nfvo-components/table/SelectActionTableRow.jsx @@ -27,12 +27,12 @@ function renderErrorOrCheck({hasError, overlayMsg}) { return <SVGIcon name='checkCircle' color='positive'/>; } -const SelectActionTableRow = ({children, onDelete, hasError, hasErrorIndication, overlayMsg, showDelete}) => ( +const SelectActionTableRow = ({children, actionIcon, onAction, showAction, hasError, hasErrorIndication, overlayMsg}) => ( <div className='select-action-table-row-wrapper'> <div className={`select-action-table-row ${hasError ? 'has-error' : ''}`}> {children} </div> - {onDelete && <SVGIcon color='secondary' name='trashO' data-test-id='select-action-table-delete' onClick={onDelete} iconClassName={(showDelete) ? '' : 'hideDelete'}/>} + {onAction && <SVGIcon color='secondary' name={actionIcon} data-test-id={`select-action-table-${actionIcon}`} onClick={onAction} iconClassName={(showAction) ? '' : 'hideDelete'}/>} {hasErrorIndication && renderErrorOrCheck({hasError, overlayMsg})} </div> ); diff --git a/openecomp-ui/src/nfvo-components/tree/Tree.jsx b/openecomp-ui/src/nfvo-components/tree/Tree.jsx new file mode 100644 index 0000000000..682f3b6d50 --- /dev/null +++ b/openecomp-ui/src/nfvo-components/tree/Tree.jsx @@ -0,0 +1,181 @@ +import React, {Component} from 'react'; +import PropTypes from 'prop-types'; +import {select} from 'd3-selection'; +import {tree, stratify} from 'd3-hierarchy'; + + +function diagonal(d) { + + const offset = 50; + return 'M' + d.y + ',' + d.x + + 'C' + (d.parent.y + offset) + ',' + d.x + + ' ' + (d.parent.y + offset) + ',' + d.parent.x + + ' ' + d.parent.y + ',' + d.parent.x; +} + +const nodeRadius = 8; +const verticalSpaceBetweenNodes = 70; +const NARROW_HORIZONTAL_SPACES = 47; +const WIDE_HORIZONTAL_SPACES = 65; + +const stratifyFn = stratify().id(d => d.id).parentId(d => d.parent); + +class Tree extends Component { + + // state = { + // startingCoordinates: null, + // isDown: false + // } + + static propTypes = { + name: PropTypes.string, + width: PropTypes.number, + allowScaleWidth: PropTypes.bool, + nodes: PropTypes.arrayOf(PropTypes.shape({ + id: PropTypes.string, + name: PropTypes.string, + parent: PropTypes.string + })), + selectedNodeId: PropTypes.string, + onNodeClick: PropTypes.func, + onRenderedBeyondWidth: PropTypes.func + }; + + static defaultProps = { + width: 500, + allowScaleWidth : true, + name: 'default-name' + }; + + render() { + let {width, name, scrollable = false} = this.props; + return ( + <div + className={`tree-view ${name}-container ${scrollable ? 'scrollable' : ''}`}> + <svg width={width} className={name}></svg> + </div> + ); + } + + componentDidMount() { + this.renderTree(); + } + + // handleMouseMove(e) { + // if (!this.state.isDown) { + // return; + // } + // const container = select(`.tree-view.${this.props.name}-container`); + // let coordinates = this.getCoordinates(e); + // container.property('scrollLeft' , container.property('scrollLeft') + coordinates.x - this.state.startingCoordinates.x); + // container.property('scrollTop' , container.property('scrollTop') + coordinates.y - this.state.startingCoordinates.y); + // } + + // handleMouseDown(e) { + // let startingCoordinates = this.getCoordinates(e); + // this.setState({ + // startingCoordinates, + // isDown: true + // }); + // } + + // handleMouseUp() { + // this.setState({ + // startingCorrdinates: null, + // isDown: false + // }); + // } + + // getCoordinates(e) { + // var bounds = e.target.getBoundingClientRect(); + // var x = e.clientX - bounds.left; + // var y = e.clientY - bounds.top; + // return {x, y}; + // } + + componentDidUpdate(prevProps) { + if (this.props.nodes.length !== prevProps.nodes.length || + this.props.selectedNodeId !== prevProps.selectedNodeId) { + console.log('update'); + this.renderTree(); + } + } + + renderTree() { + let {width, nodes, name, allowScaleWidth, selectedNodeId, onRenderedBeyondWidth, toWiden} = this.props; + if (nodes.length > 0) { + + let horizontalSpaceBetweenLeaves = toWiden ? WIDE_HORIZONTAL_SPACES : NARROW_HORIZONTAL_SPACES; + const treeFn = tree().nodeSize([horizontalSpaceBetweenLeaves, verticalSpaceBetweenNodes]);//.size([width - 50, height - 50]) + let root = stratifyFn(nodes).sort((a, b) => a.data.name.localeCompare(b.data.name)); + let svgHeight = verticalSpaceBetweenNodes * root.height + nodeRadius * 6; + + treeFn(root); + + let nodesXValue = root.descendants().map(node => node.x); + let maxX = Math.max(...nodesXValue); + let minX = Math.min(...nodesXValue); + + let svgTempWidth = (maxX - minX) / 30 * (horizontalSpaceBetweenLeaves); + let svgWidth = svgTempWidth < width ? (width - 5) : svgTempWidth; + const svgEL = select(`svg.${name}`); + const container = select(`.tree-view.${name}-container`); + svgEL.html(''); + svgEL.attr('height', svgHeight); + let canvasWidth = width; + if (svgTempWidth > width) { + if (allowScaleWidth) { + canvasWidth = svgTempWidth; + } + // we seems to have a margin of 25px that we can still see with text + if (((svgTempWidth - 25) > width) && onRenderedBeyondWidth !== undefined) { + onRenderedBeyondWidth(); + } + }; + svgEL.attr('width', canvasWidth); + let rootGroup = svgEL.append('g').attr('transform', `translate(${svgWidth / 2 + nodeRadius},${nodeRadius * 4}) rotate(90)`); + + // handle link + rootGroup.selectAll('.link') + .data(root.descendants().slice(1)) + .enter().append('path') + .attr('class', 'link') + .attr('d', diagonal); + + let node = rootGroup.selectAll('.node') + .data(root.descendants()) + .enter().append('g') + .attr('class', node => `node ${node.children ? ' has-children' : ' leaf'} ${node.id === selectedNodeId ? 'selectedNode' : ''} ${this.props.onNodeClick ? 'clickable' : ''}`) + .attr('transform', node => 'translate(' + node.y + ',' + node.x + ')') + .on('click', node => this.onNodeClick(node)); + + node.append('circle').attr('r', nodeRadius).attr('class', 'outer-circle'); + node.append('circle').attr('r', nodeRadius - 3).attr('class', 'inner-circle'); + + node.append('text') + .attr('y', nodeRadius / 4 + 1) + .attr('x', - nodeRadius * 1.8) + .text(node => node.data.name) + .attr('transform', 'rotate(-90)'); + + let selectedNode = selectedNodeId ? root.descendants().find(node => node.id === selectedNodeId) : null; + if (selectedNode) { + + container.property('scrollLeft', (svgWidth / 4) + (svgWidth / 4 - 100) - (selectedNode.x / 30 * horizontalSpaceBetweenLeaves)); + container.property('scrollTop', (selectedNode.y / 100 * verticalSpaceBetweenNodes)); + + } else { + container.property('scrollLeft', (svgWidth / 4) + (svgWidth / 4 - 100)); + } + } + } + + onNodeClick(node) { + if (this.props.onNodeClick) { + this.props.onNodeClick(node.data); + } + } + +} + +export default Tree; diff --git a/openecomp-ui/src/nfvo-components/tree/Tree.stories.js b/openecomp-ui/src/nfvo-components/tree/Tree.stories.js new file mode 100644 index 0000000000..b29920b3ec --- /dev/null +++ b/openecomp-ui/src/nfvo-components/tree/Tree.stories.js @@ -0,0 +1,119 @@ +import React from 'react'; +import {storiesOf} from '@kadira/storybook'; +import {withKnobs} from '@kadira/storybook-addon-knobs'; +import Tree from './Tree.jsx'; +import SVGIcon from 'sdc-ui/lib/react/SVGIcon.js'; + +const stories = storiesOf('Version Tree', module); +stories.addDecorator(withKnobs); + +const response = { + listCount: 6, + results: [ + { + 'id': '123', + 'name': '1.0', + 'description': 'string', + 'baseId': '', + 'status': 'Draft', + 'creationTime': '2017-06-08T08:55:37.831Z', + 'modificationTime': '2017-06-08T08:55:37.831Z' + }, + { + 'id': '1234', + 'name': '1.1', + 'description': 'string', + 'baseId': '123', + 'status': 'Draft', + 'creationTime': '2017-06-08T08:55:37.831Z', + 'modificationTime': '2017-06-08T08:55:37.831Z' + }, + { + 'id': '12345', + 'name': '2.0', + 'description': 'string', + 'baseId': '123', + 'status': 'Draft', + 'creationTime': '2017-06-08T08:55:37.831Z', + 'modificationTime': '2017-06-08T08:55:37.831Z' + }, + { + 'id': '123456', + 'name': '3.0', + 'description': 'string', + 'baseId': '12345', + 'status': 'Draft', + 'creationTime': '2017-06-08T08:55:37.831Z', + 'modificationTime': '2017-06-08T08:55:37.831Z' + }, + { + 'id': '1234567', + 'name': '1.2', + 'description': 'string', + 'baseId': '1234', + 'status': 'Draft', + 'creationTime': '2017-06-08T08:55:37.831Z', + 'modificationTime': '2017-06-08T08:55:37.831Z' + }, + { + 'id': '12345678', + 'name': '2.1', + 'description': 'string', + 'baseId': '12345', + 'status': 'Draft', + 'creationTime': '2017-06-08T08:55:37.831Z', + 'modificationTime': '2017-06-08T08:55:37.831Z' + }, + { + 'id': '123456789', + 'name': '4.0', + 'description': 'string', + 'baseId': '123456', + 'status': 'Draft', + 'creationTime': '2017-06-08T08:55:37.831Z', + 'modificationTime': '2017-06-08T08:55:37.831Z' + }, + { + 'id': '12345678910', + 'name': '3.1', + 'description': 'string', + 'baseId': '123456', + 'status': 'Draft', + 'creationTime': '2017-06-08T08:55:37.831Z', + 'modificationTime': '2017-06-08T08:55:37.831Z' + } + ] +}; +const divStyle = { width: '200px', borderStyle: 'solid', borderColor: 'black', border: '1px solid black'}; +const tree = response.results.map(item => ({id: item.id, name: item.name, parent: item.baseId})); +const nodeClickHandler = function (node) { + window.alert(node.name); +}; +stories.add('Classic Version Tree', () => ( + <div> + <Tree nodes={tree} onNodeClick={nodeClickHandler} selectedNodeId={'1234'}/> + </div> +)).add('Single Version Tree', () => ( + <div> + <Tree nodes={[tree[0]]} onNodeClick={nodeClickHandler}/> + </div> +)).add('Single Path Version Tree', () => ( + <div> + <Tree nodes={[tree[0], tree[1]]} onNodeClick={nodeClickHandler}/> + </div> +)).add('Empty Tree', () => ( + <div> + <Tree nodes={[]}/> + </div> +)).add('Add Tree in Version Page Frame', () => ( + <div style={divStyle}> + Tree wider than frame<br/><br/><br/> + <Tree + name={'versions-tree'} + width={200} + nodes={tree} + onRenderedBeyondWidth={() => {console.log('rendered beyond width')}} + allowScaleWidth={false} + onNodeClick={nodeClickHandler}/> + </div> +)); diff --git a/openecomp-ui/src/nfvo-utils/Validator.js b/openecomp-ui/src/nfvo-utils/Validator.js index 3f6a00e289..0cb1943d66 100644 --- a/openecomp-ui/src/nfvo-utils/Validator.js +++ b/openecomp-ui/src/nfvo-utils/Validator.js @@ -20,8 +20,8 @@ import i18n from 'nfvo-utils/i18n/i18n.js'; class Validator { static get globalValidationFunctions() { return { - required: value => { - return typeof value === 'string' ? value.replace(/\s+/g, '') !== '' : value !== ''; + required: value => { + return typeof value === 'string' ? value.replace(/\s+/g, '') !== '' : value !== ''; }, requiredChooseOption: value => value !== '', maxLength: (value, length) => ValidatorJS.isLength(value, {max: length}), @@ -77,13 +77,13 @@ class Validator { length: value.length, maxLength }), - minLength: (value, minLength) => i18n(`Field value should contain at least ${minLength} characters.`), - pattern: (value, pattern) => i18n(`Field value should match the pattern: ${pattern}.`), + minLength: (value, minLength) => i18n('Field value should contain at least {minLength} characters.', {minLength: minLength}), + pattern: (value, pattern) => i18n('Field value should match the pattern: {pattern}.', {pattern: pattern}), numeric: () => i18n('Field value should contain numbers only.'), - maximum: (value, maxValue) => i18n(`Field value should be less or equal to: ${maxValue}.`), - minimum: (value, minValue) => i18n(`Field value should be at least: ${minValue.toString()}.`), - maximumExclusive: (value, maxValue) => i18n(`Field value should be less than: ${maxValue}.`), - minimumExclusive: (value, minValue) => i18n(`Field value should be more than: ${minValue.toString()}.`), + maximum: (value, maxValue) => i18n('Field value should be less or equal to: {maxValue}.', {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: 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.'), diff --git a/openecomp-ui/src/nfvo-utils/WebSocketUtil.js b/openecomp-ui/src/nfvo-utils/WebSocketUtil.js new file mode 100644 index 0000000000..c9dd10f1af --- /dev/null +++ b/openecomp-ui/src/nfvo-utils/WebSocketUtil.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 store from 'sdc-app/AppStore.js'; +import Configuration from 'sdc-app/config/Configuration.js'; +import {actionTypes} from 'sdc-app/onboarding/userNotifications/UserNotificationsConstants.js'; + + +export const websocketUrl = 'ws://' + window.location.hostname + ':' + Configuration.get('websocketPort') + + '/' + Configuration.get('websocketPath'); + +/*** + * Websocket is treated like a singleton. only need one for the application. + */ +var websocket; + + +export default { + + open(url, {lastScanned}) { + if (websocket === undefined || websocket.readyState === websocket.CLOSED) { + websocket = new WebSocket(`${url}?LAST_DELIVERED_EVENT_ID=${lastScanned}`); + websocket.onmessage = event => store.dispatch({ + type: actionTypes.NOTIFICATION, + data: JSON.parse(event.data) + }); + websocket.onclose = event => { + if(event.code && event.code === 1001) { // - Idle Timeout + const {lastScanned} = store.getState().notifications; + console.log('Reconnecting to Websocket'); + this.open(websocketUrl, {lastScanned}); + } + }; + websocket.onerror = event => console.log(event); + } + }, + + close() { + if (websocket !== undefined) { + websocket.close(); + } + } +}; diff --git a/openecomp-ui/src/nfvo-utils/getValue.js b/openecomp-ui/src/nfvo-utils/getValue.js index 101655bf31..5ab0c76d73 100644 --- a/openecomp-ui/src/nfvo-utils/getValue.js +++ b/openecomp-ui/src/nfvo-utils/getValue.js @@ -25,8 +25,14 @@ function getValueFromVariable(variable) { return variable ? variable : undefined; } +function getArrayData(variable) { + return variable.length ? variable : undefined; +} + let getValue = element => { - return typeof element === 'object' ? getValueFromObject(element) : getValueFromVariable(element); + return typeof element === 'object' ? + element instanceof Array ? getArrayData(element) : getValueFromObject(element) : + getValueFromVariable(element); }; export function getStrValue(choiceObject) { diff --git a/openecomp-ui/src/nfvo-utils/i18n/en.json b/openecomp-ui/src/nfvo-utils/i18n/en.json index 8ed638352c..9cfaf6a569 100644 --- a/openecomp-ui/src/nfvo-utils/i18n/en.json +++ b/openecomp-ui/src/nfvo-utils/i18n/en.json @@ -29,6 +29,8 @@ "OK": "OK", "Cancel": "Cancel", "Error": "Error", + "Share": "Share", + "Commit": "Commit", "This item is checkedin/submitted, Click Check Out to continue": "This item is checkedin/submitted, Click Check Out to continue", "Name": "Name", "Description": "Description", @@ -170,6 +172,7 @@ "Licenses": "Licenses", "Licensing Version": "Licensing Version", "License Agreement": "License Agreement", + "Manage Permissions": "Manage Permissions", "Select...": "Select...", "Availability": "Availability", "Use Availability Zones for High Availability": "Use Availability Zones for High Availability", @@ -326,5 +329,262 @@ "Persistent Storage/Volume Size (GB)": "Persistent Storage/Volume Size (GB)", "I/O Operations (per second)": "I/O Operations (per second)", "CPU Oversubscription Ratio": "CPU Oversubscription Ratio", - "Memory - RAM": "Memory - RAM" + "Memory - RAM": "Memory - RAM", + "Commit error": "Commit error", + "Item version was certified by Owner": "Item version was certified by Owner", + + "VendorSoftwareProduct": "VSP", + "VendorSoftwareProduct/category": "Category", + "VendorSoftwareProduct/description": "Description", + "VendorSoftwareProduct/licensingData" : "Licenses", + "VendorSoftwareProduct/licensingData/featureGroups" : "Feature Groups", + "VendorSoftwareProduct/licensingData/licenseAgreement" : "License Agreement", + "VendorSoftwareProduct/licensingVersion": "Licensing Version", + "VendorSoftwareProduct/name": "Name", + "VendorSoftwareProduct/isOldVersion": "Is Old Version", + "VendorSoftwareProduct/onboardingMethod": "Onboarding Method", + "VendorSoftwareProduct/subCategory": "Sub-Category", + "VendorSoftwareProduct/vendorId": "Vendor ID", + "VendorSoftwareProduct/vendorName": "Vendor", + "VendorSoftwareProduct/onboardingOrigin": "Onboarding Origin", + "VendorSoftwareProduct/networkPackageName": "Network Package Name", + + "EntitlementPool" : "Entitlement Pool", + "EntitlementPool/name" : "Name", + "EntitlementPool/description" : "Description", + "EntitlementPool/referencingFeatureGroups" : "Referencing Feature Groups", + "EntitlementPool/operationalScope" : "Operational Scope", + "EntitlementPool/thresholdValue" : "Threshold Value", + "EntitlementPool/thresholdUnits" : "Threshold Units", + "EntitlementPool/increments" : "Increments", + "EntitlementPool/startDate" : "Start Date", + "EntitlementPool/expiryDate" : "Expiry Date", + "EntitlementPool/limits" : "Limits", + + "Limit/aggregationFunction" : "Aggregation Function", + "Limit/description" : "Description", + "Limit/metric" : "Metric", + "Limit/name" : "Name", + "Limit/time" : "Time", + "Limit/type" : "Type", + "Limit/unit" : "Unit", + "Limit/value" : "Value", + + "FeatureGroup" : "Feature Group", + "FeatureGroup/name" : "Name", + "FeatureGroup/description" : "Description", + "FeatureGroup/partNumber" : "Part Number", + "FeatureGroup/entitlementPoolsIds" : "Entitlement Pools", + "FeatureGroup/licenseKeyGroupsIds" : "License Keys", + "FeatureGroup/referencingLicenseAgreements" : "Referencing License Agreements", + "FeatureGroup/manufacturerReferenceNumber" : "Manufacturer Reference #", + + "VendorLicenseModel" : "License Model", + "VendorLicenseModel/vendorName" : "Vendor", + "VendorLicenseModel/description" : "Description", + + "Component" : "Component", + "Component/name" : "Name", + "Component/description" : "Description", + "Component/displayName" : "Display Name", + "Component/nfcCode" : "NFC Code", + "Component/vfcCode" : "VFC Code", + "Component/nfcFunction" : "NFC Function", + + "ComponentDependencies" : "Component Dependencies", + + "ComponentQuestionnaire" : "Component Questionnaire", + "ComponentQuestionnaire/compute" : "Compute", + "ComponentQuestionnaire/storage/backup/backupStorageSize": "Backup Storage Size", + "ComponentQuestionnaire/storage/backup/backupSolution": "Backup Solution", + "ComponentQuestionnaire/compute/guestOS" : "Guest OS", + "ComponentQuestionnaire/compute/guestOS/bitSize" : "Bit Size", + "ComponentQuestionnaire/compute/guestOS/name" : "Name", + "ComponentQuestionnaire/compute/guestOS/tools" : "Tools", + "ComponentQuestionnaire/compute/numOfVMs" : "Number of VMs", + "ComponentQuestionnaire/compute/numOfVMs/maximum" : "Max", + "ComponentQuestionnaire/compute/numOfVMs/minimum" : "Min", + "ComponentQuestionnaire/general" : "General", + "ComponentQuestionnaire/general/disk" : "Disk", + "ComponentQuestionnaire/general/disk/bootDiskSizePerVM" : "Size of boot disk per VM(GB)", + "ComponentQuestionnaire/general/disk/ephemeralDiskSizePerVM" : "Size of ephemeral disk per VM (GB)", + "ComponentQuestionnaire/general/dnsConfiguration" : "DNS Configuration", + "ComponentQuestionnaire/general/hypervisor" : "Hypervisor Info", + "ComponentQuestionnaire/general/hypervisor/hypervisor" : "Hypervisor", + "ComponentQuestionnaire/general/hypervisor/drivers" : "Drivers", + "ComponentQuestionnaire/general/hypervisor/containerFeaturesDescription" : "Container Features Description", + "ComponentQuestionnaire/general/image" : "Image", + "ComponentQuestionnaire/general/image/providedBy" : "Provided By", + "ComponentQuestionnaire/general/recovery" : "Recovery", + "ComponentQuestionnaire/general/recovery/pointObjective" : "Point Objective (Minutes)", + "ComponentQuestionnaire/general/recovery/timeObjective" : "Time Objective (Minutes)", + "ComponentQuestionnaire/general/recovery/vmProcessFailuresHandling" : "VM Process Failure Handling", + "ComponentQuestionnaire/general/vmCloneUsage" : "VM Clone Usage", + "ComponentQuestionnaire/highAvailabilityAndLoadBalancing" : "High Availability and Load-Balancing", + "ComponentQuestionnaire/highAvailabilityAndLoadBalancing/architectureChoice": "Architecture Choice", + "ComponentQuestionnaire/highAvailabilityAndLoadBalancing/failureLoadDistribution": "Failure Load Distribution", + "ComponentQuestionnaire/highAvailabilityAndLoadBalancing/highAvailabilityMode" : "Mode", + "ComponentQuestionnaire/highAvailabilityAndLoadBalancing/horizontalScaling": "Horizontal Scaling", + "ComponentQuestionnaire/highAvailabilityAndLoadBalancing/isComponentMandatory" : "Is Component Mandatory", + "ComponentQuestionnaire/highAvailabilityAndLoadBalancing/loadDistributionMechanism": "Load Distribution Mechanism", + "ComponentQuestionnaire/highAvailabilityAndLoadBalancing/nkModelImplementation": "nkModel Implementation", + "ComponentQuestionnaire/highAvailabilityAndLoadBalancing/slaRequirements": "SLA Requirements", + "ComponentQuestionnaire/network" : "Network", + "ComponentQuestionnaire/network/networkCapacity" : "Capacity", + "ComponentQuestionnaire/network/networkCapacity/networkTransactionsPerSecond": "Network Transactions Per Second", + "ComponentQuestionnaire/network/networkCapacity/protocolWithHighestTrafficProfileAcrossAllNICs": "Protocol with Highest Traffic Profile Across All NICs", + "ComponentQuestionnaire/storage" : "Storage", + "ComponentQuestionnaire/storage/backup" : "Backup", + "ComponentQuestionnaire/storage/backup/backupNIC" : "NIC", + "ComponentQuestionnaire/storage/backup/backupType" : "Type", + "ComponentQuestionnaire/storage/logBackup" : "Log Backup", + "ComponentQuestionnaire/storage/logBackup/logBackupFrequency": "Log Backup Frequency", + "ComponentQuestionnaire/storage/logBackup/logFileLocation": "Log File Location", + "ComponentQuestionnaire/storage/logBackup/logRetentionPeriod": "Log Retention Period", + "ComponentQuestionnaire/storage/logBackup/sizeOfLogFiles": "Size of Log Files", + "ComponentQuestionnaire/storage/snapshotBackup" : "Snapshot", + "ComponentQuestionnaire/storage/snapshotBackup/snapshotFrequency" : "Frequency", + + "ComputeQuestionnaire" : "Compute Questionnaire", + "ComputeQuestionnaire/vmSizing" : "VM Sizing", + "ComputeQuestionnaire/vmSizing/numOfCPUs" : "Number of CPUs", + "ComputeQuestionnaire/vmSizing/fileSystemSizeGB" : "File System Size (GB)", + "ComputeQuestionnaire/vmSizing/persistentStorageVolumeSize" : "Persistent Storage/Volume Size (GB)", + "ComputeQuestionnaire/vmSizing/ioOperationsPerSec" : "I/O Operations (per second)", + "ComputeQuestionnaire/vmSizing/cpuOverSubscriptionRatio" : "CPU Oversubscription Ratio", + "ComputeQuestionnaire/vmSizing/memoryRAM" : "Memory - RAM", + + "Compute/name" : "name", + "Compute/description" : "description", + + "LicenseAgreement" : "License Agreements", + "LicenseAgreement/description" : "Description", + "LicenseAgreement/featureGroupsIds" : "Related Feature Groups", + "LicenseAgreement/licenseTerm" : "Term", + "LicenseAgreement/name" : "Name", + "LicenseAgreement/requirementsAndConstrains" : "Requirements and Constraints", + + "LicenseKeyGroup" : "License Key Group", + "LicenseKeyGroup/description" : "Description", + "LicenseKeyGroup/expiryDate" : "Expiry Date", + "LicenseKeyGroup/increments" : "Increments", + "LicenseKeyGroup/name" : "Name", + "LicenseKeyGroup/operationalScope" : "Operational Scope", + "LicenseKeyGroup/referencingFeatureGroups" : "Referencing Feature Group(s)", + "LicenseKeyGroup/startDate" : "Start Date", + "LicenseKeyGroup/thresholdUnits" : "Threshold Units", + "LicenseKeyGroup/thresholdValue" : "Threshold Value", + "LicenseKeyGroup/type" : "Type", + + "Nic" : "NIC", + "Nic/description" : "Description", + "Nic/name" : "Name", + "Nic/networkDescription" : "Network Description", + "Nic/networkName" : "Network Name", + "Nic/networkType" : "Network Type", + + "NicQuestionnaire" : "NIC Questionnaire", + "NicQuestionnaire/ipConfiguration" : "IP Configuration", + "NicQuestionnaire/ipConfiguration/ipv4Required" : "IPv4 Required", + "NicQuestionnaire/ipConfiguration/ipv6Required" : "IPv6 Required", + "NicQuestionnaire/network/networkDescription" : "Network Description", + "NicQuestionnaire/sizing" : "Sizing", + "NicQuestionnaire/sizing/acceptableJitter" : "Acceptable Jitter", + "NicQuestionnaire/sizing/acceptableJitter/mean" : "Mean", + "NicQuestionnaire/sizing/acceptableJitter/max" : "Max", + "NicQuestionnaire/sizing/acceptableJitter/variable" : "Var", + "NicQuestionnaire/sizing/acceptablePacketLoss" : "Allow Packet Loss", + "NicQuestionnaire/sizing/describeQualityOfService" : "Describe Quality of Service", + "NicQuestionnaire/sizing/flowLength" : "Flow Length", + "NicQuestionnaire/sizing/flowLength/packets" : "Packets", + "NicQuestionnaire/sizing/flowLength/packets/peak" : "Peak", + "NicQuestionnaire/sizing/flowLength/packets/avg" : "Avg.", + "NicQuestionnaire/sizing/flowLength/bytes" : "Bytes", + "NicQuestionnaire/sizing/flowLength/bytes/peak" : "Peak", + "NicQuestionnaire/sizing/flowLength/bytes/avg" : "Avg.", + "NicQuestionnaire/sizing/inflowTrafficPerSecond" : "Inflow Traffic per second", + "NicQuestionnaire/sizing/inflowTrafficPerSecond/packets" : "Packets", + "NicQuestionnaire/sizing/inflowTrafficPerSecond/bytes" : "Bytes", + "NicQuestionnaire/sizing/inflowTrafficPerSecond/packets/peak" : "Peak", + "NicQuestionnaire/sizing/inflowTrafficPerSecond/packets/avg" : "Avg.", + "NicQuestionnaire/sizing/inflowTrafficPerSecond/bytes/peak" : "Peak", + "NicQuestionnaire/sizing/inflowTrafficPerSecond/bytes/avg" : "Avg.", + "NicQuestionnaire/sizing/outflowTrafficPerSecond" : "Outflow Traffic", + "NicQuestionnaire/sizing/outflowTrafficPerSecond/packets" : "Packets", + "NicQuestionnaire/sizing/outflowTrafficPerSecond/bytes" : "Bytes", + "NicQuestionnaire/sizing/outflowTrafficPerSecond/packets/peak" : "Peak", + "NicQuestionnaire/sizing/outflowTrafficPerSecond/packets/avg" : "Avg.", + "NicQuestionnaire/sizing/outflowTrafficPerSecond/bytes/peak" : "Peak", + "NicQuestionnaire/sizing/outflowTrafficPerSecond/bytes/avg" : "Avg.", + "NicQuestionnaire/protocols" : "Protocols", + "NicQuestionnaire/protocols/protocols" : "Protocols", + "NicQuestionnaire/protocols/protocolWithHighestTrafficProfile" : "Protocol with Highest Traffic Profile across all NICs", + + "OrchestrationTemplateCandidate/modules": "modules", + "OrchestrationTemplateCandidate/modules/index": "module", + "OrchestrationTemplateCandidate/nested": "nested", + "OrchestrationTemplateCandidate/unassigned": "unassigned", + "OrchestrationTemplateCandidate/modules/index/env": "env", + "OrchestrationTemplateCandidate/modules/index/yaml": "yaml", + "OrchestrationTemplateCandidate/modules/index/isBase": "Is Base", + + + "Image/fileName" : "File Name", + "Image/description" : "Description", + + "ImageQuestionnaire" : "Image Questionnaire", + "ImageQuestionnaire/format" : "Format", + "ImageQuestionnaire/version" : "Version", + "ImageQuestionnaire/md5" : "md5", + + "SNMP_POLL" : "SNMP Poll", + "SNMP_POLL/File Name" : "File Name", + + "SNMP_TRAP" : "SNMP Trap", + "SNMP_TRAP/File Name": "File Name", + + "Process" : "Process", + "Process/name" : "Name", + "Process/description" : "Description", + "Process/type" : "Type", + "Process/artifactName" : "Artifact Name", + + "DeploymentFlavor" : "Deployment Flavor", + "DeploymentFlavor/model" : "Model", + "DeploymentFlavor/description" : "Description", + "DeploymentFlavor/featureGroupId" : "Related FG", + "DeploymentFlavor/componentComputeAssociations" : "Associated Computes", + "DeploymentFlavor/componentComputeAssociations/componentId" : "Component", + "DeploymentFlavor/componentComputeAssociations/computeFlavorId" : "Compute", + + "Network/name" : "Name", + "Network/dhcp" : "DHCP", + + "OrchestrationTemplateCandidate": "Candidate Network Package", + "OrchestrationTemplateCandidate/File Structure": "File Structure", + + "OrchestrationTemplate": "Orchestration Template", + "NetworkPackage": "Network Package", + "NetworkPackage/File": "File", + "Artifact": "Artifact", + + "ServiceModel": "Service Model", + "ServiceModel/Service Model Definition Entry": "Definition Entry", + + "Merge Required" : "Conflicts", + + "VSPQuestionnaire" : "VSP Questionnaire", + "VSPQuestionnaire/general" : "General", + "VSPQuestionnaire/general/affinityData" : "Affinity", + "VSPQuestionnaire/general/availability" : "Availability", + "VSPQuestionnaire/general/availability/useAvailabilityZonesForHighAvailability" : "Use Availability Zones", + "VSPQuestionnaire/general/regionsData" : "Regions", + "VSPQuestionnaire/general/regionsData/multiRegion" : "Is Multi-Region", + "VSPQuestionnaire/general/regionsData/regions" : "Selected Regions", + "VSPQuestionnaire/general/storageDataReplication" : "Storage Data Replication", + "VSPQuestionnaire/general/storageDataReplication/storageReplicationAcrossRegion" : "Storage Replication Across Regions", + "VSPQuestionnaire/general/storageDataReplication/storageReplicationSize" : "Storage Replication Size", + "VSPQuestionnaire/general/storageDataReplication/storageReplicationSource": "Storage Replication Source", + "VSPQuestionnaire/general/storageDataReplication/storageReplicationFrequency" : "Storage Replication Frequency", + "VSPQuestionnaire/general/storageDataReplication/storageReplicationDestination" : "Storage Replication Destination" } diff --git a/openecomp-ui/src/nfvo-utils/i18n/i18n.stories.js b/openecomp-ui/src/nfvo-utils/i18n/i18n.stories.js new file mode 100644 index 0000000000..816915b1c9 --- /dev/null +++ b/openecomp-ui/src/nfvo-utils/i18n/i18n.stories.js @@ -0,0 +1,35 @@ +import React from 'react'; +import {storiesOf, action} from '@kadira/storybook'; +import {text, number} from '@kadira/storybook-addon-knobs'; +import {withKnobs} from '@kadira/storybook-addon-knobs'; +import i18n from 'nfvo-utils/i18n/i18n.js'; +import i18nJson from 'nfvo-utils/i18n/en.json'; + +const stories = storiesOf('i18n', module); +stories.addDecorator(withKnobs); + + +i18nJson['added'] = 'this is my test'; +i18nJson['added with {param}'] = 'this is my test with {param}'; + +stories + .add('i18n tests', () => { + let keys = [ + 'I do not exist', + 'Delete', + 'OrchestrationTemplateCandidate/File Structure' + ]; + let translations = []; + let i=0; + translations.push(<div id={i++}>KEY: VALUE</div>) + keys.forEach((key) => { + translations.push((<div id={i++}>{key} : {i18n(key)} </div>)); + }); + var param = 'param'; + translations.push((<div id={i++}>added : {i18n('added')} </div>)); + translations.push((<div id={i++}><font color="red"><b>WRONG</b></font> - added with ${param} in translation : {i18n(`added with ${param}`)} </div>)); + translations.push((<div id={i++}><font color="green"><b>RIGHT</b></font> - added with ${param} and options object {JSON.stringify({param:param})}: {i18n('added with {param}', {param: param})} </div>)); + + return (<div>{translations}</div>); + }) +; diff --git a/openecomp-ui/src/sdc-app/AppStore.js b/openecomp-ui/src/sdc-app/AppStore.js index 9157c340a3..be1a4254a1 100644 --- a/openecomp-ui/src/sdc-app/AppStore.js +++ b/openecomp-ui/src/sdc-app/AppStore.js @@ -19,6 +19,7 @@ import onBoardingReducersMap from './onboarding/OnboardingReducersMap.js'; import flowsReducersMap from './flows/FlowsReducersMap.js'; import loaderReducer from 'nfvo-components/loader/LoaderReducer.js'; import globalModalReducer from 'nfvo-components/modal/GlobalModalReducer.js'; +import notificationsReducer from 'sdc-app/onboarding/userNotifications/NotificationsReducer.js'; const thunk = store => next => action => typeof action === 'function' ? action(store.dispatch, store.getState) : @@ -33,7 +34,8 @@ export const storeCreator = (initialState) => createStore(combineReducers({ // flows reducers ...flowsReducersMap, modal: globalModalReducer, - loader: loaderReducer + loader: loaderReducer, + notifications: notificationsReducer }), initialState, composeEnhancers(applyMiddleware(thunk))); diff --git a/openecomp-ui/src/sdc-app/Application.jsx b/openecomp-ui/src/sdc-app/Application.jsx index 10e866a602..4915d26044 100644 --- a/openecomp-ui/src/sdc-app/Application.jsx +++ b/openecomp-ui/src/sdc-app/Application.jsx @@ -14,13 +14,28 @@ * permissions and limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import {Provider} from 'react-redux'; import GlobalModal from 'nfvo-components/modal/GlobalModal.js'; import Loader from 'nfvo-components/loader/Loader.jsx'; +import WebSocketUtil from 'nfvo-utils/WebSocketUtil.js'; +import UserNotificationsActionHelper from 'sdc-app/onboarding/userNotifications/UserNotificationsActionHelper.js'; import store from './AppStore.js'; class Application extends React.Component { + static propTypes = { + openSocket: PropTypes.bool + }; + componentDidMount() { + const {openSocket = true} = this.props; + if(openSocket) { + UserNotificationsActionHelper.notificationsFirstHandling(store.dispatch); + } + } + componentWillUnmount() { + WebSocketUtil.close(); + } render() { return ( <Provider store={store}> diff --git a/openecomp-ui/src/sdc-app/ModulesOptions.jsx b/openecomp-ui/src/sdc-app/ModulesOptions.jsx index 61d19d9e7a..28fab80da9 100644 --- a/openecomp-ui/src/sdc-app/ModulesOptions.jsx +++ b/openecomp-ui/src/sdc-app/ModulesOptions.jsx @@ -14,6 +14,7 @@ * permissions and limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import {connect} from 'react-redux'; import Input from 'nfvo-components/input/validation/InputWrapper.jsx'; @@ -55,13 +56,13 @@ const mapActionsToProps = dispatch => { class ModuleOptions extends React.Component { static propTypes = { - onBootstrapped: React.PropTypes.func.isRequired, - onLicenseAgreementListEditor: React.PropTypes.func.isRequired, - onFeatureGroupsListEditor: React.PropTypes.func.isRequired, - onLicenseKeyGroupsListEditor: React.PropTypes.func.isRequired, - onEntitlementPoolsListEditor: React.PropTypes.func.isRequired, - onOnboardingCatalog: React.PropTypes.func.isRequired, - onSoftwareProductDetails: React.PropTypes.func.isRequired, + onBootstrapped: PropTypes.func.isRequired, + onLicenseAgreementListEditor: PropTypes.func.isRequired, + onFeatureGroupsListEditor: PropTypes.func.isRequired, + onLicenseKeyGroupsListEditor: PropTypes.func.isRequired, + onEntitlementPoolsListEditor: PropTypes.func.isRequired, + onOnboardingCatalog: PropTypes.func.isRequired, + onSoftwareProductDetails: PropTypes.func.isRequired, }; state = { diff --git a/openecomp-ui/src/sdc-app/common/activity-log/ActivityLog.js b/openecomp-ui/src/sdc-app/common/activity-log/ActivityLog.js index f7354f96e2..a1ad437f5b 100644 --- a/openecomp-ui/src/sdc-app/common/activity-log/ActivityLog.js +++ b/openecomp-ui/src/sdc-app/common/activity-log/ActivityLog.js @@ -16,11 +16,12 @@ import {connect} from 'react-redux'; import ActivityLogView from './ActivityLogView.jsx'; -export const mapStateToProps = ({licenseModel: {activityLog}}) => { +export const mapStateToProps = ({users: {usersList}, licenseModel: {activityLog}}) => { let activities = activityLog; return { - activities + activities: activities.map(activity => ({...activity, user: {id: activity.user, name: usersList.find(userObject => userObject.userId === activity.user).fullName}})), + usersList }; }; diff --git a/openecomp-ui/src/sdc-app/common/activity-log/ActivityLogActionHelper.js b/openecomp-ui/src/sdc-app/common/activity-log/ActivityLogActionHelper.js index 01a27abbc5..729d8fb5f3 100644 --- a/openecomp-ui/src/sdc-app/common/activity-log/ActivityLogActionHelper.js +++ b/openecomp-ui/src/sdc-app/common/activity-log/ActivityLogActionHelper.js @@ -13,19 +13,12 @@ * or implied. See the License for the specific language governing * permissions and limitations under the License. */ -import RestAPIUtil from 'nfvo-utils/RestAPIUtil.js'; -import Configuration from 'sdc-app/config/Configuration.js'; import ActivityLogConstants from './ActivityLogConstants.js'; - - -function baseUrl(itemId, versionId) { - const restPrefix = Configuration.get('restPrefix'); - return `${restPrefix}/v1.0/activity-logs/${itemId}/versions/${versionId}`; -} +import ItemHelper from 'sdc-app/common/helpers/ItemsHelper.js'; export default { fetchActivityLog(dispatch, {itemId, versionId}){ - return RestAPIUtil.fetch(baseUrl(itemId, versionId)).then(response => dispatch({type: ActivityLogConstants.ACTIVITY_LOG_UPDATED, response})); + return ItemHelper.fetchActivityLog({itemId, versionId}).then(response => dispatch({type: ActivityLogConstants.ACTIVITY_LOG_UPDATED, response})); } }; diff --git a/openecomp-ui/src/sdc-app/common/activity-log/ActivityLogView.jsx b/openecomp-ui/src/sdc-app/common/activity-log/ActivityLogView.jsx index 9abddea542..5b8c29b719 100644 --- a/openecomp-ui/src/sdc-app/common/activity-log/ActivityLogView.jsx +++ b/openecomp-ui/src/sdc-app/common/activity-log/ActivityLogView.jsx @@ -67,9 +67,9 @@ export function ActivityListItem({activity, isHeader, isDes, onSort}) { return ( <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-action' data-test-id='activity-action'>{i18n(type)}</div> + <div className='table-cell activity-comment' title={isHeader ? '' : comment} data-test-id='activity-comment'><span>{i18n(comment)}</span></div> + <div className='table-cell activity-username' data-test-id='activity-username'>{isHeader ? i18n(activity.user) : `${i18n(user.name)} (${user.id})`}</div> <div className='table-cell activity-status' data-test-id='activity-status'><ActivityLogStatus isHeader={isHeader} status={status}/></div> </li> ); @@ -91,10 +91,10 @@ class ActivityLogView extends Component { 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})}/> + onSort={() => this.setState({sortDescending: !this.state.sortDescending})} + isHeader/> {this.sortActivities(this.filterActivities(), this.state.sortDescending).map(activity => <ActivityListItem key={activity.id} activity={activity}/>)} </ListEditorView> </div> @@ -106,7 +106,8 @@ class ActivityLogView extends Component { let {localFilter} = this.state; if (localFilter.trim()) { const filter = new RegExp(escape(localFilter), 'i'); - return activities.filter(({user = '', comment = '', type = ''}) => escape(user).match(filter) || escape(comment).match(filter) || escape(type).match(filter)); + return activities.filter(({user = {id: '', name: ''}, comment = '', type = ''}) => + escape(user.id).match(filter) || escape(user.name).match(filter) || escape(comment).match(filter) || escape(type).match(filter)); } else { return activities; diff --git a/openecomp-ui/src/sdc-app/common/helpers/ItemsHelper.js b/openecomp-ui/src/sdc-app/common/helpers/ItemsHelper.js new file mode 100644 index 0000000000..b82bc92017 --- /dev/null +++ b/openecomp-ui/src/sdc-app/common/helpers/ItemsHelper.js @@ -0,0 +1,78 @@ +/*! + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ +import RestAPIUtil from 'nfvo-utils/RestAPIUtil.js'; +import Configuration from 'sdc-app/config/Configuration.js'; +import {permissionTypes} from 'sdc-app/onboarding/permissions/PermissionsConstants.js'; +import {actionsEnum as VersionControllerActionsEnum} from 'nfvo-components/panel/versionController/VersionControllerConstants.js'; +import {actionTypes as onboardingActionTypes} from 'sdc-app/onboarding/OnboardingConstants.js'; + +function baseUrl() { + const restPrefix = Configuration.get('restPrefix'); + return `${restPrefix}/v1.0/items`; +} + +const ItemsHelper = { + performVCAction({itemId, version, action, comment}) { + const {id: versionId} = version; + const data = { + action, + ...action === VersionControllerActionsEnum.COMMIT && {commitRequest: {message: comment}} + }; + return RestAPIUtil.put(`${baseUrl()}/${itemId}/versions/${versionId}/actions`, data); + }, + + fetchVersions({itemId}) { + return RestAPIUtil.fetch(`${baseUrl()}/${itemId}/versions`); + }, + + fetchVersion({itemId, versionId}) { + return RestAPIUtil.fetch(`${baseUrl()}/${itemId}/versions/${versionId}`); + }, + + fetchActivityLog({itemId, versionId}) { + return RestAPIUtil.fetch(`${baseUrl()}/${itemId}/versions/${versionId}/activity-logs`); + }, + + fetchUsers({itemId}) { + return RestAPIUtil.fetch(`${baseUrl()}/${itemId}/permissions`); + }, + + updateContributors({itemId, removedUsersIds, addedUsersIds}) { + return RestAPIUtil.put(`${baseUrl()}/${itemId}/permissions/${permissionTypes.CONTRIBUTOR}`, {removedUsersIds, addedUsersIds}); + }, + + changeOwner({itemId, ownerId}) { + return RestAPIUtil.put(`${baseUrl()}/${itemId}/permissions/${permissionTypes.OWNER}`, {removedUsersIds: [], addedUsersIds: [ownerId]}); + }, + + checkItemStatus(dispatch, {itemId, versionId}) { + return ItemsHelper.fetchVersion({itemId, versionId}).then(response => { + let state = response && response.state || {}; + const {baseId, description, id, name, status} = response; + + dispatch({ + type: onboardingActionTypes.UPDATE_ITEM_STATUS, + itemState: state, + itemStatus: response.status, + updatedVersion: {baseId, description, id, name, status} + }); + return Promise.resolve(response); + }); + + }, +}; + +export default ItemsHelper; diff --git a/openecomp-ui/src/sdc-app/common/helpers/ScreensHelper.js b/openecomp-ui/src/sdc-app/common/helpers/ScreensHelper.js new file mode 100644 index 0000000000..d8fa02664f --- /dev/null +++ b/openecomp-ui/src/sdc-app/common/helpers/ScreensHelper.js @@ -0,0 +1,290 @@ +import {itemTypes} from 'sdc-app/onboarding/versionsPage/VersionsPageConstants.js'; +import {enums, screenTypes} from 'sdc-app/onboarding/OnboardingConstants.js'; +import OnboardingActionHelper from 'sdc-app/onboarding/OnboardingActionHelper.js'; +import {actionTypes as SoftwareProductActionTypes} from 'sdc-app/onboarding/softwareProduct/SoftwareProductConstants.js'; +import ItemsHelper from 'sdc-app/common/helpers/ItemsHelper.js'; +import versionPageActionHelper from 'sdc-app/onboarding/versionsPage/VersionsPageActionHelper.js'; +import i18n from 'nfvo-utils/i18n/i18n.js'; +import {actionTypes as modalActionTypes} from 'nfvo-components/modal/GlobalModalConstants.js'; + +const ScreensHelper = { + loadScreen(dispatch, {screen, screenType, props}) { + if(screen === enums.SCREEN.ONBOARDING_CATALOG) { + OnboardingActionHelper.navigateToOnboardingCatalog(dispatch); + return; + } + + screenType = !screenType ? this.getScreenType(screen) : screenType; + + if(screenType === screenTypes.LICENSE_MODEL) { + const {licenseModelId, version, licenseModel, usersList} = props; + let itemStatusPromise = version && screen ? + ItemsHelper.checkItemStatus(dispatch, {itemId: licenseModelId, versionId: version.id}) : + Promise.resolve(); + itemStatusPromise.then((updatedVersion) => { + if (updatedVersion && updatedVersion.status !== version.status) { + dispatch({ + type: modalActionTypes.GLOBAL_MODAL_WARNING, + data: { + title: i18n('Commit error'), + msg: i18n('Item version was certified by Owner'), + cancelButtonText: i18n('Cancel') + } + }); + versionPageActionHelper.fetchVersions(dispatch, {itemType: itemTypes.LICENSE_MODEL, itemId: licenseModelId}); + } + let newVersion = updatedVersion ? updatedVersion : version; + switch (screen) { + case enums.SCREEN.LICENSE_MODEL_OVERVIEW: + OnboardingActionHelper.navigateToLicenseModelOverview(dispatch, {licenseModelId, version: newVersion}); + break; + case enums.SCREEN.LICENSE_AGREEMENTS: + OnboardingActionHelper.navigateToLicenseAgreements(dispatch, {licenseModelId, version: newVersion}); + break; + case enums.SCREEN.FEATURE_GROUPS: + OnboardingActionHelper.navigateToFeatureGroups(dispatch, {licenseModelId, version: newVersion}); + break; + case enums.SCREEN.ENTITLEMENT_POOLS: + OnboardingActionHelper.navigateToEntitlementPools(dispatch, {licenseModelId, version: newVersion}); + break; + case enums.SCREEN.LICENSE_KEY_GROUPS: + OnboardingActionHelper.navigateToLicenseKeyGroups(dispatch, {licenseModelId, version: newVersion}); + break; + case enums.SCREEN.ACTIVITY_LOG: + OnboardingActionHelper.navigateToLicenseModelActivityLog(dispatch, {licenseModelId, version: newVersion}); + break; + case enums.SCREEN.VERSIONS_PAGE: + default: + OnboardingActionHelper.navigateToVersionsPage(dispatch, { + itemId: licenseModelId, + itemType: itemTypes.LICENSE_MODEL, + itemName: licenseModel.name, + users: usersList + }); + break; + } + }); + } + + else if(screenType === screenTypes.SOFTWARE_PRODUCT) { + const {softwareProductId, componentId, version, softwareProduct, usersList} = props; + let itemStatusPromise = version && screen ? + ItemsHelper.checkItemStatus(dispatch, {itemId: softwareProductId, versionId: version.id}) : + Promise.resolve(); + itemStatusPromise.then((updatedVersion) => { + if (updatedVersion && updatedVersion.status !== version.status) { + dispatch({ + type: modalActionTypes.GLOBAL_MODAL_WARNING, + data: { + title: i18n('Commit error'), + msg: i18n('Item version already Certified'), + cancelButtonText: i18n('Cancel') + } + }); + versionPageActionHelper.fetchVersions(dispatch, {itemType: itemTypes.SOFTWARE_PRODUCT, itemId: softwareProductId}); + } + + let newVersion = updatedVersion ? updatedVersion : version; + if (screen === screenTypes.SOFTWARE_PRODUCT_COMPONENT_DEFAULT_GENERAL) { + OnboardingActionHelper.navigateToSoftwareProductComponentGeneralAndUpdateLeftPanel(dispatch, { + softwareProductId, + componentId, + version: newVersion + }); + } + if (componentId) { + switch (screen) { + case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENTS: + OnboardingActionHelper.navigateToSoftwareProductComponentGeneralAndUpdateLeftPanel(dispatch, { + softwareProductId, + componentId, + version: newVersion + }); + break; + case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_GENERAL: + OnboardingActionHelper.navigateToSoftwareProductComponentGeneral(dispatch, { + softwareProductId, + componentId, + version: newVersion + }); + break; + case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_COMPUTE: + OnboardingActionHelper.navigateToComponentCompute(dispatch, { + softwareProductId, + componentId, + version: newVersion + }); + break; + case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_LOAD_BALANCING: + OnboardingActionHelper.navigateToComponentLoadBalancing(dispatch, { + softwareProductId, + componentId, + version: newVersion + }); + break; + case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_NETWORK: + OnboardingActionHelper.navigateToComponentNetwork(dispatch, { + softwareProductId, + componentId, + version: newVersion + }); + break; + case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_STORAGE: + OnboardingActionHelper.navigateToComponentStorage(dispatch, { + softwareProductId, + componentId, + version: newVersion + }); + break; + case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_PROCESSES: + OnboardingActionHelper.navigateToSoftwareProductComponentProcesses(dispatch, { + softwareProductId, + componentId, + version: newVersion + }); + break; + case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_MONITORING: + OnboardingActionHelper.navigateToSoftwareProductComponentMonitoring(dispatch, { + softwareProductId, + componentId, + version: newVersion + }); + break; + case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_IMAGES: + OnboardingActionHelper.navigateToComponentImages(dispatch, { + softwareProductId, + componentId, + version: newVersion + }); + break; + } + } + else { + switch (screen) { + case enums.SCREEN.SOFTWARE_PRODUCT_LANDING_PAGE: + OnboardingActionHelper.navigateToSoftwareProductLandingPage(dispatch, { + softwareProductId, + version: newVersion + }); + break; + case enums.SCREEN.SOFTWARE_PRODUCT_DETAILS: + OnboardingActionHelper.navigateToSoftwareProductDetails(dispatch, { + softwareProductId, + version: newVersion + }); + break; + case enums.SCREEN.SOFTWARE_PRODUCT_ATTACHMENTS_SETUP: + OnboardingActionHelper.navigateToSoftwareProductAttachmentsSetupTab(dispatch, { + softwareProductId, + version + }); + break; + case enums.SCREEN.SOFTWARE_PRODUCT_ATTACHMENTS_VALIDATION: + OnboardingActionHelper.navigateToSoftwareProductAttachmentsValidationTab(dispatch, { + softwareProductId, + version + }); + break; + case enums.SCREEN.SOFTWARE_PRODUCT_PROCESSES: + OnboardingActionHelper.navigateToSoftwareProductProcesses(dispatch, { + softwareProductId, + version: newVersion + }); + break; + case enums.SCREEN.SOFTWARE_PRODUCT_DEPLOYMENT: + OnboardingActionHelper.navigateToSoftwareProductDeployment(dispatch, { + softwareProductId, + version: newVersion + }); + break; + case enums.SCREEN.SOFTWARE_PRODUCT_NETWORKS: + OnboardingActionHelper.navigateToSoftwareProductNetworks(dispatch, { + softwareProductId, + version: newVersion + }); + break; + case enums.SCREEN.SOFTWARE_PRODUCT_DEPENDENCIES: + OnboardingActionHelper.navigateToSoftwareProductDependencies(dispatch, { + softwareProductId, + version: newVersion + }); + break; + case enums.SCREEN.SOFTWARE_PRODUCT_ACTIVITY_LOG: + OnboardingActionHelper.navigateToSoftwareProductActivityLog(dispatch, { + softwareProductId, + version: newVersion + }); + break; + case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENTS: + OnboardingActionHelper.navigateToSoftwareProductComponents(dispatch, { + softwareProductId, + version: newVersion + }); + dispatch({ + type: SoftwareProductActionTypes.TOGGLE_NAVIGATION_ITEM, + mapOfExpandedIds: { + [enums.SCREEN.SOFTWARE_PRODUCT_COMPONENTS]: true + } + }); + break; + case enums.SCREEN.SOFTWARE_PRODUCT_VERSIONS_PAGE: + default: + OnboardingActionHelper.navigateToVersionsPage(dispatch, { + itemId: softwareProductId, + itemType: itemTypes.SOFTWARE_PRODUCT, + itemName: softwareProduct.name, + users: usersList, + additionalProps: { + licenseModelId: softwareProduct.vendorId, + licensingVersion: softwareProduct.licensingVersion + } + }); + break; + } + } + }); + } + }, + + getScreenType(screen) { + switch (screen) { + case enums.SCREEN.LICENSE_MODEL_OVERVIEW: + case enums.SCREEN.LICENSE_AGREEMENTS: + case enums.SCREEN.FEATURE_GROUPS: + case enums.SCREEN.ENTITLEMENT_POOLS: + case enums.SCREEN.LICENSE_KEY_GROUPS: + case enums.SCREEN.ACTIVITY_LOG: + return screenTypes.LICENSE_MODEL; + case screenTypes.SOFTWARE_PRODUCT_COMPONENT_DEFAULT_GENERAL: + case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_GENERAL: + case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_COMPUTE: + case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_LOAD_BALANCING: + case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_NETWORK: + case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_STORAGE: + case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_PROCESSES: + case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_MONITORING: + case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_IMAGES: + case enums.SCREEN.SOFTWARE_PRODUCT_LANDING_PAGE: + case enums.SCREEN.SOFTWARE_PRODUCT_DETAILS: + case enums.SCREEN.SOFTWARE_PRODUCT_ATTACHMENTS: + case enums.SCREEN.SOFTWARE_PRODUCT_PROCESSES: + case enums.SCREEN.SOFTWARE_PRODUCT_DEPLOYMENT: + case enums.SCREEN.SOFTWARE_PRODUCT_NETWORKS: + case enums.SCREEN.SOFTWARE_PRODUCT_DEPENDENCIES: + case enums.SCREEN.SOFTWARE_PRODUCT_ACTIVITY_LOG: + case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENTS: + return screenTypes.SOFTWARE_PRODUCT; + } + }, + + loadLandingScreen(dispatch, {previousScreenName, props: {licenseModelId, softwareProductId, version}}) { + const screenType = this.getScreenType(previousScreenName); + let screen = screenType === screenTypes.SOFTWARE_PRODUCT ? + enums.SCREEN.SOFTWARE_PRODUCT_LANDING_PAGE : + enums.SCREEN.LICENSE_MODEL_OVERVIEW; + let props = {licenseModelId, softwareProductId, version}; + return this.loadScreen(dispatch, {screen, screenType, props}); + } +}; + +export default ScreensHelper; diff --git a/openecomp-ui/src/sdc-app/common/merge/MergeEditor.js b/openecomp-ui/src/sdc-app/common/merge/MergeEditor.js new file mode 100644 index 0000000000..baf00cf0cf --- /dev/null +++ b/openecomp-ui/src/sdc-app/common/merge/MergeEditor.js @@ -0,0 +1,37 @@ +/*! + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ +import {connect} from 'react-redux'; +import MergeEditorView from './MergeEditorView.jsx'; +import MergeEditorActionHelper from './MergeEditorActionHelper.js'; + +export const mapStateToProps = ({mergeEditor, currentScreen}) => { + let {props} = currentScreen; + let item = { + id: props.softwareProductId || props.licenseModelId, + version: props.version + }; + return {...mergeEditor, item, currentScreen}; +}; + +export const mapActionsToProps = (dispatch) => { + return { + fetchConflict: ({cid, itemId, version}) => MergeEditorActionHelper.fetchConflict(dispatch, {itemId, version, cid}), + onResolveConflict: ({conflictId, resolution, itemId, version, currentScreen}) => + MergeEditorActionHelper.resolveConflict(dispatch, {itemId, version, conflictId, resolution, currentScreen}) + }; +}; + +export default connect(mapStateToProps, mapActionsToProps)(MergeEditorView); diff --git a/openecomp-ui/src/sdc-app/common/merge/MergeEditorActionHelper.js b/openecomp-ui/src/sdc-app/common/merge/MergeEditorActionHelper.js new file mode 100644 index 0000000000..3885ee4051 --- /dev/null +++ b/openecomp-ui/src/sdc-app/common/merge/MergeEditorActionHelper.js @@ -0,0 +1,443 @@ +/*! + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ +import {actionTypes, rules, dataRules, SyncStates} from './MergeEditorConstants.js'; +import cloneDeep from 'lodash/cloneDeep.js'; +import RestAPIUtil from 'nfvo-utils/RestAPIUtil.js'; +import Configuration from 'sdc-app/config/Configuration.js'; +import ItemsHelper from '../../common/helpers/ItemsHelper.js'; +import {modalContentMapper} from 'sdc-app/common/modal/ModalContentMapper.js'; +import {actionTypes as modalActionTypes} from 'nfvo-components/modal/GlobalModalConstants.js'; +import i18n from 'nfvo-utils/i18n/i18n.js'; +import {optionsInputValues as epOptionsValues} from 'sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsConstants.js'; +import {optionsInputValues as laOptionsValues} from 'sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementConstants.js'; +import {optionsInputValues as processOptionValues} from 'sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesConstants.js'; +import {selectValues as limitSelectValues} from 'sdc-app/onboarding/licenseModel/limits/LimitEditorConstants.js'; +import FeatureGroupsActionHelper from 'sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupsActionHelper.js'; +import LicenseAgreementActionHelper from 'sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementActionHelper.js'; +import moment from 'moment'; +import {DATE_FORMAT} from 'sdc-app/onboarding/OnboardingConstants.js'; +import ScreensHelper from 'sdc-app/common/helpers/ScreensHelper.js'; + +function softwareProductCategoriesUrl() { + const restATTPrefix = Configuration.get('restATTPrefix'); + return `${restATTPrefix}/v1/categories/resources/`; +} + +function versionUrl(itemId, versionId) { + const restPrefix = Configuration.get('restPrefix'); + return `${restPrefix}/v1.0/items/${itemId}/versions/${versionId}`; +} + +function baseUrl(itemId, version, conflictId) { + const versionId = version.id; + const restPrefix = Configuration.get('restPrefix'); + let baseUrl = `${restPrefix}/v1.0/items/${itemId}/versions/${versionId}/conflicts`; + return conflictId ? `${baseUrl}/${conflictId}` : baseUrl; +} + +function fetchConflicts({itemId, version}) { + return RestAPIUtil.fetch(`${baseUrl(itemId, version)}`); +} + +function fetchConflictById({itemId, version, cid}) { + return RestAPIUtil.fetch(`${baseUrl(itemId, version, cid)}`); +} + +function resolveConflict({itemId, version, conflictId, resolution}) { + return RestAPIUtil.put(`${baseUrl(itemId, version, conflictId)}`, {resolution}); +} + +function fetchCategories() { + return RestAPIUtil.fetch(softwareProductCategoriesUrl()); +} + +function fetchVersion({vendorId, licensingVersion}) { + return RestAPIUtil.fetch(versionUrl(vendorId, licensingVersion)); +} + +function createCategoryStr(data, {categories}) { + + let {category, subCategory} = data; + let foundCat = categories.find(element => element.uniqueId === category); + if (!foundCat) { return ''; } + + let catName = foundCat.name; + let foundSub = foundCat.subcategories.find(element => element.uniqueId === subCategory); + if (!foundSub) { return `${catName}`; } + + let subcatName = foundSub.name; + return `${catName} - ${subcatName}`; + +} + +function getEnumValues({enums, list}) { + + if (!list) { return ''; } + return list.map(item => enums.find(el => el.enum === item).title); + +} + +const MergeEditorActionHelper = { + + analyzeSyncResult(dispatch, {itemId, version}) { + return ItemsHelper.checkItemStatus(dispatch, {itemId, versionId: version.id}).then((response) => { + let inMerge = response && response.state && response.state.synchronizationState === SyncStates.MERGE; + if (inMerge) { + MergeEditorActionHelper.fetchConflicts(dispatch, {itemId, version}).then(() => + dispatch({ + type: modalActionTypes.GLOBAL_MODAL_SHOW, + data: { + modalComponentName: modalContentMapper.MERGE_EDITOR, + modalClassName: 'merge-editor-modal', + title: `${i18n('Merge Required')} - ${version.description}`, + onDeclined: () => { + dispatch({ + type: modalActionTypes.GLOBAL_MODAL_CLOSE + }); + }, + modalComponentProps: { + size: 'lg', + type: 'default' + } + } + }) + ); + } + return Promise.resolve({updatedVersion: response, inMerge, isDirty: response.state.dirty}); + }); + }, + + fetchConflicts(dispatch, {itemId, version}) { + return fetchConflicts({itemId, version}).then( + (data) => { + dispatch({ + type: actionTypes.LOAD_CONFLICTS, + data + }); + return data; + } + ); + }, + + fetchConflict(dispatch, {itemId, version, cid}) { + fetchConflictById({itemId, version, cid}).then( + (data) => { + let newData = {}; + newData = MergeEditorActionHelper.processConflict(dispatch, {conflict: data, itemId, cid, version}); + dispatch({ + type: actionTypes.LOAD_CONFLICT, + data: newData + }); + } + ); + }, + + resolveConflict(dispatch, {itemId, version, conflictId, resolution, currentScreen}) { + resolveConflict({itemId, version, conflictId, resolution}).then(() => { + MergeEditorActionHelper.fetchConflicts(dispatch, {itemId, version}).then(conflicts => { + if(conflicts.conflictInfoList && conflicts.conflictInfoList.length === 0) { + dispatch({ + type: modalActionTypes.GLOBAL_MODAL_CLOSE + }); + ScreensHelper.loadLandingScreen(dispatch, {previousScreenName: currentScreen.screen, props: currentScreen.props}); + ItemsHelper.checkItemStatus(dispatch, {itemId, versionId: version.id}); + } + }); + }); + }, + + createConflictObject(data, {cid, conflict, dispatch, itemId, version, isYours}) { + + let newData = {}; + + for (let key in data) { + + if (data.hasOwnProperty(key)) { + let value = data[key]; + let fieldRule = dataRules[conflict.type] && dataRules[conflict.type][key] || dataRules.general[key]; + + if (fieldRule) { + switch (fieldRule.rule) { + + case rules.SKIP: + break; + + case rules.BOOLEAN: + let {trueValue, falseValue} = fieldRule; + newData[key] = value === trueValue ? true : value === falseValue ? false : undefined; + break; + + case rules.PARSE: + let {moveFields, subFields} = fieldRule; + if (moveFields) { + let fields = subFields || Object.keys(value); + fields.forEach(field => { + newData[field] = MergeEditorActionHelper.createConflictObject( + value[field], {cid, conflict, dispatch, itemId, version, isYours} + ); + }); + } else { + newData[key] = MergeEditorActionHelper.createConflictObject( + value, {cid, conflict, dispatch, itemId, version, isYours} + ); + } + break; + + case rules.FUNCTION: + let {args, functionName} = fieldRule; + newData[key] = MergeEditorActionHelper[functionName](data, { + cid, conflict, dispatch, version, fieldName: key, isYours, itemId, args + }); + break; + + default: + newData[key] = value; + break; + } + + } else { + newData[key] = value; + + } + } + } + + return newData; + + }, + + getNamesFromIDs(data, {version, cid, dispatch, itemId, fieldName, isYours, args}) { + + let idList = data[fieldName] || []; + let {fetchFunction, fetchField} = args; + + let promises = idList.map(id => + new Promise(resolve => + MergeEditorActionHelper[fetchFunction]( + dispatch, {licenseModelId: itemId, [fetchField]: id, version} + ).then(item => resolve(item.name)) + ) + ); + + Promise.all(promises).then(fetchedItems => { + let yoursOrTheirs = isYours ? 'yoursField' : 'theirsField'; + dispatch({ + type: actionTypes.DATA_PROCESSED, + data: { + cid, + [yoursOrTheirs]: { name: fieldName, value: fetchedItems } + } + }); + }); + + return idList; + + }, + + getFeatureGroups(data, {version, cid, dispatch, itemId, fieldName, isYours}) { + + let featureGroups = data[fieldName] || []; + if (!(featureGroups instanceof Array)) { + featureGroups = [featureGroups]; + } + + let promises = featureGroups.map(featureGroupId => + new Promise(resolve => + FeatureGroupsActionHelper.fetchFeatureGroup( + dispatch, {licenseModelId: itemId, featureGroupId, version} + ).then(featureGroup => resolve(featureGroup.name)) + .catch(reason => console.log(`getFeatureGroups Promise rejected ('${reason}')`)) + ) + ); + + Promise.all(promises).then(fetchedGroups => { + let yoursOrTheirs = isYours ? 'yoursField' : 'theirsField'; + dispatch({ + type: actionTypes.DATA_PROCESSED, + data: { + cid, + [yoursOrTheirs]: { name: fieldName, value: fetchedGroups } + } + }); + }); + + return featureGroups; + + }, + + getLicenseAgreements(data, {version, cid, dispatch, itemId, fieldName, isYours}) { + + let licenseAgreements = data[fieldName] || []; + if (!(licenseAgreements instanceof Array)) { + licenseAgreements = [licenseAgreements]; + } + + let promises = licenseAgreements.map(licenseAgreementId => + new Promise(resolve => + LicenseAgreementActionHelper.fetchLicenseAgreement( + dispatch, {licenseModelId: itemId, licenseAgreementId, version} + ).then(licenseAgreement => resolve(licenseAgreement.name)) + .catch(reason => console.log(`getLicenseAgreements Promise rejected ('${reason}')`)) + ) + ); + + Promise.all(promises).then(fetchedAgreements => { + let yoursOrTheirs = isYours ? 'yoursField' : 'theirsField'; + dispatch({ + type: actionTypes.DATA_PROCESSED, + data: { + cid, + [yoursOrTheirs]: { name: fieldName, value: fetchedAgreements } + } + }); + }); + + return licenseAgreements; + + }, + + processConflict(dispatch, {conflict, cid, version, itemId,}) { + + let {id, type, yours, theirs} = conflict; + + let newYours = MergeEditorActionHelper.createConflictObject( + cloneDeep(yours), {cid, conflict, dispatch, itemId, version, isYours: true} + ); + let newTheirs = MergeEditorActionHelper.createConflictObject( + cloneDeep(theirs), {cid, conflict, dispatch, itemId, version, isYours: false} + ); + + return { + id, + type, + yours: newYours, + theirs: newTheirs + }; + + }, + + reduceList(data, {fieldName, args}) { + + let {subField} = args; + return data[fieldName].map(el => el[subField]); + + }, + + getEnumList({fieldName}) { + + const enumLists = { + 'licenseTerm': laOptionsValues.LICENSE_MODEL_TYPE, + 'operationalScope': epOptionsValues.OPERATIONAL_SCOPE, + 'processType': processOptionValues.PROCESS_TYPE, + 'limitType': [ + {title: 'Service Provider', enum: 'ServiceProvider'}, + {title: 'Vendor', enum: 'Vendor'} + ], + 'limitUnit': limitSelectValues.UNIT + }; + + return enumLists[fieldName]; + + }, + + getEnumValue(data, {fieldName, args = {}}) { + + let value = data[fieldName]; + let enumValues = MergeEditorActionHelper.getEnumList({fieldName: args.listName || fieldName}); + let enumValue = enumValues.find(el => el.enum === value); + + return enumValue && enumValue.title || value; + + }, + + processChoice(data, {fieldName, args = {}}) { + + let value = data[fieldName]; + let enumValues = MergeEditorActionHelper.getEnumList({fieldName: args.listName || fieldName}); + let newValue = value.other || enumValues && enumValues.find(el => el.enum === value.choice).title || value.choice; + + return newValue; + + }, + + processChoices(data, {fieldName, args = {}}) { + + let value = data[fieldName]; + let enumValues = MergeEditorActionHelper.getEnumList({fieldName: args.listName || fieldName}); + let newValue = value.other || getEnumValues({enums: enumValues, list: value.choices}) || value.choices; + + return newValue; + + }, + + convertArrayToObject(data, {fieldName}) { + let value = data[fieldName]; + let newValue = {}; + value.forEach((el, index) => { + newValue[index] = el; + }); + return newValue; + }, + + fetchCategory(data, {cid, isYours, fieldName, dispatch}) { + + fetchCategories().then((categories) => { + let value = createCategoryStr(data, {categories}); + let yoursOrTheirs = isYours ? 'yoursField' : 'theirsField'; + + dispatch({ + type: actionTypes.DATA_PROCESSED, + data: { + cid, + [yoursOrTheirs]: { name: fieldName, value } + } + }); + + }); + }, + + fetchLMVersion(data, {cid, dispatch, isYours}) { + + let {licensingVersion, vendorId} = data; + let yoursOrTheirs = isYours ? 'yoursField' : 'theirsField'; + + if (licensingVersion) { + fetchVersion({licensingVersion, vendorId}).then(response => { + dispatch({ + type: actionTypes.DATA_PROCESSED, + data: { + cid, + [yoursOrTheirs]: { + name: 'licensingVersion', + value: response.name + } + } + }); + }); + } + + }, + + parseDate(data, {fieldName}) { + + let date = data[fieldName]; + return date && moment(date, DATE_FORMAT).format(DATE_FORMAT); + + } + +}; + +export default MergeEditorActionHelper; diff --git a/openecomp-ui/src/sdc-app/common/merge/MergeEditorConstants.js b/openecomp-ui/src/sdc-app/common/merge/MergeEditorConstants.js new file mode 100644 index 0000000000..f7f6d4195e --- /dev/null +++ b/openecomp-ui/src/sdc-app/common/merge/MergeEditorConstants.js @@ -0,0 +1,224 @@ +/*! + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +import keyMirror from 'nfvo-utils/KeyMirror.js'; + +export const actionTypes = keyMirror({ + LOAD_CONFLICTS: null, + ADD_ACTIONS: null, + LOAD_CONFLICT: null, + DATA_PROCESSED: null +}); + +export const rules = { + SKIP: 'skip', + PARSE: 'parse', + FUNCTION: 'function', + BOOLEAN: 'boolean' +}; + +export const SyncStates = { + MERGE : 'Merging', + OUT_OF_SYNC: 'OutOfSync', + UP_TO_DATE: 'UpToDate' +}; + +export const ResolutionTypes = { + YOURS: 'YOURS', + THEIRS: 'THEIRS' +}; + +export const fileTypes = { + LKG : 'LicenseKeyGroup', + VLM : 'VendorLicenseModel', + EP : 'EntitlementPool', + FG : 'FeatureGroup', + LA : 'LicenseAgreement', + VSP : 'VendorSoftwareProduct', + LIMIT : 'Limit', + VSP_Q : 'VSPQuestionnaire', + COMPONENT : 'Component', + COMPONENT_Q : 'ComponentQuestionnaire', + COMPONENT_DEP : 'ComponentDependencies', + COMPUTE_Q : 'ComputeQuestionnaire', + COMPUTE : 'Compute', + COMPUTE_FLAVOR: 'ComputeFlavor', + NIC : 'Nic', + NIC_Q : 'NicQuestionnaire', + IMAGE : 'Image', + IMAGE_Q : 'ImageQuestionnaire', + PROCESS : 'Process', + DEPLOYMENT_FLAVOR : 'DeploymentFlavor', + VENDOR : 'Vendor', + NETWORK : 'Network', + ORCHESTRATION_TEMPLATE_CANDIDATE : 'OrchestrationTemplateCandidate' +}; + +export const dataRules = { + general: { + id: { + rule: rules.SKIP + }, + questionareData: { + rule: rules.PARSE, + moveFields: true + }, + startDate: { + rule: rules.FUNCTION, + functionName: 'parseDate' + }, + expiryDate: { + rule: rules.FUNCTION, + functionName: 'parseDate' + }, + featureGroups: { + rule: rules.FUNCTION, + functionName: 'reduceList', + args: {subField: 'name'} + }, + licenseKeyGroups: { + rule: rules.FUNCTION, + functionName: 'reduceList', + args: {subField: 'name'} + }, + entitlementPools: { + rule: rules.FUNCTION, + functionName: 'reduceList', + args: {subField: 'name'} + }, + }, + [fileTypes.COMPONENT] : { + }, + [fileTypes.COMPUTE_FLAVOR] : { + associatedToDeploymentFlavor: { + rule: rules.BOOLEAN, + trueValue: 'true' + } + }, + [fileTypes.COMPUTE_Q] : { + }, + [fileTypes.COMPONENT_Q] : { + isComponentMandatory: { + rule: rules.BOOLEAN, + trueValue: 'YES', + falseValue: 'NO' + } + }, + [fileTypes.EP] : { + referencingFeatureGroups: { + rule: rules.SKIP, + functionName: 'getFeatureGroups' + }, + operationalScope: { + rule: rules.FUNCTION, + functionName: 'processChoices' + }, + }, + [fileTypes.FG] : { + referencingLicenseAgreements: { + rule: rules.SKIP, + functionName: 'getLicenseAgreements' + } + }, + [fileTypes.LA] : { + licenseTerm : { + rule: rules.FUNCTION, + functionName: 'processChoice' + } + }, + [fileTypes.LIMIT] : { + type: { + rule: rules.FUNCTION, + functionName: 'getEnumValue', + args: {listName: 'limitType'} + }, + unit: { + rule: rules.FUNCTION, + functionName: 'getEnumValue', + args: {listName: 'limitUnit'} + } + }, + [fileTypes.LKG] : { + operationalScope: { + rule: rules.FUNCTION, + functionName: 'processChoices' + }, + referencingFeatureGroups: { + rule: rules.SKIP, + functionName: 'getFeatureGroups' + }, + }, + [fileTypes.NIC] : { + networkId: { + rule: rules.SKIP + } + }, + [fileTypes.NIC_Q] : { + }, + [fileTypes.PROCESS] : { + type: { + rule: rules.FUNCTION, + functionName: 'getEnumValue', + args: {listName: 'processType'} + } + }, + [fileTypes.VLM] : { + iconRef: { + rule: rules.SKIP + } + }, + [fileTypes.VSP] : { + vendorId: { + rule: rules.SKIP + }, + onboardingMethod: { + rule: rules.SKIP + }, + validationData: { + rule: rules.SKIP + }, + isOldVersion: { + rule: rules.SKIP + }, + licensingVersion: { + rule: rules.FUNCTION, + functionName: 'fetchLMVersion' + }, + category: { + rule: rules.FUNCTION, + functionName: 'fetchCategory' + }, + subCategory: { + rule: rules.SKIP + }, + }, + [fileTypes.VSP_Q] : { + affinityData: { + rule: rules.SKIP + }, + storageReplicationAcrossRegion: { + rule: rules.BOOLEAN, + trueValue: 'true', + falseValue: 'false' + } + }, + [fileTypes.ORCHESTRATION_TEMPLATE_CANDIDATE] : { + modules: { + rule: rules.FUNCTION, + functionName: 'convertArrayToObject' + }, + }, +}; diff --git a/openecomp-ui/src/sdc-app/common/merge/MergeEditorReducer.js b/openecomp-ui/src/sdc-app/common/merge/MergeEditorReducer.js new file mode 100644 index 0000000000..6985fcfaca --- /dev/null +++ b/openecomp-ui/src/sdc-app/common/merge/MergeEditorReducer.js @@ -0,0 +1,66 @@ +/*! + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ +import {actionTypes} from './MergeEditorConstants.js'; + +export default (state = [], action) => { + switch (action.type) { + case actionTypes.LOAD_CONFLICT: { + let cdata = {...action.data}; + // let data = state.conflicts ? {...state.conflicts.data} : {} ; + // data[cdata.id] = cdata; + let conflicts = state.conflicts ? {...state.conflicts} : {}; + conflicts[cdata.id] = cdata; + return { + ...state, + conflicts + }; + } + case actionTypes.DATA_PROCESSED: { + let conflicts = {...state.conflicts}; + let {data} = action; + if (data && data.cid) { + let yours = {...conflicts[data.cid].yours}; + let theirs = {...conflicts[data.cid].theirs}; + let {yoursField, theirsField} = data; + if (yoursField) { + yours[yoursField.name] = yoursField.value; + conflicts[data.cid].yours = yours; + } + if (theirsField) { + theirs[theirsField.name] = theirsField.value; + conflicts[data.cid].theirs = theirs; + } + } + return { + ...state, + conflicts: { + ...conflicts + } + }; + } + case actionTypes.LOAD_CONFLICTS: + let conflictFiles = []; + if (action.data) { + conflictFiles = [...action.data.conflictInfoList]; + } + return { + inMerge: conflictFiles.length > 0, + conflictFiles + }; + default: + return state; + } +}; diff --git a/openecomp-ui/src/sdc-app/common/merge/MergeEditorView.jsx b/openecomp-ui/src/sdc-app/common/merge/MergeEditorView.jsx new file mode 100644 index 0000000000..34d86419e7 --- /dev/null +++ b/openecomp-ui/src/sdc-app/common/merge/MergeEditorView.jsx @@ -0,0 +1,256 @@ +/*! + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ +import React from 'react'; +import i18n from 'nfvo-utils/i18n/i18n.js'; +import union from 'lodash/union.js'; +import Button from 'sdc-ui/lib/react/Button.js'; +// import Checkbox from 'sdc-ui/lib/react/Checkbox.js'; +import Input from 'nfvo-components/input/validation/Input.jsx'; +import GridSection from 'nfvo-components/grid/GridSection.jsx'; +import GridItem from 'nfvo-components/grid/GridItem.jsx'; +import SVGIcon from 'sdc-ui/lib/react/SVGIcon.js'; +import Radio from 'sdc-ui/lib/react/Radio.js'; +import equal from 'deep-equal'; +import {ResolutionTypes} from './MergeEditorConstants.js'; + +class ConflictCategory extends React.Component { + state = { + resolution: ResolutionTypes.YOURS + }; + + getTitle(conflictType, conflictName) { + if (typeof conflictName === 'undefined' || conflictType === conflictName) { + return i18n(conflictType); + } else { + return `${i18n(conflictType)}: ${conflictName}`; + } + } + + render() { + let {collapseExpand, conflict: {id: conflictId, type, name}, isCollapsed, item: {id: itemId, version}, onResolveConflict} = this.props; + let {resolution} = this.state; + const iconClass = isCollapsed ? 'merge-chevron' : 'merge-chevron right'; + + return ( + <div key={'conflictCategory_' + conflictId} > + <GridSection className='conflict-section'> + <GridItem > + <div className='collapsible-section' onClick={collapseExpand}> + <SVGIcon name={isCollapsed ? 'chevronDown' : 'chevronUp'} iconClassName={iconClass} /> + <div className='conflict-title'>{this.getTitle(type, name)}</div> + </div> + </GridItem> + <GridItem className='yours'> + <Radio name={'radio_' + conflictId} checked={resolution === ResolutionTypes.YOURS} value='yours' + onChange={() => this.setState({resolution: ResolutionTypes.YOURS})} data-test-id={'radio_' + conflictId + '_yours'} /> + </GridItem> + <GridItem className='theirs'> + <Radio name={'radio_' + conflictId} checked={resolution === ResolutionTypes.THEIRS} value='theirs' + onChange={() => this.setState({resolution: ResolutionTypes.THEIRS})} data-test-id={'radio_' + conflictId + '_theirs'} /></GridItem> + <GridItem className='resolve'> + <Button className='conflict-resolve-btn' btnType='outline' color='gray' + onClick={() => onResolveConflict({conflictId, resolution, itemId, version})}> + {i18n('Resolve')} + </Button> + </GridItem> + </GridSection> + <div> + {isCollapsed && this.props.children} + </div> + </div> + ); + } + +}; + +class TextCompare extends React.Component { + render() { + // let rand = Math.random() * (3000 - 1) + 1; + let {yours, theirs, field, type, isObjName, conflictsOnly} = this.props; + let typeYours = typeof yours; + let typeTheirs = typeof theirs; + + let parsedType = `${type}/${field}`.replace(/\/[0-9]+/g,'/index'); + let level = type.split('/').length; + + if (typeYours === 'boolean' || typeTheirs === 'boolean') { + yours = yours ? i18n('Yes') : i18n('No'); + theirs = theirs ? i18n('Yes') : i18n('No'); + } + + + /*if ((typeYours !== 'string' && typeYours !== 'undefined') || (typeTheirs !== 'string' && typeTheirs !== 'undefined')) { + return (<div className='merge-editor-text-field field-error'>{field} cannot be parsed for display</div>); + }*/ + let isDiff = yours !== theirs; + if (!isObjName && + ((!isDiff && conflictsOnly) || + (yours === '' && theirs === '') || + (typeYours === 'undefined' && typeTheirs === 'undefined') + ) + ) { + return null; + } + + return ( + <GridSection className={isDiff ? 'merge-editor-text-field diff' : 'merge-editor-text-field'}> + <GridItem className='field-col grid-col-title' stretch> + <div className={`field ${isDiff ? 'diff' : ''} field-name level-${level} ${isObjName ? 'field-object-name' : ''}`}> + {i18n(parsedType)} + </div> + </GridItem> + <GridItem className='field-col grid-col-yours' stretch> + <div className={`field field-yours ${!yours ? 'empty-field' : ''}`} >{yours || (isObjName ? '' : '━━')}</div> + </GridItem> + <GridItem className='field-col grid-col-theirs' stretch> + <div className={`field field-theirs ${!theirs ? 'empty-field' : ''}`}>{theirs || (isObjName ? '' : '━━')}</div> + </GridItem> + <GridItem stretch/> + </GridSection> + ); + } +}; + +class MergeEditorView extends React.Component { + state = { + collapsingSections: {}, + conflictsOnly: false + }; + + render() { + let {conflicts, item, conflictFiles, onResolveConflict, currentScreen, resolution} = this.props; + + return ( + <div className='merge-editor'> + {conflictFiles && this.renderConflictTableTitles()} + <div className='merge-editor-body'> + {conflictFiles && conflictFiles.sort((a, b) => a.type > b.type).map(file => ( + <ConflictCategory key={'conflict_' + file.id} conflict={file} item={item} isCollapsed={this.state.collapsingSections[file.id]} + collapseExpand={()=>{this.updateCollapseState(file.id);}} + onResolveConflict={cDetails => onResolveConflict({...cDetails, currentScreen})}> + {(conflicts && conflicts[file.id]) && + this.getUnion(conflicts[file.id].yours, conflicts[file.id].theirs).map(field => { + return this.renderField(field, file, conflicts[file.id].yours[field], conflicts[file.id].theirs[field], resolution); + })} + </ConflictCategory>))} + </div> + </div>); + } + + renderConflictTableTitles() + { + return (<GridSection className='conflict-titles-section'> + <GridItem> + {i18n('Page')} + </GridItem> + <GridItem className='yours'> + {i18n('Local (Me)')} + </GridItem> + <GridItem className='theirs'> + {i18n('Last Committed')} + </GridItem> + <GridItem className='resolve'> + <Input + label={i18n('Show Conflicts Only')} + type='checkbox' + value={this.state.conflictsOnly} + onChange={e => this.setState({conflictsOnly: e}) } /> + </GridItem> + </GridSection>); + } + // <Checkbox + // label={i18n('Show Conflicts Only')} + // value={this.state.conflictsOnly} + // checked={this.state.conflictsOnly} + // onChange={checked => this.setState({conflictsOnly: checked})} /> + + renderObjects(yours, theirs, fileType, field, id, resolution) { + if (equal(yours, theirs)) { + return; + } + let {conflictsOnly} = this.state; + return ( + <div key={`obj_${fileType}/${field}_${id}`}> + <TextCompare field={field} type={fileType} conflictsOnly={conflictsOnly} yours='' theirs='' isObjName resolution={resolution} /> + <div className='field-objects'> + <div> + {this.getUnion(yours, theirs).map(key => + this.renderField( + key, + {type: `${fileType}/${field}`, id}, + yours && yours[key], + theirs && theirs[key] + ) + )} + </div> + </div> + </div> + ); + } + + renderList(yours = [], theirs = [], type, field, id, resolution) { + let theirsList = theirs.join(', '); + let yoursList = yours.join(', '); + let {conflictsOnly} = this.state; + return (<TextCompare key={'text_' + id + '_' + field} + field={field} type={type} yours={yoursList} theirs={theirsList} conflictsOnly={conflictsOnly} resolution={resolution} />); + } + + renderField(field, file, yours, theirs, resolution) { + if (yours) { + if (Array.isArray(yours)) { + return this.renderList(yours, theirs, file.type, field, file.id, resolution); + } + else if (typeof yours === 'object') { + return this.renderObjects(yours, theirs, file.type, field, file.id, resolution); + } + } else if (theirs) { + if (Array.isArray(theirs)) { + return this.renderList(yours, theirs, file.type, field, file.id, resolution); + } + else if (typeof theirs === 'object') { + return this.renderObjects(yours, theirs, file.type, field, file.id, resolution); + } + } + let {conflictsOnly} = this.state; + return (<TextCompare key={'text_' + file.id + '_' + field} resolution={resolution} + field={field} type={file.type} yours={yours} theirs={theirs} conflictsOnly={conflictsOnly} />); + } + + getUnion(yours = {},theirs = {}) { + let yoursKeys = Object.keys(yours); + let theirsKeys = Object.keys(theirs); + let myUn = union(yoursKeys, theirsKeys); + return myUn;//.sort((a, b) => a > b); + } + + updateCollapseState(conflictId) { + const {fetchConflict, item: {id: itemId, version}, /*conflicts*/} = this.props; + let isCollapsed = this.state.collapsingSections[conflictId]; + // if (!isCollapsed && !(conflicts && conflictId in conflicts)) { + if (!isCollapsed) { + fetchConflict({cid: conflictId, itemId, version}); + } + this.setState({ + collapsingSections: { + ...this.state.collapsingSections, + [conflictId]: !isCollapsed + } + }); + } +} + +export default MergeEditorView; diff --git a/openecomp-ui/src/sdc-app/common/modal/ModalContentMapper.js b/openecomp-ui/src/sdc-app/common/modal/ModalContentMapper.js index 8c10beb952..487ada0d88 100644 --- a/openecomp-ui/src/sdc-app/common/modal/ModalContentMapper.js +++ b/openecomp-ui/src/sdc-app/common/modal/ModalContentMapper.js @@ -17,12 +17,18 @@ import SoftwareProductCreation from 'sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreation.js'; import LicenseModelCreation from 'sdc-app/onboarding/licenseModel/creation/LicenseModelCreation.js'; import SoftwareProductComponentImageEditor from 'sdc-app/onboarding/softwareProduct/components/images/SoftwareProductComponentsImageEditor.js'; +import VersionPageCreation from 'sdc-app/onboarding/versionsPage/creation/VersionsPageCreation.js'; import SubmitErrorResponse from 'nfvo-components/SubmitErrorResponse.jsx'; import ComputeFlavorEditor from 'sdc-app/onboarding/softwareProduct/components/compute/computeComponents/computeFlavor/ComputeFlavorEditor.js'; import NICCreation from 'sdc-app/onboarding/softwareProduct/components/network/NICCreation/NICCreation.js'; import SoftwareProductComponentsNICEditor from 'sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNICEditor.js'; import ComponentCreation from 'sdc-app/onboarding/softwareProduct/components/creation/SoftwareProductComponentCreation.js'; import SoftwareProductDeploymentEditor from 'sdc-app/onboarding/softwareProduct/deployment/editor/SoftwareProductDeploymentEditor.js'; +import PermissionsManager from 'sdc-app/onboarding/permissions/PermissionsManager.js'; +import CommitCommentModal from 'nfvo-components/panel/versionController/components/CommitCommentModal.jsx'; +import Tree from 'nfvo-components/tree/Tree.jsx'; +import MergeEditor from 'sdc-app/common/merge/MergeEditor.js'; +import Revisions from 'sdc-app/onboarding/revisions/Revisions.js'; export const modalContentMapper = { SOFTWARE_PRODUCT_CREATION: 'SOFTWARE_PRODUCT_CREATION', @@ -33,17 +39,29 @@ export const modalContentMapper = { NIC_CREATION: 'NIC_CREATION', COMPONENT_CREATION: 'COMPONENT_CREATION', SOFTWARE_PRODUCT_COMPONENT_IMAGE_EDITOR : 'SOFTWARE_PRODUCT_COMPONENT_IMAGE_EDITOR', - DEPLOYMENT_FLAVOR_EDITOR: 'DEPLOYMENT_FLAVOR_EDITOR' + DEPLOYMENT_FLAVOR_EDITOR: 'DEPLOYMENT_FLAVOR_EDITOR', + MANAGE_PERMISSIONS: 'MANAGE_PERMISSIONS', + VERSION_CREATION: 'VERSION_CREATION', + COMMIT_COMMENT: 'COMMIT_COMMENT', + VERSION_TREE: 'VERSION_TREE', + MERGE_EDITOR: 'MERGE_EDITOR', + REVISIONS_LIST: 'REVISIONS_LIST' }; export const modalContentComponents = { SUMBIT_ERROR_RESPONSE: SubmitErrorResponse, SOFTWARE_PRODUCT_CREATION: SoftwareProductCreation, + VERSION_CREATION: VersionPageCreation, LICENSE_MODEL_CREATION: LicenseModelCreation, COMPONENT_COMPUTE_FLAVOR_EDITOR: ComputeFlavorEditor, NIC_EDITOR: SoftwareProductComponentsNICEditor, NIC_CREATION: NICCreation, COMPONENT_CREATION: ComponentCreation, SOFTWARE_PRODUCT_COMPONENT_IMAGE_EDITOR : SoftwareProductComponentImageEditor, - DEPLOYMENT_FLAVOR_EDITOR: SoftwareProductDeploymentEditor + DEPLOYMENT_FLAVOR_EDITOR: SoftwareProductDeploymentEditor, + MANAGE_PERMISSIONS: PermissionsManager, + COMMIT_COMMENT: CommitCommentModal, + VERSION_TREE: Tree, + MERGE_EDITOR: MergeEditor, + REVISIONS_LIST: Revisions }; diff --git a/openecomp-ui/src/sdc-app/config/Configuration.js b/openecomp-ui/src/sdc-app/config/Configuration.js index 227e36995b..3d9ab8bf72 100644 --- a/openecomp-ui/src/sdc-app/config/Configuration.js +++ b/openecomp-ui/src/sdc-app/config/Configuration.js @@ -50,6 +50,13 @@ const configuration = new Configuration(); configuration.set('restATTPrefix', configuration.get('defaultRestATTPrefix')); configuration.set('appContextPath', configuration.get('appContextPath')); })(configuration); - +(function setDefaultWebsocketConfig(configuration) { + let websocketPort = configuration.get('defaultWebsocketPort'); + if (DEBUG) { + websocketPort = configuration.get('defaultDebugWebsocketPort'); + } + configuration.set('websocketPort', websocketPort); + configuration.set('websocketPath', configuration.get('defaultWebsocketPath')); +})(configuration); export default configuration; diff --git a/openecomp-ui/src/sdc-app/config/config.json b/openecomp-ui/src/sdc-app/config/config.json index 2725cf1310..e73856e5bb 100644 --- a/openecomp-ui/src/sdc-app/config/config.json +++ b/openecomp-ui/src/sdc-app/config/config.json @@ -4,5 +4,8 @@ "build": "dev", "appContextPath" : "/onboarding", "defaultRestPrefix": "/onboarding-api", - "defaultRestATTPrefix": "/sdc1/feProxy/rest" + "defaultRestATTPrefix": "/sdc1/feProxy/rest", + "defaultWebsocketPort" : "8181", + "defaultDebugWebsocketPort" : "9000", + "defaultWebsocketPath" : "notification-api/ws/notificationHandler" } diff --git a/openecomp-ui/src/sdc-app/flows/FlowsListEditorView.jsx b/openecomp-ui/src/sdc-app/flows/FlowsListEditorView.jsx index c5dbb4f909..365b7f1bdf 100644 --- a/openecomp-ui/src/sdc-app/flows/FlowsListEditorView.jsx +++ b/openecomp-ui/src/sdc-app/flows/FlowsListEditorView.jsx @@ -13,8 +13,8 @@ * or implied. See the License for the specific language governing * permissions and limitations under the License. */ -import React, {PropTypes, Component} from 'react'; - +import React, {Component} from 'react'; +import PropTypes from 'prop-types'; import i18n from 'nfvo-utils/i18n/i18n.js'; import Modal from 'nfvo-components/modal/Modal.jsx'; diff --git a/openecomp-ui/src/sdc-app/flows/SequenceDiagram.jsx b/openecomp-ui/src/sdc-app/flows/SequenceDiagram.jsx index 1add76b598..c128083774 100644 --- a/openecomp-ui/src/sdc-app/flows/SequenceDiagram.jsx +++ b/openecomp-ui/src/sdc-app/flows/SequenceDiagram.jsx @@ -13,7 +13,8 @@ * or implied. See the License for the specific language governing * permissions and limitations under the License. */ -import React, {Component, PropTypes} from 'react'; +import React, {Component} from 'react'; +import PropTypes from 'prop-types'; import Button from 'sdc-ui/lib/react/Button.js'; import Sequencer from 'dox-sequence-diagram-ui'; diff --git a/openecomp-ui/src/sdc-app/heatValidation.app.jsx b/openecomp-ui/src/sdc-app/heatValidation.app.jsx index 6ff3c7375c..5abe3091b3 100644 --- a/openecomp-ui/src/sdc-app/heatValidation.app.jsx +++ b/openecomp-ui/src/sdc-app/heatValidation.app.jsx @@ -24,4 +24,4 @@ import UploadScreen from './heatvalidation/UploadScreen.jsx'; import Application from './Application.jsx'; -ReactDOM.render(<Application><UploadScreen/></Application>, document.getElementById('heat-validation-app')); +ReactDOM.render(<Application openSocket={false}><UploadScreen/></Application>, document.getElementById('heat-validation-app')); diff --git a/openecomp-ui/src/sdc-app/heatvalidation/UploadScreenActionHelper.js b/openecomp-ui/src/sdc-app/heatvalidation/UploadScreenActionHelper.js index 4e9120956e..3c41b126e6 100644 --- a/openecomp-ui/src/sdc-app/heatvalidation/UploadScreenActionHelper.js +++ b/openecomp-ui/src/sdc-app/heatvalidation/UploadScreenActionHelper.js @@ -26,7 +26,7 @@ import {actionTypes as HeatSetupActions} from '../onboarding/softwareProduct/att const options = { headers: { - HTTP_CSP_ATTUID: 'validationOnlyVspUser' + USER_ID: 'validationOnlyVspUser' } }; @@ -37,16 +37,18 @@ function getTimestampString() { return `${date.getFullYear()}-${z(date.getMonth())}-${z(date.getDate())}_${z(date.getHours())}-${z(date.getMinutes())}`; } -function fetchVspId() { +function fetchVspIdAndVersion() { let vspId = sessionStorage.getItem('validationAppVspId'); + let versionId = sessionStorage.getItem('validationAppVersionId'); if (vspId) { - return Promise.resolve({value: vspId}); + return Promise.resolve({value: vspId, versionId}); }else { return RestAPIUtil.fetch('/sdc1/feProxy/onboarding-api/v1.0/vendor-software-products/validation-vsp', options) .then(response => { - sessionStorage.setItem('validationAppVspId', response.value); - return Promise.resolve(response); + sessionStorage.setItem('validationAppVspId', response.itemId); + sessionStorage.setItem('validationAppVersionId', response.version.id); + return Promise.resolve({value: response.itemId, versionId: response.version.id}); }); } @@ -82,16 +84,16 @@ function showFileSaveDialog({blob, xhr, defaultFilename, addTimestamp}) { function uploadFile(formData) { - return fetchVspId() + return fetchVspIdAndVersion() .then(response => { - return RestAPIUtil.post(`/sdc1/feProxy/onboarding-api/v1.0/vendor-software-products/${response.value}/versions/0.1/orchestration-template-candidate`, formData, options); + return RestAPIUtil.post(`/sdc1/feProxy/onboarding-api/v1.0/vendor-software-products/${response.value}/versions/${response.versionId}/orchestration-template-candidate`, formData, options); }); } function loadSoftwareProductHeatCandidate(dispatch){ - return fetchVspId() + return fetchVspIdAndVersion() .then(response => { - return RestAPIUtil.fetch(`/sdc1/feProxy/onboarding-api/v1.0/vendor-software-products/${response.value}/versions/0.1/orchestration-template-candidate/manifest`, options) + return RestAPIUtil.fetch(`/sdc1/feProxy/onboarding-api/v1.0/vendor-software-products/${response.value}/versions/${response.versionId}/orchestration-template-candidate/manifest`, options) .then(response => dispatch({ type: HeatSetupActions.MANIFEST_LOADED, response @@ -100,9 +102,9 @@ function loadSoftwareProductHeatCandidate(dispatch){ } function updateHeatCandidate(dispatch, heatCandidate) { - return fetchVspId() + return fetchVspIdAndVersion() .then(response => { - return RestAPIUtil.put(`/sdc1/feProxy/onboarding-api/v1.0/vendor-software-products/${response.value}/versions/0.1/orchestration-template-candidate/manifest`, + return RestAPIUtil.put(`/sdc1/feProxy/onboarding-api/v1.0/vendor-software-products/${response.value}/versions/${response.versionId}/orchestration-template-candidate/manifest`, heatCandidate.heatData, options) .then(null, error => { dispatch({ @@ -122,16 +124,16 @@ function updateHeatCandidate(dispatch, heatCandidate) { } function fetchSoftwareProduct() { - return fetchVspId() + return fetchVspIdAndVersion() .then(response => { - return RestAPIUtil.fetch(`/sdc1/feProxy/onboarding-api/v1.0/vendor-software-products/${response.value}/versions/0.1`, options); + return RestAPIUtil.fetch(`/sdc1/feProxy/onboarding-api/v1.0/vendor-software-products/${response.value}/versions/${response.versionId}`, options); }); } function downloadHeatFile() { - return fetchVspId() + return fetchVspIdAndVersion() .then(response => { - RestAPIUtil.fetch(`/sdc1/feProxy/onboarding-api/v1.0/vendor-software-products/${response.value}/versions/0.1/orchestration-template-candidate`, { + RestAPIUtil.fetch(`/sdc1/feProxy/onboarding-api/v1.0/vendor-software-products/${response.value}/versions/${response.versionId}/orchestration-template-candidate`, { ...options, dataType: 'binary' }) @@ -145,9 +147,9 @@ function downloadHeatFile() { } function processAndValidateHeatCandidate(dispatch) { - return fetchVspId() + return fetchVspIdAndVersion() .then(response => { - return RestAPIUtil.put(`/sdc1/feProxy/onboarding-api/v1.0/vendor-software-products/${response.value}/versions/0.1/orchestration-template-candidate/process`, {}, options) + return RestAPIUtil.put(`/sdc1/feProxy/onboarding-api/v1.0/vendor-software-products/${response.value}/versions/${response.versionId}/orchestration-template-candidate/process`, {}, options) .then(response => { if (response.status === 'Success') { fetchSoftwareProduct().then(response => { diff --git a/openecomp-ui/src/sdc-app/onboarding/GridStyling.stories.js b/openecomp-ui/src/sdc-app/onboarding/GridStyling.stories.js new file mode 100644 index 0000000000..81a29cf046 --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/GridStyling.stories.js @@ -0,0 +1,221 @@ +import React from 'react'; +import {storiesOf} from '@kadira/storybook'; +import {withKnobs} from '@kadira/storybook-addon-knobs'; + +import GridSection from 'nfvo-components/grid/GridSection.jsx'; +import GridItem from 'nfvo-components/grid/GridItem.jsx'; + + +const stories = storiesOf('GridColumns', module); +stories.addDecorator(withKnobs); + +var divStyle = { + 'border-style': 'solid', + 'border-size': 1 +}; + +const myDiv = (<div style={divStyle}>Text Text Text</div>); + +stories + .add('Grid Options', () => ( + <div> + <GridSection title='No last column set on item'> + <GridItem colSpan={2}> + {myDiv} + </GridItem> + <GridItem colSpan={2}> + {myDiv} + </GridItem> + </GridSection> + + <GridSection hasLastColSet={true} title='With last column set on item and gridsection'> + <GridItem colSpan={2}> + {myDiv} + </GridItem> + <GridItem colSpan={2} lastColInRow={true}> + {myDiv} + </GridItem> + </GridSection> + + <GridSection title='With last column set on item and NOT on gridsection'> + <GridItem colSpan={2}> + {myDiv} + </GridItem> + <GridItem colSpan={2} lastColInRow={true}> + {myDiv} + </GridItem> + </GridSection> + + </div> + )) + .add('Last Column', () => ( + + <div> + <GridSection hasLastColSet={true} title='Testing different configurations with all settings'> + <GridItem colSpan={2}> + {myDiv} + </GridItem> + <GridItem colSpan={2} lastColInRow={true}> + {myDiv} + </GridItem> + </GridSection> + <GridSection hasLastColSet={true}> + <GridItem colSpan={1}> + {myDiv} + </GridItem> + <GridItem colSpan={1}> + {myDiv} + </GridItem> + <GridItem colSpan={1}> + {myDiv} + </GridItem> + <GridItem colSpan={1} lastColInRow={true}> + {myDiv} + </GridItem> + </GridSection> + <GridSection hasLastColSet={true}> + <GridItem colSpan={1}> + {myDiv} + </GridItem> + <GridItem colSpan={1}> + {myDiv} + </GridItem> + <GridItem colSpan={2} lastColInRow={true}> + {myDiv} + </GridItem> + </GridSection> + <GridSection hasLastColSet={true}> + <GridItem colSpan={2}> + {myDiv} + </GridItem> + <GridItem colSpan={1}> + {myDiv} + </GridItem> + <GridItem colSpan={1} lastColInRow={true}> + {myDiv} + </GridItem> + </GridSection> + <GridSection hasLastColSet={true}> + <GridItem colSpan={4} lastColInRow={true}> + {myDiv} + </GridItem> + </GridSection> + <GridSection hasLastColSet={true}> + <GridItem colSpan={3}> + {myDiv} + </GridItem> + <GridItem colSpan={1} lastColInRow={true}> + {myDiv} + </GridItem> + </GridSection> + <GridSection hasLastColSet={true}> + <GridItem colSpan={1}> + {myDiv} + </GridItem> + <GridItem colSpan={3} lastColInRow={true}> + {myDiv} + </GridItem> + </GridSection> + </div> + )) + .add('No Last Column', () => ( + <div> + <GridSection title='Testing different configurations'> + <GridItem colSpan={2}> + {myDiv} + </GridItem> + <GridItem colSpan={2}> + {myDiv} + </GridItem> + </GridSection> + <GridSection> + <GridItem colSpan={1}> + {myDiv} + </GridItem> + <GridItem colSpan={1}> + {myDiv} + </GridItem> + <GridItem colSpan={1}> + {myDiv} + </GridItem> + <GridItem colSpan={1}> + {myDiv} + </GridItem> + </GridSection> + <GridSection> + <GridItem colSpan={1}> + {myDiv} + </GridItem> + <GridItem colSpan={1}> + {myDiv} + </GridItem> + <GridItem colSpan={2}> + {myDiv} + </GridItem> + </GridSection> + <GridSection> + <GridItem colSpan={2}> + {myDiv} + </GridItem> + <GridItem colSpan={1}> + {myDiv} + </GridItem> + <GridItem colSpan={1}> + {myDiv} + </GridItem> + </GridSection> + <GridSection> + <GridItem colSpan={4}> + {myDiv} + </GridItem> + </GridSection> + <GridSection> + <GridItem colSpan={3}> + {myDiv} + </GridItem> + <GridItem colSpan={1}> + {myDiv} + </GridItem> + </GridSection> + <GridSection> + <GridItem colSpan={1}> + {myDiv} + </GridItem> + <GridItem colSpan={3}> + {myDiv} + </GridItem> + </GridSection> + </div> + )) .add('Test LKG form', () => ( + <div> + <GridSection title='Testing VLM LKG configurations'> + <GridItem colSpan={2}> + {myDiv} + </GridItem> + <GridItem colSpan={2} lastColInRow={true}> + {myDiv} + </GridItem> + <GridItem colSpan={2}> + {myDiv} + </GridItem> + <GridItem colSpan={2} lastColInRow={true}> + {myDiv} + </GridItem> + <GridItem colSpan={1}> + {myDiv} + </GridItem> + <GridItem colSpan={1}> + {myDiv} + </GridItem> + <GridItem colSpan={1}> + {myDiv} + </GridItem> + <GridItem colSpan={1} lastColInRow={true}> + {myDiv} + </GridItem> + <GridItem colSpan={2}> + <div style={divStyle}>1</div> + </GridItem> + </GridSection> + </div> +));
\ No newline at end of file diff --git a/openecomp-ui/src/sdc-app/onboarding/OnboardingActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/OnboardingActionHelper.js index 2788d4db92..794f5c1781 100644 --- a/openecomp-ui/src/sdc-app/onboarding/OnboardingActionHelper.js +++ b/openecomp-ui/src/sdc-app/onboarding/OnboardingActionHelper.js @@ -13,6 +13,9 @@ * or implied. See the License for the specific language governing * permissions and limitations under the License. */ +import UsersActionHelper from './users/UsersActionHelper.js'; +import VersionsPageActionHelper from './versionsPage/VersionsPageActionHelper.js'; +import PermissionsActionHelper from './permissions/PermissionsActionHelper.js'; import LicenseModelActionHelper from './licenseModel/LicenseModelActionHelper.js'; import LicenseAgreementActionHelper from './licenseModel/licenseAgreement/LicenseAgreementActionHelper.js'; import FeatureGroupsActionHelper from './licenseModel/featureGroups/FeatureGroupsActionHelper.js'; @@ -28,13 +31,15 @@ import SoftwareProductComponentsNetworkActionHelper from './softwareProduct/comp import SoftwareProductDependenciesActionHelper from './softwareProduct/dependencies/SoftwareProductDependenciesActionHelper.js'; import ComputeFlavorActionHelper from './softwareProduct/components/compute/ComputeFlavorActionHelper.js'; import OnboardActionHelper from './onboard/OnboardActionHelper.js'; +import MergeEditorActionHelper from 'sdc-app/common/merge/MergeEditorActionHelper.js'; +// import {SyncStates} from 'sdc-app/common/merge/MergeEditorConstants.js'; import SoftwareProductComponentsMonitoringAction from './softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringActionHelper.js'; import {actionTypes, enums} from './OnboardingConstants.js'; -import SoftwareProductComponentsImageActionHelper from './softwareProduct/components/images/SoftwareProductComponentsImageActionHelper.js'; -import {navigationItems as SoftwareProductNavigationItems, actionTypes as SoftwareProductActionTypes, onboardingOriginTypes} from 'sdc-app/onboarding/softwareProduct/SoftwareProductConstants.js'; +import {actionTypes as SoftwareProductActionTypes, onboardingOriginTypes} from 'sdc-app/onboarding/softwareProduct/SoftwareProductConstants.js'; import ActivityLogActionHelper from 'sdc-app/common/activity-log/ActivityLogActionHelper.js'; +import ItemsHelper from 'sdc-app/common/helpers/ItemsHelper.js'; +import SoftwareProductComponentsImageActionHelper from './softwareProduct/components/images/SoftwareProductComponentsImageActionHelper.js'; import licenseModelOverviewActionHelper from 'sdc-app/onboarding/licenseModel/overview/licenseModelOverviewActionHelper.js'; -import store from 'sdc-app/AppStore.js'; import {tabsMapping as attachmentsTabsMapping} from 'sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachmentsConstants.js'; import SoftwareProductAttachmentsActionHelper from 'sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachmentsActionHelper.js'; @@ -49,21 +54,25 @@ function setCurrentScreen(dispatch, screen, props = {}) { }); } -function getCurrentLicenseModelVersion(licenseModelId) { - return store.getState().licenseModelList.find(({id}) => id === licenseModelId).version; -} - -function getCurrentSoftwareProductVersion(softwareProductId) { - return store.getState().softwareProductList.find(({id}) => id === softwareProductId).version; +export function updateCurrentScreenProps(dispatch, props = {}) { + dispatch({ + type: actionTypes.UPDATE_CURRENT_SCREEN_PROPS, + props + }); } -export default { +const OnboardingActionHelper = { - navigateToOnboardingCatalog(dispatch) { + loadItemsLists(dispatch) { LicenseModelActionHelper.fetchLicenseModels(dispatch); LicenseModelActionHelper.fetchFinalizedLicenseModels(dispatch); SoftwareProductActionHelper.fetchSoftwareProductList(dispatch); SoftwareProductActionHelper.fetchFinalizedSoftwareProductList(dispatch); + }, + + navigateToOnboardingCatalog(dispatch) { + UsersActionHelper.fetchUsersList(dispatch); + this.loadItemsLists(dispatch); OnboardActionHelper.resetOnboardStore(dispatch); setCurrentScreen(dispatch, enums.SCREEN.ONBOARDING_CATALOG); }, @@ -79,6 +88,7 @@ export default { } return SoftwareProductActionHelper.updateSoftwareProduct(dispatch, { softwareProduct: dataToSave.softwareProduct, + version, qdata: dataToSave.qdata }); } @@ -86,25 +96,19 @@ export default { }, navigateToLicenseModelOverview(dispatch, {licenseModelId, version}) { - if (!version) { - version = getCurrentLicenseModelVersion(licenseModelId); - } /** * TODO change to specific rest */ LicenseModelActionHelper.fetchLicenseModelById(dispatch, {licenseModelId, version}).then(() => { - LicenseModelActionHelper.fetchLicenseModelItems(dispatch, {licenseModelId, version}).then(() =>{ + LicenseModelActionHelper.fetchLicenseModelItems(dispatch, {licenseModelId, version}).then(() => { setCurrentScreen(dispatch, enums.SCREEN.LICENSE_MODEL_OVERVIEW, {licenseModelId, version}); }); licenseModelOverviewActionHelper.selectVLMListView(dispatch, {buttonTab: null}); }); }, navigateToLicenseAgreements(dispatch, {licenseModelId, version}) { - if(!version) { - version = getCurrentLicenseModelVersion(licenseModelId); - } LicenseAgreementActionHelper.fetchLicenseAgreementList(dispatch, {licenseModelId, version}); LicenseModelActionHelper.fetchLicenseModelById(dispatch, {licenseModelId, version}).then(() => { setCurrentScreen(dispatch, enums.SCREEN.LICENSE_AGREEMENTS, {licenseModelId, version}); @@ -112,70 +116,45 @@ export default { }, navigateToFeatureGroups(dispatch, {licenseModelId, version}) { - if(!version) { - version = getCurrentLicenseModelVersion(licenseModelId); - } FeatureGroupsActionHelper.fetchFeatureGroupsList(dispatch, {licenseModelId, version}); setCurrentScreen(dispatch, enums.SCREEN.FEATURE_GROUPS, {licenseModelId, version}); }, navigateToEntitlementPools(dispatch, {licenseModelId, version}) { - if(!version) { - version = getCurrentLicenseModelVersion(licenseModelId); - } EntitlementPoolsActionHelper.fetchEntitlementPoolsList(dispatch, {licenseModelId, version}); setCurrentScreen(dispatch, enums.SCREEN.ENTITLEMENT_POOLS, {licenseModelId, version}); }, navigateToLicenseKeyGroups(dispatch, {licenseModelId, version}) { - if(!version) { - version = getCurrentLicenseModelVersion(licenseModelId); - } LicenseKeyGroupsActionHelper.fetchLicenseKeyGroupsList(dispatch, {licenseModelId, version}); setCurrentScreen(dispatch, enums.SCREEN.LICENSE_KEY_GROUPS, {licenseModelId, version}); }, navigateToLicenseModelActivityLog(dispatch, {licenseModelId, version}){ - if(!version) { - version = getCurrentLicenseModelVersion(licenseModelId); - } ActivityLogActionHelper.fetchActivityLog(dispatch, {itemId: licenseModelId, versionId: version.id}); setCurrentScreen(dispatch, enums.SCREEN.ACTIVITY_LOG, {licenseModelId, version}); }, - navigateToSoftwareProductLandingPage(dispatch, {softwareProductId, licenseModelId, version, licensingVersion}) { - - if (!version) { - version = getCurrentSoftwareProductVersion(softwareProductId); - } - + navigateToSoftwareProductLandingPage(dispatch, {softwareProductId, version}) { SoftwareProductComponentsActionHelper.clearComponentsStore(dispatch); SoftwareProductActionHelper.fetchSoftwareProduct(dispatch, {softwareProductId, version}).then(response => { - if(!licensingVersion) { - licensingVersion = response[0].licensingVersion; - if (!licensingVersion) { - licensingVersion = {id: '1.0', label: '1.0'}; - } - } - if (!licenseModelId) { - licenseModelId = response[0].vendorId; - } - - const newVersion = response[0].version ? response[0].version : version; - + let {vendorId: licenseModelId, licensingVersion} = response[0]; SoftwareProductActionHelper.loadSoftwareProductDetailsData(dispatch, {licenseModelId, licensingVersion}); - - SoftwareProductComponentsActionHelper.fetchSoftwareProductComponents(dispatch, {softwareProductId, version: newVersion}); + SoftwareProductComponentsActionHelper.fetchSoftwareProductComponents(dispatch, {softwareProductId, version: version}); if(response[0].onboardingOrigin === onboardingOriginTypes.ZIP) { - SoftwareProductActionHelper.loadSoftwareProductHeatCandidate(dispatch, {softwareProductId, version: newVersion}); + SoftwareProductActionHelper.loadSoftwareProductHeatCandidate(dispatch, {softwareProductId, version: version}); } - setCurrentScreen(dispatch, enums.SCREEN.SOFTWARE_PRODUCT_LANDING_PAGE, {softwareProductId, licenseModelId, version: newVersion}); + setCurrentScreen(dispatch, enums.SCREEN.SOFTWARE_PRODUCT_LANDING_PAGE, {softwareProductId, licenseModelId, version}); }); }, navigateToSoftwareProductDetails(dispatch, {softwareProductId, version}) { - SoftwareProductActionHelper.fetchSoftwareProduct(dispatch, {softwareProductId, version}); - setCurrentScreen(dispatch, enums.SCREEN.SOFTWARE_PRODUCT_DETAILS, {softwareProductId, version}); + SoftwareProductActionHelper.fetchSoftwareProduct(dispatch, {softwareProductId, version}).then(response => { + let {vendorId: licenseModelId, licensingVersion} = response[0]; + SoftwareProductActionHelper.loadLicensingVersionsList(dispatch, {licenseModelId}); + SoftwareProductActionHelper.loadSoftwareProductDetailsData(dispatch, {licenseModelId, licensingVersion}); + setCurrentScreen(dispatch, enums.SCREEN.SOFTWARE_PRODUCT_DETAILS, {softwareProductId, version}); + }); }, navigateToSoftwareProductAttachmentsSetupTab(dispatch, {softwareProductId, version}) { @@ -183,7 +162,6 @@ export default { SoftwareProductAttachmentsActionHelper.setActiveTab(dispatch, {activeTab: attachmentsTabsMapping.SETUP}); setCurrentScreen(dispatch, enums.SCREEN.SOFTWARE_PRODUCT_ATTACHMENTS, {softwareProductId, version}); }, - navigateToSoftwareProductAttachmentsValidationTab(dispatch, {softwareProductId, version}) { SoftwareProductActionHelper.processAndValidateHeatCandidate(dispatch, {softwareProductId, version}).then(() => { SoftwareProductAttachmentsActionHelper.setActiveTab(dispatch, {activeTab: attachmentsTabsMapping.VALIDATION}); @@ -206,8 +184,15 @@ export default { }, navigateToSoftwareProductDependencies(dispatch, {softwareProductId, version}) { - SoftwareProductDependenciesActionHelper.fetchDependencies(dispatch, {softwareProductId, version}); - setCurrentScreen(dispatch, enums.SCREEN.SOFTWARE_PRODUCT_DEPENDENCIES, {softwareProductId, version}); + SoftwareProductComponentsActionHelper.fetchSoftwareProductComponents(dispatch, {softwareProductId, version}).then(result => { + if(result.listCount >= 2) { + SoftwareProductDependenciesActionHelper.fetchDependencies(dispatch, {softwareProductId, version}); + setCurrentScreen(dispatch, enums.SCREEN.SOFTWARE_PRODUCT_DEPENDENCIES, {softwareProductId, version}); + } + else { + this.navigateToSoftwareProductLandingPage(dispatch, {softwareProductId, version}); + } + }); }, navigateToSoftwareProductComponents(dispatch, {softwareProductId, version}) { @@ -268,8 +253,8 @@ export default { dispatch({ type: SoftwareProductActionTypes.TOGGLE_NAVIGATION_ITEM, mapOfExpandedIds: { - [SoftwareProductNavigationItems.COMPONENTS]: true, - [SoftwareProductNavigationItems.COMPONENTS + '|' + componentId]: true + [enums.SCREEN.SOFTWARE_PRODUCT_COMPONENTS]: true, + [enums.SCREEN.SOFTWARE_PRODUCT_COMPONENTS + '|' + componentId]: true } }); }, @@ -288,11 +273,44 @@ export default { setCurrentScreen(dispatch, enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_IMAGES, {softwareProductId, version, componentId}); }, + navigateToVersionsPage(dispatch, {itemType, itemId, itemName, additionalProps, users}) { + PermissionsActionHelper.fetchItemUsers(dispatch, {itemId, allUsers: users}); + VersionsPageActionHelper.selectNone(dispatch); + VersionsPageActionHelper.fetchVersions(dispatch, {itemType, itemId}).then(() => { + setCurrentScreen(dispatch, enums.SCREEN.VERSIONS_PAGE, {itemType, itemId, itemName, additionalProps}); + }); + }, + + checkMergeStatus(dispatch, {itemId, versionId, version}) { + return ItemsHelper.fetchVersion({itemId, versionId}).then(response => { + let state = response && response.state || {}; + let {synchronizationState} = state; + // let inMerge = synchronizationState === SyncStates.MERGE; + MergeEditorActionHelper.fetchConflicts(dispatch, {itemId, version}).then(data => { + dispatch({ + type: actionTypes.CHECK_MERGE_STATUS, + synchronizationState, + conflictInfoList: data.conflictInfoList + }); + }); + }); + }, + + forceBreadCrumbsUpdate(dispatch) { + dispatch({ + type: actionTypes.SET_CURRENT_SCREEN, + currentScreen: { + forceBreadCrumbsUpdate: true + } + }); + }, + updateCurrentScreenVersion(dispatch, version) { dispatch({ type: actionTypes.SET_CURRENT_SCREEN_VERSION, version }); } - }; + +export default OnboardingActionHelper; diff --git a/openecomp-ui/src/sdc-app/onboarding/OnboardingConstants.js b/openecomp-ui/src/sdc-app/onboarding/OnboardingConstants.js index 1ce8605b63..5b33fc2099 100644 --- a/openecomp-ui/src/sdc-app/onboarding/OnboardingConstants.js +++ b/openecomp-ui/src/sdc-app/onboarding/OnboardingConstants.js @@ -21,63 +21,80 @@ export const actionTypes = keyMirror({ SET_CURRENT_SCREEN: null, SET_CURRENT_LICENSE_MODEL: null, SET_CURRENT_SCREEN_VERSION: null, + UPDATE_CURRENT_SCREEN_PROPS: null, + UPDATE_ITEM_STATUS: null }); -export const enums = keyMirror({ +export const screenTypes = keyMirror({ + LICENSE_MODEL: null, + SOFTWARE_PRODUCT: null, + SOFTWARE_PRODUCT_COMPONENT_DEFAULT_GENERAL: null +}); + +const breadcrumbsEnum = { + LICENSE_MODEL: 'LICENSE_MODEL', + VERSIONS_PAGE: 'VERSIONS_PAGE', + LICENSE_MODEL_OVERVIEW: 'LICENSE_MODEL_OVERVIEW', + LICENSE_AGREEMENTS: 'LICENSE_AGREEMENTS', + FEATURE_GROUPS: 'FEATURE_GROUPS', + ENTITLEMENT_POOLS: 'ENTITLEMENT_POOLS', + LICENSE_KEY_GROUPS: 'LICENSE_KEY_GROUPS', + ACTIVITY_LOG: 'ACTIVITY_LOG', - BREADCRUMS: { - LICENSE_MODEL: 'LICENSE_MODEL', - LICENSE_MODEL_OVERVIEW: 'LICENSE_MODEL_OVERVIEW', - LICENSE_AGREEMENTS: 'LICENSE_AGREEMENTS', - FEATURE_GROUPS: 'FEATURE_GROUPS', - ENTITLEMENT_POOLS: 'ENTITLEMENT_POOLS', - LICENSE_KEY_GROUPS: 'LICENSE_KEY_GROUPS', - ACTIVITY_LOG: 'ACTIVITY_LOG', + SOFTWARE_PRODUCT: 'SOFTWARE_PRODUCT', + SOFTWARE_PRODUCT_VERSIONS_PAGE: 'SOFTWARE_PRODUCT_VERSIONS_PAGE', + SOFTWARE_PRODUCT_LANDING_PAGE: 'SOFTWARE_PRODUCT_LANDING_PAGE', + SOFTWARE_PRODUCT_DETAILS: 'SOFTWARE_PRODUCT_DETAILS', + SOFTWARE_PRODUCT_ATTACHMENTS: 'SOFTWARE_PRODUCT_ATTACHMENTS', + SOFTWARE_PRODUCT_PROCESSES: 'SOFTWARE_PRODUCT_PROCESSES', + SOFTWARE_PRODUCT_DEPLOYMENT: 'SOFTWARE_PRODUCT_DEPLOYMENT', + SOFTWARE_PRODUCT_NETWORKS: 'SOFTWARE_PRODUCT_NETWORKS', + SOFTWARE_PRODUCT_DEPENDENCIES: 'SOFTWARE_PRODUCT_DEPENDENCIES', + SOFTWARE_PRODUCT_ACTIVITY_LOG: 'SOFTWARE_PRODUCT_ACTIVITY_LOG', + SOFTWARE_PRODUCT_COMPONENTS: 'SOFTWARE_PRODUCT_COMPONENTS', + SOFTWARE_PRODUCT_COMPONENT_PROCESSES: 'SOFTWARE_PRODUCT_COMPONENT_PROCESSES', + SOFTWARE_PRODUCT_COMPONENT_NETWORK: 'SOFTWARE_PRODUCT_COMPONENT_NETWORK', + SOFTWARE_PRODUCT_COMPONENT_STORAGE: 'SOFTWARE_PRODUCT_COMPONENT_STORAGE', + SOFTWARE_PRODUCT_COMPONENT_GENERAL: 'SOFTWARE_PRODUCT_COMPONENT_GENERAL', + SOFTWARE_PRODUCT_COMPONENT_COMPUTE: 'SOFTWARE_PRODUCT_COMPONENT_COMPUTE', + SOFTWARE_PRODUCT_COMPONENT_LOAD_BALANCING: 'SOFTWARE_PRODUCT_COMPONENT_LOAD_BALANCING', + SOFTWARE_PRODUCT_COMPONENT_MONITORING: 'SOFTWARE_PRODUCT_COMPONENT_MONITORING', + SOFTWARE_PRODUCT_COMPONENT_IMAGES: 'SOFTWARE_PRODUCT_COMPONENT_IMAGES' +}; + +export const enums = keyMirror({ - SOFTWARE_PRODUCT: 'SOFTWARE_PRODUCT', - SOFTWARE_PRODUCT_LANDING_PAGE: 'SOFTWARE_PRODUCT_LANDING_PAGE', - SOFTWARE_PRODUCT_DETAILS: 'SOFTWARE_PRODUCT_DETAILS', - SOFTWARE_PRODUCT_ATTACHMENTS: 'SOFTWARE_PRODUCT_ATTACHMENTS', - SOFTWARE_PRODUCT_PROCESSES: 'SOFTWARE_PRODUCT_PROCESSES', - SOFTWARE_PRODUCT_DEPLOYMENT: 'SOFTWARE_PRODUCT_DEPLOYMENT', - SOFTWARE_PRODUCT_NETWORKS: 'SOFTWARE_PRODUCT_NETWORKS', - SOFTWARE_PRODUCT_DEPENDENCIES: 'SOFTWARE_PRODUCT_DEPENDENCIES', - SOFTWARE_PRODUCT_ACTIVITY_LOG: 'SOFTWARE_PRODUCT_ACTIVITY_LOG', - SOFTWARE_PRODUCT_COMPONENTS: 'SOFTWARE_PRODUCT_COMPONENTS', - SOFTWARE_PRODUCT_COMPONENT_PROCESSES: 'SOFTWARE_PRODUCT_COMPONENT_PROCESSES', - SOFTWARE_PRODUCT_COMPONENT_STORAGE: 'SOFTWARE_PRODUCT_COMPONENT_STORAGE', - SOFTWARE_PRODUCT_COMPONENT_GENERAL: 'SOFTWARE_PRODUCT_COMPONENT_GENERAL', - SOFTWARE_PRODUCT_COMPONENT_COMPUTE: 'SOFTWARE_PRODUCT_COMPONENT_COMPUTE', - SOFTWARE_PRODUCT_COMPONENT_LOAD_BALANCING: 'SOFTWARE_PRODUCT_COMPONENT_LOAD_BALANCING', - SOFTWARE_PRODUCT_COMPONENT_MONITORING: 'SOFTWARE_PRODUCT_COMPONENT_MONITORING', - SOFTWARE_PRODUCT_COMPONENT_IMAGES: 'SOFTWARE_PRODUCT_COMPONENT_IMAGES' - }, + BREADCRUMS: {...breadcrumbsEnum}, SCREEN: { - ONBOARDING_CATALOG: null, - LICENSE_MODEL_OVERVIEW: null, - LICENSE_AGREEMENTS: null, - FEATURE_GROUPS: null, - ENTITLEMENT_POOLS: null, - LICENSE_KEY_GROUPS: null, - ACTIVITY_LOG: null, + ONBOARDING_CATALOG: 'ONBOARDING_CATALOG', + VERSIONS_PAGE: breadcrumbsEnum.VERSIONS_PAGE, + LICENSE_MODEL_OVERVIEW: breadcrumbsEnum.LICENSE_MODEL_OVERVIEW, + LICENSE_AGREEMENTS: breadcrumbsEnum.LICENSE_AGREEMENTS, + FEATURE_GROUPS: breadcrumbsEnum.FEATURE_GROUPS, + ENTITLEMENT_POOLS: breadcrumbsEnum.ENTITLEMENT_POOLS, + LICENSE_KEY_GROUPS: breadcrumbsEnum.LICENSE_KEY_GROUPS, + ACTIVITY_LOG: breadcrumbsEnum.ACTIVITY_LOG, - SOFTWARE_PRODUCT_LANDING_PAGE: null, - SOFTWARE_PRODUCT_DETAILS: null, - SOFTWARE_PRODUCT_ATTACHMENTS: null, - SOFTWARE_PRODUCT_PROCESSES: null, - SOFTWARE_PRODUCT_DEPLOYMENT: null, - SOFTWARE_PRODUCT_NETWORKS: null, - SOFTWARE_PRODUCT_DEPENDENCIES: null, - SOFTWARE_PRODUCT_ACTIVITY_LOG: null, - SOFTWARE_PRODUCT_COMPONENTS: null, - SOFTWARE_PRODUCT_COMPONENT_PROCESSES: null, - SOFTWARE_PRODUCT_COMPONENT_COMPUTE: null, - SOFTWARE_PRODUCT_COMPONENT_STORAGE: null, - SOFTWARE_PRODUCT_COMPONENT_NETWORK: null, - SOFTWARE_PRODUCT_COMPONENT_GENERAL: null, - SOFTWARE_PRODUCT_COMPONENT_LOAD_BALANCING: null, - SOFTWARE_PRODUCT_COMPONENT_MONITORING: null, - SOFTWARE_PRODUCT_COMPONENT_IMAGES: null + SOFTWARE_PRODUCT_VERSIONS_PAGE: breadcrumbsEnum.SOFTWARE_PRODUCT_VERSIONS_PAGE, + SOFTWARE_PRODUCT_LANDING_PAGE: breadcrumbsEnum.SOFTWARE_PRODUCT_LANDING_PAGE, + SOFTWARE_PRODUCT_DETAILS: breadcrumbsEnum.SOFTWARE_PRODUCT_DETAILS, + SOFTWARE_PRODUCT_ATTACHMENTS: breadcrumbsEnum.SOFTWARE_PRODUCT_ATTACHMENTS, + SOFTWARE_PRODUCT_ATTACHMENTS_SETUP: 'SOFTWARE_PRODUCT_ATTACHMENTS_SETUP', + SOFTWARE_PRODUCT_ATTACHMENTS_VALIDATION: 'SOFTWARE_PRODUCT_ATTACHMENTS_VALIDATION', + SOFTWARE_PRODUCT_PROCESSES: breadcrumbsEnum.SOFTWARE_PRODUCT_PROCESSES, + SOFTWARE_PRODUCT_DEPLOYMENT: breadcrumbsEnum.SOFTWARE_PRODUCT_DEPLOYMENT, + SOFTWARE_PRODUCT_NETWORKS: breadcrumbsEnum.SOFTWARE_PRODUCT_NETWORKS, + SOFTWARE_PRODUCT_DEPENDENCIES: breadcrumbsEnum.SOFTWARE_PRODUCT_DEPENDENCIES, + SOFTWARE_PRODUCT_ACTIVITY_LOG: breadcrumbsEnum.SOFTWARE_PRODUCT_ACTIVITY_LOG, + SOFTWARE_PRODUCT_COMPONENTS: breadcrumbsEnum.SOFTWARE_PRODUCT_COMPONENTS, + SOFTWARE_PRODUCT_COMPONENT_PROCESSES: breadcrumbsEnum.SOFTWARE_PRODUCT_COMPONENT_PROCESSES, + SOFTWARE_PRODUCT_COMPONENT_COMPUTE: breadcrumbsEnum.SOFTWARE_PRODUCT_COMPONENT_COMPUTE, + SOFTWARE_PRODUCT_COMPONENT_STORAGE: breadcrumbsEnum.SOFTWARE_PRODUCT_COMPONENT_STORAGE, + SOFTWARE_PRODUCT_COMPONENT_NETWORK: breadcrumbsEnum.SOFTWARE_PRODUCT_COMPONENT_NETWORK, + SOFTWARE_PRODUCT_COMPONENT_GENERAL: breadcrumbsEnum.SOFTWARE_PRODUCT_COMPONENT_GENERAL, + SOFTWARE_PRODUCT_COMPONENT_LOAD_BALANCING: breadcrumbsEnum.SOFTWARE_PRODUCT_COMPONENT_LOAD_BALANCING, + SOFTWARE_PRODUCT_COMPONENT_MONITORING: breadcrumbsEnum.SOFTWARE_PRODUCT_COMPONENT_MONITORING, + SOFTWARE_PRODUCT_COMPONENT_IMAGES: breadcrumbsEnum.SOFTWARE_PRODUCT_COMPONENT_IMAGES } }); diff --git a/openecomp-ui/src/sdc-app/onboarding/OnboardingPunchOut.jsx b/openecomp-ui/src/sdc-app/onboarding/OnboardingPunchOut.jsx index c1f3251281..905712003a 100644 --- a/openecomp-ui/src/sdc-app/onboarding/OnboardingPunchOut.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/OnboardingPunchOut.jsx @@ -14,6 +14,7 @@ * permissions and limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import ReactDOM from 'react-dom'; import {connect} from 'react-redux'; import isEqual from 'lodash/isEqual.js'; @@ -23,8 +24,10 @@ import i18n from 'nfvo-utils/i18n/i18n.js'; import Application from 'sdc-app/Application.jsx'; import store from 'sdc-app/AppStore.js'; import Configuration from 'sdc-app/config/Configuration.js'; +import ScreensHelper from 'sdc-app/common/helpers/ScreensHelper.js'; import Onboard from './onboard/Onboard.js'; +import VersionsPage from './versionsPage/VersionsPage.js'; import LicenseModel from './licenseModel/LicenseModel.js'; import LicenseModelOverview from './licenseModel/overview/LicenseModelOverview.js'; import ActivityLog from 'sdc-app/common/activity-log/ActivityLog.js'; @@ -51,27 +54,21 @@ import SoftwareProductComponentsCompute from './softwareProduct/components/compu import SoftwareProductComponentLoadBalancing from './softwareProduct/components/loadBalancing/SoftwareProductComponentLoadBalancing.js'; import SoftwareProductComponentsImageList from './softwareProduct/components/images/SoftwareProductComponentsImageList.js'; import SoftwareProductComponentsMonitoring from './softwareProduct/components/monitoring/SoftwareProductComponentsMonitoring.js'; -import { - navigationItems as SoftwareProductNavigationItems, - onboardingMethod as onboardingMethodTypes, - actionTypes as SoftwareProductActionTypes, - onboardingOriginTypes -} from 'sdc-app/onboarding/softwareProduct/SoftwareProductConstants.js'; +import {onboardingMethod as onboardingMethodTypes, onboardingOriginTypes} from 'sdc-app/onboarding/softwareProduct/SoftwareProductConstants.js'; -import {statusEnum as VCItemStatus} from 'nfvo-components/panel/versionController/VersionControllerConstants.js'; -import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js'; +import {itemTypes} from './versionsPage/VersionsPageConstants.js'; import HeatSetupActionHelper from './softwareProduct/attachments/setup/HeatSetupActionHelper.js'; -import {actionTypes, enums} from './OnboardingConstants.js'; +import {actionTypes, enums, screenTypes} from './OnboardingConstants.js'; import OnboardingActionHelper from './OnboardingActionHelper.js'; - class OnboardingView extends React.Component { static propTypes = { - currentScreen: React.PropTypes.shape({ - screen: React.PropTypes.oneOf(objectValues(enums.SCREEN)).isRequired, - props: React.PropTypes.object.isRequired + currentScreen: PropTypes.shape({ + screen: PropTypes.oneOf(objectValues(enums.SCREEN)).isRequired, + props: PropTypes.object.isRequired, + itemPermission: PropTypes.object }).isRequired }; @@ -97,6 +94,8 @@ class OnboardingView extends React.Component { switch (screen) { case enums.SCREEN.ONBOARDING_CATALOG: return <Onboard {...props}/>; + case enums.SCREEN.VERSIONS_PAGE: + return <VersionsPage {...props} />; case enums.SCREEN.LICENSE_AGREEMENTS: case enums.SCREEN.FEATURE_GROUPS: @@ -106,24 +105,24 @@ class OnboardingView extends React.Component { case enums.SCREEN.ACTIVITY_LOG: return ( <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: - return <FeatureGroupListEditor {...props}/>; - case enums.SCREEN.ENTITLEMENT_POOLS: - return <EntitlementPoolsListEditor {...props}/>; - case enums.SCREEN.LICENSE_KEY_GROUPS: - return <LicenseKeyGroupsListEditor {...props}/>; - case enums.SCREEN.ACTIVITY_LOG: - return <ActivityLog {...props}/>; - } - })() - } + { + (()=>{ + switch(screen) { + case enums.SCREEN.LICENSE_MODEL_OVERVIEW: + return <LicenseModelOverview {...props}/>; + case enums.SCREEN.LICENSE_AGREEMENTS: + return <LicenseAgreementListEditor {...props}/>; + case enums.SCREEN.FEATURE_GROUPS: + return <FeatureGroupListEditor {...props}/>; + case enums.SCREEN.ENTITLEMENT_POOLS: + return <EntitlementPoolsListEditor {...props}/>; + case enums.SCREEN.LICENSE_KEY_GROUPS: + return <LicenseKeyGroupsListEditor {...props}/>; + case enums.SCREEN.ACTIVITY_LOG: + return <ActivityLog {...props}/>; + } + })() + } </LicenseModel> ); @@ -146,46 +145,46 @@ class OnboardingView extends React.Component { case enums.SCREEN.SOFTWARE_PRODUCT_ACTIVITY_LOG: return ( <SoftwareProduct currentScreen={currentScreen}> - { - (()=>{ - switch(screen) { - case enums.SCREEN.SOFTWARE_PRODUCT_LANDING_PAGE: - return <SoftwareProductLandingPage {...props}/>; - case enums.SCREEN.SOFTWARE_PRODUCT_DETAILS: - return <SoftwareProductDetails {...props}/>; - case enums.SCREEN.SOFTWARE_PRODUCT_ATTACHMENTS: - return <SoftwareProductAttachments className='no-padding-content-area' {...props} />; - case enums.SCREEN.SOFTWARE_PRODUCT_PROCESSES: - return <SoftwareProductProcesses {...props}/>; - case enums.SCREEN.SOFTWARE_PRODUCT_DEPLOYMENT: - return <SoftwareProductDeployment {...props}/>; - case enums.SCREEN.SOFTWARE_PRODUCT_NETWORKS: - return <SoftwareProductNetworks {...props}/>; - case enums.SCREEN.SOFTWARE_PRODUCT_DEPENDENCIES: - return <SoftwareProductDependencies {...props} />; - case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENTS: - return <SoftwareProductComponentsList {...props}/>; - case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_PROCESSES: - return <SoftwareProductComponentProcessesList {...props}/>; - case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_STORAGE: - return <SoftwareProductComponentStorage {...props}/>; - case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_NETWORK: - return <SoftwareProductComponentsNetworkList {...props}/>; - case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_GENERAL: - return <SoftwareProductComponentsGeneral{...props}/>; - case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_COMPUTE: - return <SoftwareProductComponentsCompute {...props}/>; - case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_LOAD_BALANCING: - return <SoftwareProductComponentLoadBalancing{...props}/>; - case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_IMAGES: - return <SoftwareProductComponentsImageList{...props}/>; - case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_MONITORING: - return <SoftwareProductComponentsMonitoring {...props}/>; - case enums.SCREEN.SOFTWARE_PRODUCT_ACTIVITY_LOG: - return <ActivityLog {...props}/>; - } - })() - } + { + (()=>{ + switch(screen) { + case enums.SCREEN.SOFTWARE_PRODUCT_LANDING_PAGE: + return <SoftwareProductLandingPage {...props}/>; + case enums.SCREEN.SOFTWARE_PRODUCT_DETAILS: + return <SoftwareProductDetails {...props}/>; + case enums.SCREEN.SOFTWARE_PRODUCT_ATTACHMENTS: + return <SoftwareProductAttachments className='no-padding-content-area' {...props} />; + case enums.SCREEN.SOFTWARE_PRODUCT_PROCESSES: + return <SoftwareProductProcesses {...props}/>; + case enums.SCREEN.SOFTWARE_PRODUCT_DEPLOYMENT: + return <SoftwareProductDeployment {...props}/>; + case enums.SCREEN.SOFTWARE_PRODUCT_NETWORKS: + return <SoftwareProductNetworks {...props}/>; + case enums.SCREEN.SOFTWARE_PRODUCT_DEPENDENCIES: + return <SoftwareProductDependencies {...props} />; + case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENTS: + return <SoftwareProductComponentsList {...props}/>; + case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_PROCESSES: + return <SoftwareProductComponentProcessesList {...props}/>; + case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_STORAGE: + return <SoftwareProductComponentStorage {...props}/>; + case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_NETWORK: + return <SoftwareProductComponentsNetworkList {...props}/>; + case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_GENERAL: + return <SoftwareProductComponentsGeneral{...props}/>; + case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_COMPUTE: + return <SoftwareProductComponentsCompute {...props}/>; + case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_LOAD_BALANCING: + return <SoftwareProductComponentLoadBalancing{...props}/>; + case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_IMAGES: + return <SoftwareProductComponentsImageList{...props}/>; + case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_MONITORING: + return <SoftwareProductComponentsMonitoring {...props}/>; + case enums.SCREEN.SOFTWARE_PRODUCT_ACTIVITY_LOG: + return <ActivityLog {...props}/>; + } + })() + } </SoftwareProduct> ); } @@ -234,10 +233,10 @@ export default class OnboardingPunchOut { handleData(data) { let {breadcrumbs: {selectedKeys = []} = {}} = data; let dispatch = action => store.dispatch(action); - let {currentScreen, softwareProductList, softwareProduct: {softwareProductEditor: {data: vspData = {}}, - softwareProductComponents = {}, softwareProductQuestionnaire = {}}, - licenseModelList, licenseModel: {licenseModelEditor: {data: {id: currentLicenseModelId, version: currentLicenseModelVersion} = {}}}} = store.getState(); - let {id: currentSoftwareProductId, version: currentSoftwareProductVersion} = vspData; + let {currentScreen, users: {usersList}, softwareProductList, licenseModelList, softwareProduct: {softwareProductEditor: {data: vspData = {}}, + softwareProductComponents = {}, softwareProductQuestionnaire = {}}} = store.getState(); + + let {props: {version, isReadOnlyMode}, screen} = currentScreen; let {componentEditor: {data: componentData = {}, qdata: componentQData = {}}} = softwareProductComponents; if (this.programmaticBreadcrumbsUpdate) { this.prevSelectedKeys = selectedKeys; @@ -249,11 +248,11 @@ export default class OnboardingPunchOut { const [, screenType, prevVspId, , prevComponentId] = this.prevSelectedKeys || []; let preNavigate = Promise.resolve(); - if(screenType === enums.BREADCRUMS.SOFTWARE_PRODUCT && vspData.status === VCItemStatus.CHECK_OUT_STATUS && VersionControllerUtils.isCheckedOutByCurrentUser(vspData)) { + if(screenType === enums.BREADCRUMS.SOFTWARE_PRODUCT && screen !== 'VERSIONS_PAGE' && !isReadOnlyMode) { let dataToSave = prevVspId ? prevComponentId ? {componentData, qdata: componentQData} : {softwareProduct: vspData, qdata: softwareProductQuestionnaire.qdata} : {}; preNavigate = OnboardingActionHelper.autoSaveBeforeNavigate(dispatch, { softwareProductId: prevVspId, - version: currentSoftwareProductVersion, + version, vspComponentId: prevComponentId, dataToSave }); @@ -261,40 +260,19 @@ export default class OnboardingPunchOut { let {currentScreen: {props: {softwareProductId}}, softwareProduct: {softwareProductAttachments: {heatSetup, heatSetupCache}}} = store.getState(); let heatSetupPopupPromise = currentScreen.screen === enums.SCREEN.SOFTWARE_PRODUCT_ATTACHMENTS ? - HeatSetupActionHelper.heatSetupLeaveConfirmation(dispatch, {softwareProductId, heatSetup, heatSetupCache}) : - Promise.resolve(); + HeatSetupActionHelper.heatSetupLeaveConfirmation(dispatch, {softwareProductId, heatSetup, heatSetupCache}) : + Promise.resolve(); Promise.all([preNavigate, heatSetupPopupPromise]).then(() => { this.prevSelectedKeys = selectedKeys; if (selectedKeys.length === 0) { - OnboardingActionHelper.navigateToOnboardingCatalog(dispatch); + ScreensHelper.loadScreen(dispatch, {screen: enums.SCREEN.ONBOARDING_CATALOG}); + } else if (selectedKeys.length === 1 || selectedKeys[1] === enums.BREADCRUMS.LICENSE_MODEL) { let [licenseModelId, , licenseModelScreen] = selectedKeys; - if (!licenseModelScreen) { - licenseModelScreen = enums.BREADCRUMS.LICENSE_MODEL_OVERVIEW; - } - if (currentLicenseModelId !== licenseModelId) { - currentLicenseModelVersion = licenseModelList.find(lm => lm.id === licenseModelId).version; - } - switch (licenseModelScreen) { - case enums.BREADCRUMS.LICENSE_MODEL_OVERVIEW: - OnboardingActionHelper.navigateToLicenseModelOverview(dispatch, {licenseModelId, version: currentLicenseModelVersion}); - break; - case enums.BREADCRUMS.LICENSE_AGREEMENTS: - OnboardingActionHelper.navigateToLicenseAgreements(dispatch, {licenseModelId, version: currentLicenseModelVersion}); - break; - case enums.BREADCRUMS.FEATURE_GROUPS: - OnboardingActionHelper.navigateToFeatureGroups(dispatch, {licenseModelId, version: currentLicenseModelVersion}); - break; - case enums.BREADCRUMS.ENTITLEMENT_POOLS: - OnboardingActionHelper.navigateToEntitlementPools(dispatch, {licenseModelId, version: currentLicenseModelVersion}); - break; - case enums.BREADCRUMS.LICENSE_KEY_GROUPS: - OnboardingActionHelper.navigateToLicenseKeyGroups(dispatch, {licenseModelId, version: currentLicenseModelVersion}); - break; - case enums.BREADCRUMS.ACTIVITY_LOG: - OnboardingActionHelper.navigateToLicenseModelActivityLog(dispatch, {licenseModelId, version: currentLicenseModelVersion}); - break; - } + let licenseModel = licenseModelList.find(vlm => vlm.id === licenseModelId); + ScreensHelper.loadScreen(dispatch, {screen: licenseModelScreen, screenType: screenTypes.LICENSE_MODEL, + props: {licenseModelId, version, licenseModel, usersList}}); + } else if (selectedKeys.length <= 4 && selectedKeys[1] === enums.BREADCRUMS.SOFTWARE_PRODUCT) { let [licenseModelId, , softwareProductId, softwareProductScreen] = selectedKeys; let softwareProduct = softwareProductId ? @@ -303,52 +281,20 @@ export default class OnboardingPunchOut { if (!softwareProductId) { softwareProductId = softwareProduct.id; } - if (currentSoftwareProductId !== softwareProductId) { - currentSoftwareProductVersion = softwareProduct.version; - } - switch (softwareProductScreen) { - case enums.BREADCRUMS.SOFTWARE_PRODUCT_LANDING_PAGE: - OnboardingActionHelper.navigateToSoftwareProductLandingPage(dispatch, {softwareProductId, version: currentSoftwareProductVersion}); - break; - case enums.BREADCRUMS.SOFTWARE_PRODUCT_DETAILS: - OnboardingActionHelper.navigateToSoftwareProductDetails(dispatch, {softwareProductId, version: currentSoftwareProductVersion}); - break; - case enums.BREADCRUMS.SOFTWARE_PRODUCT_ATTACHMENTS: - if(softwareProduct.onboardingOrigin === onboardingOriginTypes.ZIP) { - OnboardingActionHelper.navigateToSoftwareProductAttachmentsSetupTab(dispatch, {softwareProductId, version: currentSoftwareProductVersion}); - } - else if(softwareProduct.onboardingOrigin === onboardingOriginTypes.CSAR) { - OnboardingActionHelper.navigateToSoftwareProductAttachmentsValidationTab(dispatch, {softwareProductId, version: currentSoftwareProductVersion}); - } - break; - case enums.BREADCRUMS.SOFTWARE_PRODUCT_PROCESSES: - OnboardingActionHelper.navigateToSoftwareProductProcesses(dispatch, {softwareProductId, version: currentSoftwareProductVersion}); - break; - case enums.BREADCRUMS.SOFTWARE_PRODUCT_DEPLOYMENT: - OnboardingActionHelper.navigateToSoftwareProductDeployment(dispatch, {softwareProductId, version: currentSoftwareProductVersion}); - break; - case enums.BREADCRUMS.SOFTWARE_PRODUCT_NETWORKS: - OnboardingActionHelper.navigateToSoftwareProductNetworks(dispatch, {softwareProductId, version: currentSoftwareProductVersion}); - break; - case enums.BREADCRUMS.SOFTWARE_PRODUCT_DEPENDENCIES: - OnboardingActionHelper.navigateToSoftwareProductDependencies(dispatch, {softwareProductId, version: currentSoftwareProductVersion}); - break; - case enums.BREADCRUMS.SOFTWARE_PRODUCT_ACTIVITY_LOG: - OnboardingActionHelper.navigateToSoftwareProductActivityLog(dispatch, {softwareProductId, version: currentSoftwareProductVersion}); - break; - case enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENTS: - OnboardingActionHelper.navigateToSoftwareProductComponents(dispatch, {softwareProductId, version: currentSoftwareProductVersion}); - dispatch({ - type: SoftwareProductActionTypes.TOGGLE_NAVIGATION_ITEM, - mapOfExpandedIds: { - [SoftwareProductNavigationItems.COMPONENTS]: true - } - }); - break; - default: - OnboardingActionHelper.navigateToSoftwareProductLandingPage(dispatch, {softwareProductId, version: currentSoftwareProductVersion}); - break; + if (softwareProductScreen === enums.SCREEN.SOFTWARE_PRODUCT_ATTACHMENTS) { + softwareProduct = vspData; + //check current vsp fields to determine which file has uploaded + if(vspData.onboardingOrigin === onboardingOriginTypes.ZIP || vspData.candidateOnboardingOrigin === onboardingOriginTypes.ZIP) { + softwareProductScreen = enums.SCREEN.SOFTWARE_PRODUCT_ATTACHMENTS_SETUP; + } + else if(vspData.onboardingOrigin === onboardingOriginTypes.CSAR) { + softwareProductScreen = enums.SCREEN.SOFTWARE_PRODUCT_ATTACHMENTS_VALIDATION; + } } + + ScreensHelper.loadScreen(dispatch, {screen: softwareProductScreen, screenType: screenTypes.SOFTWARE_PRODUCT, + props: {softwareProductId, softwareProduct, version, usersList}}); + } else if (selectedKeys.length === 5 && selectedKeys[1] === enums.BREADCRUMS.SOFTWARE_PRODUCT && selectedKeys[3] === enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENTS) { let [licenseModelId, , softwareProductId, , componentId] = selectedKeys; let softwareProduct = softwareProductId ? @@ -357,10 +303,9 @@ export default class OnboardingPunchOut { if (!softwareProductId) { softwareProductId = softwareProduct.id; } - if (currentSoftwareProductId !== softwareProductId) { - currentSoftwareProductVersion = softwareProduct.version; - } - OnboardingActionHelper.navigateToSoftwareProductComponentGeneralAndUpdateLeftPanel(dispatch, {softwareProductId, componentId, version: currentSoftwareProductVersion}); + ScreensHelper.loadScreen(dispatch, {screen: enums.SCREEN.SOFTWARE_PRODUCT_COMPONENTS, screenType: screenTypes.SOFTWARE_PRODUCT, + props: {softwareProductId, softwareProduct, componentId, version, usersList}}); + } else if (selectedKeys.length === 6 && selectedKeys[1] === enums.BREADCRUMS.SOFTWARE_PRODUCT && selectedKeys[3] === enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENTS) { let [licenseModelId, , softwareProductId, , componentId, componentScreen] = selectedKeys; let softwareProduct = softwareProductId ? @@ -369,39 +314,9 @@ export default class OnboardingPunchOut { if (!softwareProductId) { softwareProductId = softwareProduct.id; } - if (currentSoftwareProductId !== softwareProductId) { - currentSoftwareProductVersion = softwareProduct.version; - } - switch (componentScreen) { - case enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENT_GENERAL: - OnboardingActionHelper.navigateToSoftwareProductComponentGeneral(dispatch, {softwareProductId, componentId, version: currentSoftwareProductVersion}); - break; - case enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENT_COMPUTE: - OnboardingActionHelper.navigateToComponentCompute(dispatch, {softwareProductId, componentId, version: currentSoftwareProductVersion}); - break; - case enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENT_LOAD_BALANCING: - OnboardingActionHelper.navigateToComponentLoadBalancing(dispatch, {softwareProductId, componentId, version: currentSoftwareProductVersion}); - break; - case enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENT_NETWORK: - OnboardingActionHelper.navigateToComponentNetwork(dispatch, {softwareProductId, componentId, version: currentSoftwareProductVersion}); - break; - case enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENT_STORAGE: - OnboardingActionHelper.navigateToComponentStorage(dispatch, {softwareProductId, componentId, version: currentSoftwareProductVersion}); - break; - case enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENT_PROCESSES: - OnboardingActionHelper.navigateToSoftwareProductComponentProcesses(dispatch, {softwareProductId, componentId, version: currentSoftwareProductVersion}); - break; - case enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENT_MONITORING: - OnboardingActionHelper.navigateToSoftwareProductComponentMonitoring(dispatch, {softwareProductId, componentId, version: currentSoftwareProductVersion}); - break; - case enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENT_IMAGES: - OnboardingActionHelper.navigateToComponentImages(dispatch, { - softwareProductId, - componentId, - version: currentSoftwareProductVersion - }); - break; - } + ScreensHelper.loadScreen(dispatch, {screen: componentScreen, screenType: screenTypes.SOFTWARE_PRODUCT, + props: {softwareProductId, softwareProduct, componentId, version, usersList}}); + } else { console.error('Unknown breadcrumbs path: ', selectedKeys); } @@ -418,11 +333,14 @@ export default class OnboardingPunchOut { } handleStoreChange() { - let {currentScreen, licenseModelList, softwareProductList, - softwareProduct: {softwareProductEditor: {data = {onboardingMethod: ''}}, + let {currentScreen, licenseModelList, finalizedLicenseModelList, softwareProductList, finalizedSoftwareProductList, versionsPage: + {versionsList: {itemType, itemId}}, + softwareProduct: {softwareProductEditor: {data: currentSoftwareProduct = {onboardingMethod: ''}}, softwareProductComponents: {componentsList}}} = store.getState(); - let {onboardingMethod, onboardingOrigin} = data; - let breadcrumbsData = {onboardingMethod, currentScreen, licenseModelList, softwareProductList, componentsList, onboardingOrigin}; + const wholeSoftwareProductList = [...softwareProductList, ...finalizedSoftwareProductList]; + const wholeLicenseModelList = [...licenseModelList, ...finalizedLicenseModelList]; + let breadcrumbsData = {itemType, itemId, currentScreen, wholeLicenseModelList, wholeSoftwareProductList, currentSoftwareProduct, componentsList}; + if (currentScreen.forceBreadCrumbsUpdate || !isEqual(breadcrumbsData, this.prevBreadcrumbsData) || this.breadcrumbsPrefixSelected) { this.prevBreadcrumbsData = breadcrumbsData; this.breadcrumbsPrefixSelected = false; @@ -439,12 +357,58 @@ export default class OnboardingPunchOut { } } - buildBreadcrumbs({currentScreen: {screen, props}, onboardingMethod, licenseModelList, softwareProductList, componentsList, onboardingOrigin}) { + buildBreadcrumbs({currentScreen: {screen, props}, itemType, itemId, currentSoftwareProduct, + wholeLicenseModelList, wholeSoftwareProductList, componentsList}) { + let {onboardingMethod, onboardingOrigin, candidateOnboardingOrigin} = currentSoftwareProduct; let screenToBreadcrumb; switch (screen) { case enums.SCREEN.ONBOARDING_CATALOG: return []; + case enums.SCREEN.VERSIONS_PAGE: + let firstMenuItems = itemType === itemTypes.LICENSE_MODEL ? [ + { + selectedKey: itemId, + menuItems: wholeLicenseModelList.map(({id, name}) => ({ + key: id, + displayText: name + })) + }] : [ + { + selectedKey: props.additionalProps.licenseModelId || currentSoftwareProduct.vendorId, + menuItems: wholeLicenseModelList.map(({id, name}) => ({ + key: id, + displayText: name + })) + }, + { + selectedKey: enums.BREADCRUMS.SOFTWARE_PRODUCT, + menuItems: [{ + key: enums.BREADCRUMS.LICENSE_MODEL, + displayText: i18n('License Model') + }, { + key: enums.BREADCRUMS.SOFTWARE_PRODUCT, + displayText: i18n('Software Products') + }] + }, + { + selectedKey: itemId, + menuItems: wholeSoftwareProductList + .filter(({id, vendorId}) => vendorId === currentSoftwareProduct.vendorId || id === itemId) + .map(({id, name}) => ({ + key: id, + displayText: name + })) + }, + ]; + return [ + ...firstMenuItems, + { + selectedKey: enums.BREADCRUMS.VERSIONS_PAGE, + menuItems: [{key: enums.BREADCRUMS.VERSIONS_PAGE, displayText: i18n('Versions Page')}] + } + ]; + case enums.SCREEN.LICENSE_AGREEMENTS: case enums.SCREEN.FEATURE_GROUPS: case enums.SCREEN.ENTITLEMENT_POOLS: @@ -462,9 +426,9 @@ export default class OnboardingPunchOut { return [ { selectedKey: props.licenseModelId, - menuItems: licenseModelList.map(({id, vendorName}) => ({ + menuItems: wholeLicenseModelList.map(({id, name}) => ({ key: id, - displayText: vendorName + displayText: name })) }, { @@ -473,10 +437,10 @@ export default class OnboardingPunchOut { key: enums.BREADCRUMS.LICENSE_MODEL, displayText: i18n('License Model') }, - ...(softwareProductList.findIndex(({vendorId}) => vendorId === props.licenseModelId) === -1 ? [] : [{ - key: enums.BREADCRUMS.SOFTWARE_PRODUCT, - displayText: i18n('Software Products') - }])] + ...(wholeSoftwareProductList.findIndex(({vendorId}) => vendorId === props.licenseModelId) === -1 ? [] : [{ + key: enums.BREADCRUMS.SOFTWARE_PRODUCT, + displayText: i18n('Software Products') + }])] }, { selectedKey: screenToBreadcrumb[screen], menuItems: [{ @@ -540,13 +504,13 @@ export default class OnboardingPunchOut { [enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_IMAGES]: enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENT_IMAGES, [enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_MONITORING]: enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENT_MONITORING }; - let licenseModelId = softwareProductList.find(({id}) => id === props.softwareProductId).vendorId; + let licenseModelId = currentSoftwareProduct.vendorId; let returnedBreadcrumb = [ { selectedKey: licenseModelId, - menuItems: licenseModelList.map(({id, vendorName}) => ({ + menuItems: wholeLicenseModelList.map(({id, name}) => ({ key: id, - displayText: vendorName + displayText: name })) }, { @@ -561,8 +525,8 @@ export default class OnboardingPunchOut { }, { selectedKey: props.softwareProductId, - menuItems: softwareProductList - .filter(({vendorId}) => vendorId === licenseModelId) + menuItems: wholeSoftwareProductList + .filter(({vendorId, id}) => vendorId === licenseModelId || id === props.softwareProductId) .map(({id, name}) => ({ key: id, displayText: name @@ -598,14 +562,14 @@ export default class OnboardingPunchOut { key: enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENTS, displayText: i18n('Components') }].filter(item => { - let isHeatData = onboardingOrigin !== onboardingOriginTypes.NONE; - let isManualMode = onboardingMethod === onboardingMethodTypes.MANUAL; switch (item.key) { case enums.BREADCRUMS.SOFTWARE_PRODUCT_ATTACHMENTS: + let isHeatData = onboardingOrigin !== onboardingOriginTypes.NONE || candidateOnboardingOrigin === onboardingOriginTypes.ZIP; return isHeatData; case enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENTS: return (componentsList.length > 0); case enums.BREADCRUMS.SOFTWARE_PRODUCT_DEPLOYMENT: + let isManualMode = onboardingMethod === onboardingMethodTypes.MANUAL; return isManualMode; case enums.BREADCRUMS.SOFTWARE_PRODUCT_DEPENDENCIES: return (componentsList.length > 1); diff --git a/openecomp-ui/src/sdc-app/onboarding/OnboardingReducers.js b/openecomp-ui/src/sdc-app/onboarding/OnboardingReducers.js index e63bcb16af..2eb455f9dd 100644 --- a/openecomp-ui/src/sdc-app/onboarding/OnboardingReducers.js +++ b/openecomp-ui/src/sdc-app/onboarding/OnboardingReducers.js @@ -14,21 +14,127 @@ * permissions and limitations under the License. */ import {actionTypes, enums} from './OnboardingConstants.js'; +import {actionTypes as permissionActionTypes} from './permissions/PermissionsConstants.js'; +import {actionTypes as licenseModelCreateActionTypes} from './licenseModel/creation/LicenseModelCreationConstants.js'; +import {actionTypes as softwareProductCreateActionTypes} from './softwareProduct/creation/SoftwareProductCreationConstants.js'; +import {actionTypes as versionCreateActionTypes} from './versionsPage/creation/VersionsPageCreationConstants.js'; +import {SyncStates} from 'sdc-app/common/merge/MergeEditorConstants.js'; + +import {catalogItemStatuses} from './onboard/onboardingCatalog/OnboardingCatalogConstants.js'; +import Configuration from 'sdc-app/config/Configuration.js'; + +const checkReadOnly = ({isCollaborator = true, inMerge = false, isCertified = false}) => !isCollaborator || inMerge || isCertified; + +const currentScreen = (state = { + forceBreadCrumbsUpdate: false, + screen: enums.SCREEN.ONBOARDING_CATALOG, + itemPermission: {}, + props: {} +}, action) => { -export const currentScreenReducer = (state = {forceBreadCrumbsUpdate: false, screen: enums.SCREEN.ONBOARDING_CATALOG, props: {}}, action) => { switch (action.type) { - case actionTypes.SET_CURRENT_SCREEN: - return action.currentScreen; + + case actionTypes.SET_CURRENT_SCREEN: { + let itemPermission = {...state.itemPermission}; + let {currentScreen} = action; + + if (currentScreen.props.version) { + let {status} = currentScreen.props.version; + itemPermission.isCertified = itemPermission.isCertified && status === catalogItemStatuses.CERTIFIED; + } + + let isReadOnlyMode = checkReadOnly(itemPermission); + let props = {...currentScreen.props, isReadOnlyMode}; + + return { + ...state, + ...currentScreen, + itemPermission, + props + }; + } + + case actionTypes.UPDATE_CURRENT_SCREEN_PROPS: + return { + ...state, + props: { + ...state.props, + ...action.props, + isReadOnlyMode: checkReadOnly(state.itemPermission) + } + }; + case actionTypes.SET_CURRENT_SCREEN_VERSION: return { ...state, props: { ...state.props, - version: action.version + version: action.version, + isReadOnlyMode: checkReadOnly(state.itemPermission) } - }; + }; + + case licenseModelCreateActionTypes.LICENSE_MODEL_CREATED: + case softwareProductCreateActionTypes.SOFTWARE_PRODUCT_CREATED: + case versionCreateActionTypes.VERSION_CREATED: + return { + ...state, + itemPermission: { + isCollaborator: true, + inMerge: false, + isCertified: false + }, + props: { + ...state.props, + isReadOnlyMode: false + } + }; + + case permissionActionTypes.ITEM_USERS_LOADED: { + let userId = Configuration.get('UserID'); + let isCollaborator = false; + + if (userId === action.owner.userId) { + isCollaborator = true; + } else { + isCollaborator = action.contributors.reduce( + (foundUser, contributor) => foundUser || contributor.userId === userId, false + ); + } + + let itemPermission = {...state.itemPermission, isCollaborator}; + let isReadOnlyMode = checkReadOnly(itemPermission); + let props = {...state.props, isReadOnlyMode}; + + return { + ...state, + itemPermission, + props + }; + } + + case actionTypes.UPDATE_ITEM_STATUS: { + const {itemState: {synchronizationState, dirty}, itemStatus, updatedVersion} = action; + const inMerge = synchronizationState === SyncStates.MERGE; + const isOutOfSync = synchronizationState === SyncStates.OUT_OF_SYNC; + const isUpToDate = synchronizationState === SyncStates.UP_TO_DATE; + const isCertified = itemStatus === catalogItemStatuses.CERTIFIED; + const itemPermission = {...state.itemPermission, inMerge, isDirty: dirty, isOutOfSync, isUpToDate, isCertified}; + const isReadOnlyMode = checkReadOnly(itemPermission); + const props = {...state.props, isReadOnlyMode, version: {...state.props.version, ...updatedVersion}}; + + return { + ...state, + itemPermission, + props + }; + } + default: return state; - } + + } + }; +export default currentScreen; diff --git a/openecomp-ui/src/sdc-app/onboarding/OnboardingReducersMap.js b/openecomp-ui/src/sdc-app/onboarding/OnboardingReducersMap.js index 9428dd5829..f69bc0da5e 100644 --- a/openecomp-ui/src/sdc-app/onboarding/OnboardingReducersMap.js +++ b/openecomp-ui/src/sdc-app/onboarding/OnboardingReducersMap.js @@ -13,7 +13,7 @@ * or implied. See the License for the specific language governing * permissions and limitations under the License. */ -import {currentScreenReducer} from './OnboardingReducers.js'; +import currentScreenReducer from './OnboardingReducers.js'; import licenseModelListReducer from './licenseModel/LicenseModelListReducer.js'; import finalizedLicenseModelListReducer from './licenseModel/FinalizedLicenseModelListReducer.js'; import licenseModelReducer from './licenseModel/LicenseModelReducer.js'; @@ -21,14 +21,22 @@ import softwareProductReducer from './softwareProduct/SoftwareProductReducer.js' import softwareProductListReducer from './softwareProduct/SoftwareProductListReducer.js'; import finalizedSoftwareProductReducer from './softwareProduct/FinalizedSoftwareProductReducer.js'; import onboardReducer from './onboard/OnboardReducer.js'; +import versionsPageReducer from './versionsPage/VersionsPageReducer.js'; +import usersReducer from './users/UsersReducers.js'; +import mergeEditorReducer from 'sdc-app/common/merge/MergeEditorReducer.js'; +import revisionsReducer from './revisions/RevisionsReducer.js'; export default { currentScreen: currentScreenReducer, + licenseModel: licenseModelReducer, licenseModelList: licenseModelListReducer, finalizedLicenseModelList: finalizedLicenseModelListReducer, finalizedSoftwareProductList: finalizedSoftwareProductReducer, - licenseModel: licenseModelReducer, + mergeEditor: mergeEditorReducer, + onboard: onboardReducer, softwareProduct: softwareProductReducer, softwareProductList: softwareProductListReducer, - onboard: onboardReducer + users: usersReducer, + versionsPage: versionsPageReducer, + revisions: revisionsReducer }; diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModel.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModel.js index 895a329047..73027c7e36 100644 --- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModel.js +++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModel.js @@ -16,18 +16,17 @@ import {connect} from 'react-redux'; import i18n from 'nfvo-utils/i18n/i18n.js'; -import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js'; import TabulatedEditor from 'src/nfvo-components/editor/TabulatedEditor.jsx'; -import ActivityLogActionHelper from 'sdc-app/common/activity-log/ActivityLogActionHelper.js'; -import {enums} from 'sdc-app/onboarding/OnboardingConstants.js'; -import OnboardingActionHelper from 'sdc-app/onboarding/OnboardingActionHelper.js'; +import ScreensHelper from 'sdc-app/common/helpers/ScreensHelper.js'; +import {enums, screenTypes} from 'sdc-app/onboarding/OnboardingConstants.js'; + +import PermissionsActionHelper from './../permissions/PermissionsActionHelper.js'; +import RevisionsActionHelper from './../revisions/RevisionsActionHelper.js'; -import {navigationItems} from './LicenseModelConstants.js'; import LicenseModelActionHelper from './LicenseModelActionHelper.js'; -import LicenseAgreementActionHelper from './licenseAgreement/LicenseAgreementActionHelper.js'; -import FeatureGroupsActionHelper from './featureGroups/FeatureGroupsActionHelper.js'; -import EntitlementPoolsActionHelper from './entitlementPools/EntitlementPoolsActionHelper.js'; -import LicenseKeyGroupsActionHelper from './licenseKeyGroups/LicenseKeyGroupsActionHelper.js'; +import {actionTypes as modalActionTypes} from 'nfvo-components/modal/GlobalModalConstants.js'; +import {modalContentMapper} from 'sdc-app/common/modal/ModalContentMapper.js'; +import {CommitModalType} from 'nfvo-components/panel/versionController/components/CommitCommentModal.jsx'; const buildNavigationBarProps = (licenseModel, screen) => { @@ -39,131 +38,135 @@ const buildNavigationBarProps = (licenseModel, screen) => { name: vendorName, items: [ { - id: navigationItems.LICENSE_MODEL_OVERVIEW, + id: enums.SCREEN.LICENSE_MODEL_OVERVIEW, name: i18n('Overview'), meta }, { - id: navigationItems.LICENSE_AGREEMENTS, + id: enums.SCREEN.LICENSE_AGREEMENTS, name: i18n('License Agreements'), meta }, { - id: navigationItems.FEATURE_GROUPS, + id: enums.SCREEN.FEATURE_GROUPS, name: i18n('Feature Groups'), meta }, { - id: navigationItems.ENTITLEMENT_POOLS, + id: enums.SCREEN.ENTITLEMENT_POOLS, name: i18n('Entitlement Pools'), meta }, { - id: navigationItems.LICENSE_KEY_GROUPS, + id: enums.SCREEN.LICENSE_KEY_GROUPS, name: i18n('License Key Groups'), meta }, { - id: navigationItems.ACTIVITY_LOG, + id: enums.SCREEN.ACTIVITY_LOG, name: i18n('Activity Log'), meta } ] }]; - const activeItemId = ({ - [enums.SCREEN.LICENSE_MODEL_OVERVIEW]: navigationItems.LICENSE_MODEL_OVERVIEW, - [enums.SCREEN.LICENSE_AGREEMENTS]: navigationItems.LICENSE_AGREEMENTS, - [enums.SCREEN.FEATURE_GROUPS]: navigationItems.FEATURE_GROUPS, - [enums.SCREEN.ENTITLEMENT_POOLS]: navigationItems.ENTITLEMENT_POOLS, - [enums.SCREEN.LICENSE_KEY_GROUPS]: navigationItems.LICENSE_KEY_GROUPS, - [enums.SCREEN.ACTIVITY_LOG]: navigationItems.ACTIVITY_LOG - })[screen]; - return { - activeItemId, groups + activeItemId: screen, groups }; }; -const buildVersionControllerProps = (licenseModel) => { - let {version, viewableVersions, status: currentStatus, lockingUser} = licenseModel; - let {status, isCheckedOut} = VersionControllerUtils.getCheckOutStatusKindByUserID(currentStatus, lockingUser); - +const buildVersionControllerProps = ({ + licenseModelEditor = {data: {}}, + versions, + currentVersion, + userInfo, + usersList, + permissions, + itemPermission, + isReadOnlyMode +}) => { + const {isValidityData = true} = licenseModelEditor; return { - version, - viewableVersions, - status, - isCheckedOut + version: currentVersion, + viewableVersions: versions, + isFormDataValid: isValidityData, + permissions, + userInfo, + usersList, + itemName: licenseModelEditor.data.vendorName, + itemPermission, + isReadOnlyMode }; }; -const mapStateToProps = ({licenseModel: {licenseModelEditor}}, {currentScreen: {screen}}) => { +const mapStateToProps = ({ + users: {userInfo, usersList}, + licenseModel: {licenseModelEditor}, + versionsPage: {permissions, versionsList: {versions, itemName}} +}, { + currentScreen: {screen, itemPermission, props: {isReadOnlyMode, version: currentVersion}} +}) => { return { - versionControllerProps: buildVersionControllerProps(licenseModelEditor.data), + versionControllerProps: buildVersionControllerProps({ + licenseModelEditor, + versions, + currentVersion, + userInfo, + permissions, + usersList, + itemPermission, + isReadOnlyMode + }), navigationBarProps: buildNavigationBarProps(licenseModelEditor.data, screen) }; }; -const mapActionsToProps = (dispatch, {currentScreen: {screen, props: {licenseModelId}}}) => { +const mapActionsToProps = (dispatch, {currentScreen: {screen, props: {licenseModelId, version}}}) => { return { - onVersionControllerAction: (action, version) => - LicenseModelActionHelper.performVCAction(dispatch, {licenseModelId, action, version}).then((newVersion) => { - switch(screen) { - case enums.SCREEN.LICENSE_MODEL_OVERVIEW: - /** - * TODO change to specific rest - */ - LicenseAgreementActionHelper.fetchLicenseAgreementList(dispatch, {licenseModelId, version: newVersion}); - break; - case enums.SCREEN.LICENSE_AGREEMENTS: - LicenseAgreementActionHelper.fetchLicenseAgreementList(dispatch, {licenseModelId, version: newVersion}); - break; - case enums.SCREEN.FEATURE_GROUPS: - FeatureGroupsActionHelper.fetchFeatureGroupsList(dispatch, {licenseModelId, version: newVersion}); - break; - case enums.SCREEN.ENTITLEMENT_POOLS: - EntitlementPoolsActionHelper.fetchEntitlementPoolsList(dispatch, {licenseModelId, version: newVersion}); - break; - case enums.SCREEN.LICENSE_KEY_GROUPS: - LicenseKeyGroupsActionHelper.fetchLicenseKeyGroupsList(dispatch, {licenseModelId, version: newVersion}); - break; - case enums.SCREEN.ACTIVITY_LOG: - ActivityLogActionHelper.fetchActivityLog(dispatch, {itemId: licenseModelId, versionId: newVersion.id}); - break; - } + onVersionControllerAction: (action, version, comment) => + LicenseModelActionHelper.performVCAction(dispatch, {licenseModelId, action, version, comment}).then(updatedVersion => { + ScreensHelper.loadScreen(dispatch, {screen, screenType: screenTypes.LICENSE_MODEL, props: {licenseModelId, version: updatedVersion}}); }), - onVersionSwitching: version => { - LicenseModelActionHelper.switchVersion(dispatch, {licenseModelId, version}); - if(screen === enums.SCREEN.ACTIVITY_LOG) { - ActivityLogActionHelper.fetchActivityLog(dispatch, {itemId: licenseModelId, versionId: version.id}); + + onOpenCommentCommitModal: ({onCommit, title}) => dispatch({ + type: modalActionTypes.GLOBAL_MODAL_SHOW, + data: { + modalComponentName: modalContentMapper.COMMIT_COMMENT, + modalComponentProps: { + onCommit, + type: CommitModalType.COMMIT + }, + title } + }), + + onVersionSwitching: version => { + ScreensHelper.loadScreen(dispatch, {screen, screenType: screenTypes.LICENSE_MODEL, props: {licenseModelId, version}}); }, - onNavigate: ({id, meta: {version}}) => { - switch(id) { - case navigationItems.LICENSE_MODEL_OVERVIEW: - OnboardingActionHelper.navigateToLicenseModelOverview(dispatch, {licenseModelId, version}); - break; - case navigationItems.LICENSE_AGREEMENTS: - OnboardingActionHelper.navigateToLicenseAgreements(dispatch, {licenseModelId, version}); - break; - case navigationItems.FEATURE_GROUPS: - OnboardingActionHelper.navigateToFeatureGroups(dispatch, {licenseModelId, version}); - break; - case navigationItems.ENTITLEMENT_POOLS: - OnboardingActionHelper.navigateToEntitlementPools(dispatch, {licenseModelId, version}); - break; - case navigationItems.LICENSE_KEY_GROUPS: - OnboardingActionHelper.navigateToLicenseKeyGroups(dispatch, {licenseModelId, version}); - break; - case navigationItems.ACTIVITY_LOG: - OnboardingActionHelper.navigateToLicenseModelActivityLog(dispatch, {licenseModelId, version}); - break; - } + onManagePermissions() { + PermissionsActionHelper.openPermissonsManager(dispatch, {itemId: licenseModelId, askForRights: false}); + }, + + onMoreVersionsClick: ({itemName, users}) => { + ScreensHelper.loadScreen(dispatch, {screen: enums.SCREEN.VERSIONS_PAGE, screenType: screenTypes.LICENSE_MODEL, + props: {licenseModelId, licenseModel: {name: itemName}, usersList: users}}); + }, + + onOpenPermissions: ({users}) => { + return PermissionsActionHelper.fetchItemUsers(dispatch, {itemId: licenseModelId, allUsers: users}); + }, + + onOpenRevisionsModal: () => { + return RevisionsActionHelper.openRevisionsView(dispatch, {itemId: licenseModelId, version: version, itemType: screenTypes.LICENSE_MODEL}); + }, + + onNavigate: ({id}) => { + ScreensHelper.loadScreen(dispatch, {screen: id, screenType: screenTypes.LICENSE_MODEL, props: {licenseModelId, version}}); } }; }; diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModelActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModelActionHelper.js index 788528fd75..ff264b3003 100644 --- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModelActionHelper.js +++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModelActionHelper.js @@ -23,7 +23,14 @@ import LicenseAgreementActionHelper from './licenseAgreement/LicenseAgreementAct import FeatureGroupsActionHelper from './featureGroups/FeatureGroupsActionHelper.js'; import EntitlementPoolsActionHelper from './entitlementPools/EntitlementPoolsActionHelper.js'; import LicenseKeyGroupsActionHelper from './licenseKeyGroups/LicenseKeyGroupsActionHelper.js'; -import OnboardingActionHelper from 'sdc-app/onboarding/OnboardingActionHelper.js'; +import ItemsHelper from '../../common/helpers/ItemsHelper.js'; +import MergeEditorActionHelper from 'sdc-app/common/merge/MergeEditorActionHelper.js'; +import {modalContentMapper} from 'sdc-app/common/modal/ModalContentMapper.js'; +import {CommitModalType} from 'nfvo-components/panel/versionController/components/CommitCommentModal.jsx'; +import versionPageActionHelper from 'sdc-app/onboarding/versionsPage/VersionsPageActionHelper.js'; +import {itemTypes} from 'sdc-app/onboarding/versionsPage/VersionsPageConstants.js'; +import {catalogItemStatuses} from 'sdc-app/onboarding/onboard/onboardingCatalog/OnboardingCatalogConstants.js'; +import {actionsEnum as VersionControllerActionsEnum} from 'nfvo-components/panel/versionController/VersionControllerConstants.js'; function baseUrl() { const restPrefix = Configuration.get('restPrefix'); @@ -31,11 +38,11 @@ function baseUrl() { } function fetchLicenseModels() { - return RestAPIUtil.fetch(baseUrl()); + return RestAPIUtil.fetch(`${baseUrl()}?versionFilter=Draft`); } function fetchFinalizedLicenseModels() { - return RestAPIUtil.fetch(`${baseUrl()}?versionFilter=Final`); + return RestAPIUtil.fetch(`${baseUrl()}?versionFilter=Certified`); } function fetchLicenseModelById(licenseModelId, version) { @@ -43,11 +50,6 @@ function fetchLicenseModelById(licenseModelId, version) { return RestAPIUtil.fetch(`${baseUrl()}${licenseModelId}/versions/${versionId}`); } -function putLicenseModelAction(id, action, version) { - const {id: versionId} = version; - return RestAPIUtil.put(`${baseUrl()}${id}/versions/${versionId}/actions`, {action: action}); -} - function putLicenseModel(licenseModel) { let {id, vendorName, description, iconRef, version: {id: versionId}} = licenseModel; return RestAPIUtil.put(`${baseUrl()}${id}/versions/${versionId}`, { @@ -57,14 +59,9 @@ function putLicenseModel(licenseModel) { }); } -function adjustMinorVersion(version, value) { - let ar = version.split('.'); - return ar[0] + '.' + (parseInt(ar[1]) + value); -} - -function adjustMajorVersion(version, value) { - let ar = version.split('.'); - return (parseInt(ar[0]) + value) + '.0'; +function putLicenseModelAction({itemId, action, version}) { + const {id: versionId} = version; + return RestAPIUtil.put(`${baseUrl()}${itemId}/versions/${versionId}/actions`, {action: action}); } const LicenseModelActionHelper = { @@ -87,8 +84,8 @@ const LicenseModelActionHelper = { }, fetchLicenseModelById(dispatch, {licenseModelId, version}) { - - return fetchLicenseModelById(licenseModelId, version).then(response => { + + return fetchLicenseModelById(licenseModelId, version).then(response => { dispatch({ type: actionTypes.LICENSE_MODEL_LOADED, response: {...response, version} @@ -96,13 +93,6 @@ const LicenseModelActionHelper = { }); }, - addLicenseModel(dispatch, {licenseModel}){ - dispatch({ - type: actionTypes.ADD_LICENSE_MODEL, - licenseModel - }); - }, - fetchLicenseModelItems(dispatch, {licenseModelId, version}) { return Promise.all([ LicenseAgreementActionHelper.fetchLicenseAgreementList(dispatch, {licenseModelId, version}), @@ -112,58 +102,94 @@ const LicenseModelActionHelper = { ]); }, - performVCAction(dispatch, {licenseModelId, action, version}) { - return putLicenseModelAction(licenseModelId, action, version).then(() => { - if(action === vcActionsEnum.SUBMIT){ + manageSubmitAction(dispatch, {licenseModelId, version, isDirty}) { + if(isDirty) { + const onCommit = comment => { + return this.performVCAction(dispatch, {licenseModelId, action: vcActionsEnum.COMMIT, version, comment}).then(() => { + return this.performSubmitAction(dispatch, {licenseModelId, version}); + }); + }; + dispatch({ + type: modalActionTypes.GLOBAL_MODAL_SHOW, + data: { + modalComponentName: modalContentMapper.COMMIT_COMMENT, + modalComponentProps: { + onCommit, + type: CommitModalType.COMMIT_SUBMIT + }, + title: i18n('Commit & Submit') + } + }); + return Promise.reject(); + } + return this.performSubmitAction(dispatch, {licenseModelId, version}); + }, + + performSubmitAction(dispatch, {licenseModelId, version}) { + return putLicenseModelAction({itemId: licenseModelId, action: vcActionsEnum.SUBMIT, version}).then(() => { + return ItemsHelper.checkItemStatus(dispatch, {itemId: licenseModelId, versionId: version.id}).then(updatedVersion => { dispatch({ type: modalActionTypes.GLOBAL_MODAL_SUCCESS, data: { - title: i18n('Submit Succeeded'), + title: i18n('Submit Succeeded'), msg: i18n('This license model successfully submitted'), - cancelButtonText: i18n('OK'), + cancelButtonText: i18n('OK'), timeout: 2000 } }); - } - - let newVersionId = version.id; - /* - TODO Temorary switch to change version label - */ - switch(action) { - case vcActionsEnum.CHECK_OUT: - newVersionId = adjustMinorVersion(version.label, 1); - break; - case vcActionsEnum.UNDO_CHECK_OUT: - newVersionId = adjustMinorVersion(version.label, -1); - break; - case vcActionsEnum.SUBMIT: - newVersionId = adjustMajorVersion(version.label, 1); - } - - OnboardingActionHelper.updateCurrentScreenVersion(dispatch, {label: newVersionId, id: newVersionId}); - - LicenseModelActionHelper.fetchLicenseModelById(dispatch, {licenseModelId, version:{id: newVersionId, label: newVersionId}}); - return Promise.resolve({id: newVersionId, label: newVersionId}); + versionPageActionHelper.fetchVersions(dispatch, {itemType: itemTypes.LICENSE_MODEL, itemId: licenseModelId}); + return Promise.resolve(updatedVersion); + }); }); }, - switchVersion(dispatch, {licenseModelId, version}) { - LicenseModelActionHelper.fetchLicenseModelById(dispatch, {licenseModelId, version: {id: version.id, label: version.label}}).then(() => { - LicenseModelActionHelper.fetchLicenseModelItems(dispatch, {licenseModelId, version}); + performVCAction(dispatch, {licenseModelId, action, version, comment}) { + return MergeEditorActionHelper.analyzeSyncResult(dispatch, {itemId: licenseModelId, version}).then(({inMerge, isDirty, updatedVersion}) => { + if (updatedVersion.status === catalogItemStatuses.CERTIFIED && + (action === VersionControllerActionsEnum.COMMIT || action === VersionControllerActionsEnum.SYNC)) { + versionPageActionHelper.fetchVersions(dispatch, {itemType: itemTypes.LICENSE_MODEL, itemId: licenseModelId}); + dispatch({ + type: modalActionTypes.GLOBAL_MODAL_WARNING, + data: { + title: i18n('Commit error'), + msg: i18n('Item version already Certified'), + cancelButtonText: i18n('Cancel') + } + }); + return Promise.resolve(updatedVersion); + } + if (!inMerge) { + if(action === vcActionsEnum.SUBMIT) { + return this.manageSubmitAction(dispatch, {licenseModelId, version, isDirty}); + } + else { + return ItemsHelper.performVCAction({itemId: licenseModelId, action, version, comment}).then(() => { + versionPageActionHelper.fetchVersions(dispatch, {itemType: itemTypes.LICENSE_MODEL, itemId: licenseModelId}); + if (action === vcActionsEnum.SYNC) { + return MergeEditorActionHelper.analyzeSyncResult(dispatch, {itemId: licenseModelId, version}).then(({updatedVersion}) => { + return Promise.resolve(updatedVersion); + }); + } else { + return ItemsHelper.checkItemStatus(dispatch, {itemId: licenseModelId, versionId: version.id}); + } + }); + } + } }); }, saveLicenseModel(dispatch, {licenseModel}) { return putLicenseModel(licenseModel).then(() => { dispatch({ - type: actionTypes.ADD_LICENSE_MODEL, - licenseModel - }); - dispatch({ type: actionTypes.LICENSE_MODEL_LOADED, response: licenseModel }); + const {id, version: {id: versionId}} = licenseModel; + return ItemsHelper.checkItemStatus(dispatch, {itemId: id, versionId}).then(updatedVersion => { + if (updatedVersion.status !== licenseModel.version.status) { + versionPageActionHelper.fetchVersions(dispatch, {itemType: itemTypes.LICENSE_MODEL, itemId: licenseModel.id}); + } + }); }); } diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModelConstants.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModelConstants.js index 960090c2d8..283cb23168 100644 --- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModelConstants.js +++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModelConstants.js @@ -20,18 +20,9 @@ export const actionTypes = keyMirror({ LICENSE_MODEL_LOADED: null, LICENSE_MODELS_LIST_LOADED: null, FINALIZED_LICENSE_MODELS_LIST_LOADED: null, - ADD_LICENSE_MODEL: null, EDIT_LICENSE_MODEL: null }); -export const navigationItems = keyMirror({ - LICENSE_MODEL_OVERVIEW: 'overview', - LICENSE_AGREEMENTS: 'license-agreements', - FEATURE_GROUPS: 'feature-groups', - ENTITLEMENT_POOLS: 'entitlement-pools', - LICENSE_KEY_GROUPS: 'license-key-groups', - ACTIVITY_LOG: 'activity-log' -}); export const thresholdUnitType = { ABSOLUTE: 'Absolute', diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModelListReducer.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModelListReducer.js index fd73b462a3..36a190a39c 100644 --- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModelListReducer.js +++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModelListReducer.js @@ -19,8 +19,6 @@ export default (state = [], action) => { switch (action.type) { case actionTypes.LICENSE_MODELS_LIST_LOADED: return [...action.response.results]; - case actionTypes.ADD_LICENSE_MODEL: - return [...state, action.licenseModel]; default: return state; } diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/creation/LicenseModelCreation.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/creation/LicenseModelCreation.js index 39b3c15c6a..71f41710db 100644 --- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/creation/LicenseModelCreation.js +++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/creation/LicenseModelCreation.js @@ -14,34 +14,42 @@ * permissions and limitations under the License. */ import {connect} from 'react-redux'; -import OnboardingActionHelper from 'sdc-app/onboarding/OnboardingActionHelper.js'; import LicenseModelCreationActionHelper from './LicenseModelCreationActionHelper.js'; import LicenseModelCreationView from './LicenseModelCreationView.jsx'; import ValidationHelper from 'sdc-app/common/helpers/ValidationHelper.js'; import LicenseModelActionHelper from 'sdc-app/onboarding/licenseModel/LicenseModelActionHelper.js'; +import VersionsPageActionHelper from 'sdc-app/onboarding/versionsPage/VersionsPageActionHelper.js'; +import {itemTypes as versionItemTypes} from 'sdc-app/onboarding/versionsPage/VersionsPageConstants.js'; +import ScreensHelper from 'sdc-app/common/helpers/ScreensHelper.js'; +import {enums, screenTypes} from 'sdc-app/onboarding/OnboardingConstants.js'; +import PermissionsActionHelper from 'sdc-app/onboarding/permissions/PermissionsActionHelper.js'; -export const mapStateToProps = ({licenseModelList, licenseModel: {licenseModelCreation}}) => { +export const mapStateToProps = ({users: {usersList}, licenseModelList, licenseModel: {licenseModelCreation}}) => { let {genericFieldInfo} = licenseModelCreation; let isFormValid = ValidationHelper.checkFormValid(genericFieldInfo); let VLMNames = {}; for (let i = 0; i < licenseModelList.length; i++) { - VLMNames[licenseModelList[i].vendorName.toLowerCase()] = licenseModelList[i].id; + VLMNames[licenseModelList[i].name.toLowerCase()] = licenseModelList[i].id; } - return {...licenseModelCreation, isFormValid: isFormValid, VLMNames}; + return {...licenseModelCreation, isFormValid: isFormValid, VLMNames, usersList}; }; export const mapActionsToProps = (dispatch) => { return { onDataChanged: (deltaData, formName, customValidations) => ValidationHelper.dataChanged(dispatch, {deltaData, formName, customValidations}), onCancel: () => LicenseModelCreationActionHelper.close(dispatch), - onSubmit: (licenseModel) => { + onSubmit: (licenseModel, usersList) => { LicenseModelCreationActionHelper.close(dispatch); LicenseModelCreationActionHelper.createLicenseModel(dispatch, {licenseModel}).then(response => { - LicenseModelActionHelper.fetchLicenseModels(dispatch).then(() => { - OnboardingActionHelper.navigateToLicenseModelOverview(dispatch, {licenseModelId: response.value}); - }); + let {itemId, version} = response; + LicenseModelActionHelper.fetchLicenseModels(dispatch).then(() => + PermissionsActionHelper.fetchItemUsers(dispatch, {itemId, allUsers: usersList}).then(() => + VersionsPageActionHelper.fetchVersions(dispatch, {itemType: versionItemTypes.LICENSE_MODEL, itemId}).then(() => + ScreensHelper.loadScreen(dispatch, {screen: enums.SCREEN.LICENSE_MODEL_OVERVIEW, screenType: screenTypes.LICENSE_MODEL, + props: {licenseModelId: itemId, version}}) + ))); }); }, onValidateForm: (formName) => ValidationHelper.validateForm(dispatch, formName) diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/creation/LicenseModelCreationActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/creation/LicenseModelCreationActionHelper.js index 51f5b7f276..87df1386b6 100644 --- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/creation/LicenseModelCreationActionHelper.js +++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/creation/LicenseModelCreationActionHelper.js @@ -61,7 +61,13 @@ export default { }, createLicenseModel(dispatch, {licenseModel}){ - return createLicenseModel(licenseModel); + return createLicenseModel(licenseModel).then(result => { + dispatch({ + type: actionTypes.LICENSE_MODEL_CREATED, + result + }); + return result; + }); } }; diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/creation/LicenseModelCreationConstants.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/creation/LicenseModelCreationConstants.js index 28f1175676..e9b1c46bef 100644 --- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/creation/LicenseModelCreationConstants.js +++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/creation/LicenseModelCreationConstants.js @@ -17,7 +17,8 @@ import keyMirror from 'nfvo-utils/KeyMirror.js'; export const actionTypes = keyMirror({ OPEN: null, - CLOSE: null + CLOSE: null, + LICENSE_MODEL_CREATED: null }); export const LICENSE_MODEL_CREATION_FORM_NAME = 'LMCREATIONFORM'; diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/creation/LicenseModelCreationView.jsx b/openecomp-ui/src/sdc-app/onboarding/licenseModel/creation/LicenseModelCreationView.jsx index 80040460c0..948bdc158d 100644 --- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/creation/LicenseModelCreationView.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/creation/LicenseModelCreationView.jsx @@ -14,27 +14,29 @@ * permissions and limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import i18n from 'nfvo-utils/i18n/i18n.js'; import Validator from 'nfvo-utils/Validator.js'; import Input from 'nfvo-components/input/validation/Input.jsx'; import Form from 'nfvo-components/input/validation/Form.jsx'; import {LICENSE_MODEL_CREATION_FORM_NAME} from './LicenseModelCreationConstants.js'; -const LicenseModelPropType = React.PropTypes.shape({ - id: React.PropTypes.string, - vendorName: React.PropTypes.string, - description: React.PropTypes.string +const LicenseModelPropType = PropTypes.shape({ + id: PropTypes.string, + vendorName: PropTypes.string, + description: PropTypes.string }); class LicenseModelCreationView extends React.Component { static propTypes = { data: LicenseModelPropType, - VLMNames: React.PropTypes.object, - onDataChanged: React.PropTypes.func.isRequired, - onSubmit: React.PropTypes.func.isRequired, - onValidateForm: React.PropTypes.func.isRequired, - onCancel: React.PropTypes.func.isRequired + VLMNames: PropTypes.object, + usersList: PropTypes.array, + onDataChanged: PropTypes.func.isRequired, + onSubmit: PropTypes.func.isRequired, + onValidateForm: PropTypes.func.isRequired, + onCancel: PropTypes.func.isRequired }; render() { @@ -46,6 +48,7 @@ class LicenseModelCreationView extends React.Component { ref='validationForm' hasButtons={true} onSubmit={ () => this.submit() } + submitButtonText={i18n('Create')} onReset={ () => this.props.onCancel() } labledButtons={true} isValid={this.props.isFormValid} @@ -79,8 +82,8 @@ class LicenseModelCreationView extends React.Component { submit() { - const {data:licenseModel} = this.props; - this.props.onSubmit(licenseModel); + const {data:licenseModel, usersList} = this.props; + this.props.onSubmit(licenseModel, usersList); } validateName(value) { diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsActionHelper.js index ce4327d810..09a6e8228c 100644 --- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsActionHelper.js +++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsActionHelper.js @@ -16,9 +16,9 @@ import RestAPIUtil from 'nfvo-utils/RestAPIUtil.js'; import Configuration from 'sdc-app/config/Configuration.js'; import {actionTypes as entitlementPoolsActionTypes } from './EntitlementPoolsConstants.js'; -import LicenseModelActionHelper from 'sdc-app/onboarding/licenseModel/LicenseModelActionHelper.js'; import {actionTypes as limitEditorActions} from 'sdc-app/onboarding/licenseModel/limits/LimitEditorConstants.js'; import {default as getValue, getStrValue} from 'nfvo-utils/getValue.js'; +import ItemsHelper from 'sdc-app/common/helpers/ItemsHelper.js'; function baseUrl(licenseModelId, version) { const restPrefix = Configuration.get('restPrefix'); @@ -124,6 +124,7 @@ export default { type: entitlementPoolsActionTypes.DELETE_ENTITLEMENT_POOL, entitlementPoolId }); + ItemsHelper.checkItemStatus(dispatch, {itemId: licenseModelId, versionId: version.id}); }); }, @@ -147,6 +148,7 @@ export default { type: entitlementPoolsActionTypes.EDIT_ENTITLEMENT_POOL, entitlementPool }); + ItemsHelper.checkItemStatus(dispatch, {itemId: licenseModelId, versionId: version.id}); }); } else { @@ -159,6 +161,7 @@ export default { id: response.value } }); + ItemsHelper.checkItemStatus(dispatch, {itemId: licenseModelId, versionId: version.id}); }); } }, @@ -176,11 +179,6 @@ export default { }); }, - switchVersion(dispatch, {licenseModelId, version}) { - LicenseModelActionHelper.fetchLicenseModelById(dispatch, {licenseModelId, version}).then(() => { - this.fetchEntitlementPoolsList(dispatch, {licenseModelId, version}); - }); - }, fetchLimits(dispatch, {licenseModelId, version, entitlementPool}) { @@ -200,12 +198,14 @@ export default { type: limitEditorActions.CLOSE }); this.fetchLimits(dispatch, {licenseModelId, version, entitlementPool}); + ItemsHelper.checkItemStatus(dispatch, {itemId: licenseModelId, versionId: version.id}); }); }, deleteLimit(dispatch, {licenseModelId, version, entitlementPool, limit}) { return deleteLimit(licenseModelId,entitlementPool.id, version, limit.id).then(() => { this.fetchLimits(dispatch, {licenseModelId, version, entitlementPool}); + ItemsHelper.checkItemStatus(dispatch, {itemId: licenseModelId, versionId: version.id}); }); } }; diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsEditorView.jsx b/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsEditorView.jsx index 8473c1a2be..154174cf6c 100644 --- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsEditorView.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsEditorView.jsx @@ -14,6 +14,7 @@ * permissions and limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import i18n from 'nfvo-utils/i18n/i18n.js'; import Validator from 'nfvo-utils/Validator.js'; @@ -34,19 +35,19 @@ import Tab from 'sdc-ui/lib/react/Tab.js'; import EntitlementPoolsLimits from './EntitlementPoolsLimits.js'; import {limitType, NEW_LIMIT_TEMP_ID} from '../limits/LimitEditorConstants.js'; -const EntitlementPoolPropType = React.PropTypes.shape({ - id: React.PropTypes.string, - name: React.PropTypes.string, - description: React.PropTypes.string, - operationalScope: React.PropTypes.shape({ - choices: React.PropTypes.array, - other: React.PropTypes.string +const EntitlementPoolPropType = PropTypes.shape({ + id: PropTypes.string, + name: PropTypes.string, + description: PropTypes.string, + operationalScope: PropTypes.shape({ + choices: PropTypes.array, + other: PropTypes.string }), - thresholdUnits: React.PropTypes.string, - thresholdValue: React.PropTypes.number, - increments: React.PropTypes.string, - startDate: React.PropTypes.string, - expiryDate: React.PropTypes.string + thresholdUnits: PropTypes.string, + thresholdValue: PropTypes.string, + increments: PropTypes.string, + startDate: PropTypes.string, + expiryDate: PropTypes.string }); const EntitlementPoolsFormContent = ({data, genericFieldInfo, onDataChanged, validateName, @@ -55,7 +56,7 @@ const EntitlementPoolsFormContent = ({data, genericFieldInfo, onDataChanged, val let {name, description, operationalScope, thresholdUnits, thresholdValue, increments, startDate, expiryDate} = data; return ( - <GridSection> + <GridSection hasLastColSet> <GridItem colSpan={2}> <Input onChange={name => onDataChanged({name}, SP_ENTITLEMENT_POOL_FORM, {name: validateName})} @@ -67,7 +68,7 @@ const EntitlementPoolsFormContent = ({data, genericFieldInfo, onDataChanged, val data-test-id='create-ep-name' type='text'/> </GridItem> - <GridItem colSpan={2}> + <GridItem colSpan={2} lastColInRow> <InputOptions onInputChange={()=>{}} isMultiSelect={true} @@ -94,7 +95,7 @@ const EntitlementPoolsFormContent = ({data, genericFieldInfo, onDataChanged, val data-test-id='create-ep-description' type='textarea'/> </GridItem> - <GridItem colSpan={2}> + <GridItem colSpan={2} lastColInRow> <div className='threshold-section'> <Input onChange={e => { @@ -152,7 +153,7 @@ const EntitlementPoolsFormContent = ({data, genericFieldInfo, onDataChanged, val )} isValid={genericFieldInfo.startDate.isValid} errorText={genericFieldInfo.startDate.errorText} - selectsStart/> + selectsStart/> <Input type='date' label={i18n('Expiry Date')} @@ -167,8 +168,8 @@ const EntitlementPoolsFormContent = ({data, genericFieldInfo, onDataChanged, val isValid={genericFieldInfo.expiryDate.isValid} errorText={genericFieldInfo.expiryDate.errorText} selectsEnd/> - </div> - </GridItem> + </div> + </GridItem> </GridSection> ); }; @@ -178,18 +179,18 @@ class EntitlementPoolsEditorView extends React.Component { static propTypes = { data: EntitlementPoolPropType, previousData: EntitlementPoolPropType, - EPNames: React.PropTypes.object, - isReadOnlyMode: React.PropTypes.bool, - onDataChanged: React.PropTypes.func.isRequired, - onSubmit: React.PropTypes.func.isRequired, - onCancel: React.PropTypes.func.isRequired + EPNames: PropTypes.object, + isReadOnlyMode: PropTypes.bool, + onDataChanged: PropTypes.func.isRequired, + onSubmit: PropTypes.func.isRequired, + onCancel: PropTypes.func.isRequired }; static defaultProps = { data: {} }; - componentDidUpdate(prevProps) { + componentDidUpdate(prevProps) { if (this.props.formReady && this.props.formReady !== prevProps.formReady) { // if form validation succeeded -> continue with submit this.submit(); } @@ -207,9 +208,9 @@ class EntitlementPoolsEditorView extends React.Component { return ( <div> - <Tabs - type='menu' - activeTab={selectedTab} + <Tabs + type='menu' + activeTab={selectedTab} onTabClick={(tabIndex)=>{ if (tabIndex === tabIds.ADD_LIMIT_BUTTON) { this.onAddLimit(); @@ -218,14 +219,13 @@ class EntitlementPoolsEditorView extends React.Component { this.setState({selectedLimit: ''}); onCloseLimitEditor(); } - - }} + }} invalidTabs={[]}> <Tab tabId={tabIds.GENERAL} data-test-id='general-tab' title={i18n('General')}> { genericFieldInfo && <Form ref='validationForm' - hasButtons={false} + hasButtons={false} labledButtons={false} isReadOnlyMode={isReadOnlyMode} isValid={this.props.isFormValid} @@ -243,20 +243,20 @@ class EntitlementPoolsEditorView extends React.Component { } </Tab> <Tab disabled={isTabsDisabled} tabId={tabIds.SP_LIMITS} data-test-id='sp-limits-tab' title={i18n('SP Limits')}> - {selectedTab === tabIds.SP_LIMITS && - <EntitlementPoolsLimits + {selectedTab === tabIds.SP_LIMITS && + <EntitlementPoolsLimits isReadOnlyMode={isReadOnlyMode} - limitType={limitType.SERVICE_PROVIDER} + limitType={limitType.SERVICE_PROVIDER} limitsList={limitsList.filter(item => item.type === limitType.SERVICE_PROVIDER)} selectedLimit={this.state.selectedLimit} onCloseLimitEditor={() => this.onCloseLimitEditor()} onSelectLimit={limit => this.onSelectLimit(limit)}/>} </Tab> <Tab disabled={isTabsDisabled} tabId={tabIds.VENDOR_LIMITS} data-test-id='vendor-limits-tab' title={i18n('Vendor Limits')}> - {selectedTab === tabIds.VENDOR_LIMITS && - <EntitlementPoolsLimits + {selectedTab === tabIds.VENDOR_LIMITS && + <EntitlementPoolsLimits isReadOnlyMode={isReadOnlyMode} - limitType={limitType.VENDOR} + limitType={limitType.VENDOR} limitsList={limitsList.filter(item => item.type === limitType.VENDOR)} selectedLimit={this.state.selectedLimit} onCloseLimitEditor={() => this.onCloseLimitEditor()} @@ -273,7 +273,7 @@ class EntitlementPoolsEditorView extends React.Component { {i18n('Add Limit')} </Button> : - <div></div> // Render empty div to not break tabs + <div></div> // Render empty div to not break tabs } </Tabs> <GridSection className='license-model-modal-buttons entitlement-pools-editor-buttons'> @@ -285,21 +285,18 @@ class EntitlementPoolsEditorView extends React.Component { <Button btnType={this.state.selectedLimit ? 'default' : 'outline'} onClick={() => this.props.onCancel()} type='reset'> {i18n('Cancel')} </Button> - </GridSection> + </GridSection> </div> ); } submit() { const {data: entitlementPool, previousData: previousEntitlementPool, formReady} = this.props; - if (!formReady) { this.props.onValidateForm(SP_ENTITLEMENT_POOL_FORM); } else { this.props.onSubmit({entitlementPool, previousEntitlementPool}); } - - } validateName(value) { @@ -329,8 +326,6 @@ class EntitlementPoolsEditorView extends React.Component { this.props.onOpenLimitEditor(); } - - } export default EntitlementPoolsEditorView; diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsLimits.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsLimits.js index 1eb6eebff8..8300594098 100644 --- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsLimits.js +++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsLimits.js @@ -20,10 +20,10 @@ import Limits from 'sdc-app/onboarding/licenseModel/limits/Limits.jsx'; import {actionTypes as globalModalActionTypes} from 'nfvo-components/modal/GlobalModalConstants.js'; import EntitlementPoolsActionHelper from './EntitlementPoolsActionHelper.js'; -const mapStateToProps = ({licenseModel: {entitlementPool: {entitlementPoolEditor: {data}}, limitEditor}, currentScreen}) => { +const mapStateToProps = ({licenseModel: {entitlementPool: {entitlementPoolEditor: {data}}, limitEditor}, currentScreen}) => { let {props: {licenseModelId, version}} = currentScreen; return { - parent: data, + parent: data, limitEditor, licenseModelId, version @@ -42,10 +42,10 @@ const mapActionsToProps = (dispatch) => { onDelete: ({limit, parent, licenseModelId, version, onCloseLimitEditor, selectedLimit}) => dispatch({ type: globalModalActionTypes.GLOBAL_MODAL_WARNING, data:{ - msg: i18n(`Are you sure you want to delete ${limit.name}?`), + msg: i18n('Are you sure you want to delete {name}?', {name: limit.name}), confirmationButtonText: i18n('Delete'), title: i18n('Delete'), - onConfirmed: ()=> EntitlementPoolsActionHelper.deleteLimit(dispatch, {limit, entitlementPool: parent, licenseModelId, version}).then(() => + onConfirmed: ()=> EntitlementPoolsActionHelper.deleteLimit(dispatch, {limit, entitlementPool: parent, licenseModelId, version}).then(() => selectedLimit === limit.id && onCloseLimitEditor() ) } @@ -53,4 +53,4 @@ const mapActionsToProps = (dispatch) => { }; }; -export default connect(mapStateToProps, mapActionsToProps)(Limits);
\ No newline at end of file +export default connect(mapStateToProps, mapActionsToProps)(Limits); diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsListEditor.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsListEditor.js index fa21109541..f1dc1f8542 100644 --- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsListEditor.js +++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsListEditor.js @@ -14,26 +14,24 @@ * permissions and limitations under the License. */ import {connect} from 'react-redux'; -import i18n from 'nfvo-utils/i18n/i18n.js'; +import i18n from 'nfvo-utils/i18n/i18n.js'; import EntitlementPoolsActionHelper from './EntitlementPoolsActionHelper.js'; import EntitlementPoolsListEditorView, {generateConfirmationMsg} from './EntitlementPoolsListEditorView.jsx'; -import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js'; import {actionTypes as globalMoadlActions} from 'nfvo-components/modal/GlobalModalConstants.js'; const mapStateToProps = ({licenseModel: {entitlementPool, licenseModelEditor}}) => { - let {entitlementPoolsList} = entitlementPool; - let {data} = entitlementPool.entitlementPoolEditor; - let {vendorName} = licenseModelEditor.data; - let isReadOnlyMode = VersionControllerUtils.isReadOnly(licenseModelEditor.data); + const {entitlementPoolsList} = entitlementPool; + const {data} = entitlementPool.entitlementPoolEditor; + const {vendorName} = licenseModelEditor.data; return { vendorName, entitlementPoolsList, - isReadOnlyMode, isDisplayModal: Boolean(data), isModalInEditMode: Boolean(data && data.id), }; + }; const mapActionsToProps = (dispatch, {licenseModelId, version}) => { @@ -46,7 +44,7 @@ const mapActionsToProps = (dispatch, {licenseModelId, version}) => { msg: generateConfirmationMsg(entitlementPool), confirmationButtonText: i18n('Delete'), title: i18n('Delete'), - onConfirmed: ()=>EntitlementPoolsActionHelper.deleteEntitlementPool(dispatch, { + onConfirmed: () => EntitlementPoolsActionHelper.deleteEntitlementPool(dispatch, { licenseModelId, entitlementPoolId: entitlementPool.id, version diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsListEditorView.jsx b/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsListEditorView.jsx index c730d669c7..cc0cda1992 100644 --- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsListEditorView.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsListEditorView.jsx @@ -14,6 +14,7 @@ * permissions and limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import i18n from 'nfvo-utils/i18n/i18n.js'; import Modal from 'nfvo-components/modal/Modal.jsx'; @@ -25,15 +26,15 @@ import {extractUnits} from './EntitlementPoolsConstants'; class EntitlementPoolsListEditorView extends React.Component { static propTypes = { - vendorName: React.PropTypes.string, - licenseModelId: React.PropTypes.string.isRequired, - entitlementPoolsList: React.PropTypes.array, - isReadOnlyMode: React.PropTypes.bool.isRequired, - isDisplayModal: React.PropTypes.bool, - isModalInEditMode: React.PropTypes.bool, - onAddEntitlementPoolClick: React.PropTypes.func, - onEditEntitlementPoolClick: React.PropTypes.func, - onDeleteEntitlementPool: React.PropTypes.func, + vendorName: PropTypes.string, + licenseModelId: PropTypes.string.isRequired, + entitlementPoolsList: PropTypes.array, + isReadOnlyMode: PropTypes.bool.isRequired, + isDisplayModal: PropTypes.bool, + isModalInEditMode: PropTypes.bool, + onAddEntitlementPoolClick: PropTypes.func, + onEditEntitlementPoolClick: PropTypes.func, + onDeleteEntitlementPool: PropTypes.func, }; static defaultProps = { @@ -50,7 +51,7 @@ class EntitlementPoolsListEditorView extends React.Component { const {localFilter} = this.state; return ( - <div className='entitlement-pools-list-editor'> + <div className='license-model-list-editor entitlement-pools-list-editor'> <ListEditorView title={i18n('Entitlement Pools')} plusButtonTitle={i18n('Add Entitlement Pool')} @@ -125,7 +126,7 @@ export default EntitlementPoolsListEditorView; export function generateConfirmationMsg(entitlementPoolToDelete) { let poolName = entitlementPoolToDelete ? entitlementPoolToDelete.name : ''; - let msg = i18n(`Are you sure you want to delete "${poolName}"?`); + let msg = i18n('Are you sure you want to delete "{poolName}"?', {poolName: poolName}); let subMsg = entitlementPoolToDelete && entitlementPoolToDelete.referencingFeatureGroups && entitlementPoolToDelete.referencingFeatureGroups.length > 0 ? diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupEditorView.jsx b/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupEditorView.jsx index 6a5ee4617c..6d0acaa65d 100644 --- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupEditorView.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupEditorView.jsx @@ -14,6 +14,7 @@ * permissions and limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import Tabs from 'nfvo-components/input/validation/Tabs.jsx'; import Tab from 'sdc-ui/lib/react/Tab.js'; import GridSection from 'nfvo-components/grid/GridSection.jsx'; @@ -26,20 +27,20 @@ import Validator from 'nfvo-utils/Validator.js'; import {state as FeatureGroupStateConstants, FG_EDITOR_FORM} from './FeatureGroupsConstants.js'; -const FeatureGroupsPropType = React.PropTypes.shape({ - id: React.PropTypes.string, - name: React.PropTypes.string, - description: React.PropTypes.string, - partNumber: React.PropTypes.string, - manufacturerReferenceNumber: React.PropTypes.string, - entitlementPoolsIds: React.PropTypes.arrayOf(React.PropTypes.string), - licenseKeyGroupsIds: React.PropTypes.arrayOf(React.PropTypes.string) +const FeatureGroupsPropType = PropTypes.shape({ + id: PropTypes.string, + name: PropTypes.string, + description: PropTypes.string, + partNumber: PropTypes.string, + manufacturerReferenceNumber: PropTypes.string, + entitlementPoolsIds: PropTypes.arrayOf(PropTypes.string), + licenseKeyGroupsIds: PropTypes.arrayOf(PropTypes.string) }); const GeneralTab = ({data = {}, onDataChanged, genericFieldInfo, validateName}) => { let {name, description, partNumber, manufacturerReferenceNumber} = data; return ( - <GridSection> + <GridSection hasLastColSet> <GridItem colSpan={2}> <Input groupClassName='field-section' @@ -53,7 +54,7 @@ const GeneralTab = ({data = {}, onDataChanged, genericFieldInfo, validateName}) isValid={genericFieldInfo.name.isValid} errorText={genericFieldInfo.name.errorText} /> </GridItem> - <GridItem colSpan={2}> + <GridItem colSpan={2} lastColInRow> <Input groupClassName='field-section' className='description-field' @@ -78,7 +79,7 @@ const GeneralTab = ({data = {}, onDataChanged, genericFieldInfo, validateName}) isValid={genericFieldInfo.partNumber.isValid} errorText={genericFieldInfo.partNumber.errorText} /> </GridItem> - <GridItem colSpan={2}> + <GridItem colSpan={2} lastColInRow> <Input groupClassName='field-section' onChange={manufacturerReferenceNumber => onDataChanged({manufacturerReferenceNumber}, FG_EDITOR_FORM)} @@ -142,14 +143,14 @@ class FeatureGroupEditorView extends React.Component { static propTypes = { data: FeatureGroupsPropType, previousData: FeatureGroupsPropType, - isReadOnlyMode: React.PropTypes.bool, - FGNames: React.PropTypes.object, + isReadOnlyMode: PropTypes.bool, + FGNames: PropTypes.object, - onSubmit: React.PropTypes.func, - onCancel: React.PropTypes.func, + onSubmit: PropTypes.func, + onCancel: PropTypes.func, - selectedTab: React.PropTypes.number, - onTabSelect: React.PropTypes.func, + selectedTab: PropTypes.number, + onTabSelect: PropTypes.func, entitlementPoolsList: DualListboxView.propTypes.availableList, licenseKeyGroupsList: DualListboxView.propTypes.availableList diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupListEditor.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupListEditor.js index fc892387c6..26925487db 100644 --- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupListEditor.js +++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupListEditor.js @@ -14,17 +14,16 @@ * permissions and limitations under the License. */ import {connect} from 'react-redux'; - import FeatureGroupsActionHelper from './FeatureGroupsActionHelper.js'; import FeatureGroupListEditorView, {generateConfirmationMsg} from './FeatureGroupListEditorView.jsx'; -import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js'; import i18n from 'nfvo-utils/i18n/i18n.js'; import {actionTypes as globalMoadlActions} from 'nfvo-components/modal/GlobalModalConstants.js'; export const mapStateToProps = ({licenseModel: {featureGroup, licenseModelEditor}}) => { + const {featureGroupEditor: {data}, featureGroupsList} = featureGroup; - let {vendorName, version} = licenseModelEditor.data; - let isReadOnlyMode = VersionControllerUtils.isReadOnly(licenseModelEditor.data); + const {vendorName, version} = licenseModelEditor.data; + return { vendorName, version, @@ -32,9 +31,9 @@ export const mapStateToProps = ({licenseModel: {featureGroup, licenseModelEditor show: Boolean(data), editMode: Boolean(data && data.id) }, - featureGroupsList, - isReadOnlyMode + featureGroupsList }; + }; diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupListEditorView.jsx b/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupListEditorView.jsx index 497c29d14c..f59e000c21 100644 --- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupListEditorView.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupListEditorView.jsx @@ -14,6 +14,7 @@ * permissions and limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import i18n from 'nfvo-utils/i18n/i18n.js'; import Modal from 'nfvo-components/modal/Modal.jsx'; @@ -24,18 +25,18 @@ import FeatureGroupEditor from './FeatureGroupEditor.js'; class FeatureGroupListEditorView extends React.Component { static propTypes = { - vendorName: React.PropTypes.string, - licenseModelId: React.PropTypes.string.isRequired, - featureGroupsModal: React.PropTypes.shape({ - show: React.PropTypes.bool, - editMode: React.PropTypes.bool + vendorName: PropTypes.string, + licenseModelId: PropTypes.string.isRequired, + featureGroupsModal: PropTypes.shape({ + show: PropTypes.bool, + editMode: PropTypes.bool }), - isReadOnlyMode: React.PropTypes.bool.isRequired, - onAddFeatureGroupClick: React.PropTypes.func, - onEditFeatureGroupClick: React.PropTypes.func, - onDeleteFeatureGroupClick: React.PropTypes.func, - onCancelFeatureGroupsEditor: React.PropTypes.func, - featureGroupsList: React.PropTypes.array + isReadOnlyMode: PropTypes.bool.isRequired, + onAddFeatureGroupClick: PropTypes.func, + onEditFeatureGroupClick: PropTypes.func, + onDeleteFeatureGroupClick: PropTypes.func, + onCancelFeatureGroupsEditor: PropTypes.func, + featureGroupsList: PropTypes.array }; static defaultProps = { @@ -54,7 +55,7 @@ class FeatureGroupListEditorView extends React.Component { let {licenseModelId, featureGroupsModal, isReadOnlyMode, onAddFeatureGroupClick, version} = this.props; const {localFilter} = this.state; return ( - <div className='feature-groups-list-editor'> + <div className='license-model-list-editor feature-groups-list-editor'> <ListEditorView title={i18n('Feature Groups')} plusButtonTitle={i18n('Add Feature Group')} @@ -155,7 +156,7 @@ export default FeatureGroupListEditorView; export function generateConfirmationMsg(featureGroupToDelete) { let name = featureGroupToDelete ? featureGroupToDelete.name : ''; - let msg = i18n(`Are you sure you want to delete "${name}"?`); + let msg = i18n('Are you sure you want to delete "{name}"?', {name: name}); let subMsg = featureGroupToDelete.referencingLicenseAgreements && featureGroupToDelete.referencingLicenseAgreements.length > 0 ? i18n('This feature group is associated with one ore more license agreements') : diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupsActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupsActionHelper.js index b8c03750fb..aadf8e0301 100644 --- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupsActionHelper.js +++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupsActionHelper.js @@ -16,9 +16,9 @@ import RestAPIUtil from 'nfvo-utils/RestAPIUtil.js'; import Configuration from 'sdc-app/config/Configuration.js'; import {actionTypes as featureGroupsActionConstants} from './FeatureGroupsConstants.js'; -import LicenseModelActionHelper from 'sdc-app/onboarding/licenseModel/LicenseModelActionHelper.js'; import EntitlementPoolsActionHelper from 'sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsActionHelper.js'; import LicenseKeyGroupsActionHelper from 'sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsActionHelper.js'; +import ItemsHelper from 'sdc-app/common/helpers/ItemsHelper.js'; function baseUrl(licenseModelId, version) { const restPrefix = Configuration.get('restPrefix'); @@ -26,6 +26,10 @@ function baseUrl(licenseModelId, version) { return `${restPrefix}/v1.0/vendor-license-models/${licenseModelId}/versions/${versionId}/feature-groups`; } +function fetchFeatureGroup(licenseModelId, featureGroupId, version) { + return RestAPIUtil.fetch(`${baseUrl(licenseModelId, version)}/${featureGroupId}`); +} + function fetchFeatureGroupsList(licenseModelId, version) { return RestAPIUtil.fetch(`${baseUrl(licenseModelId, version)}`); } @@ -65,6 +69,10 @@ function updateFeatureGroup(licenseModelId, previousFeatureGroup, featureGroup, } export default { + fetchFeatureGroup(dispatch, {licenseModelId, featureGroupId, version}) { + return fetchFeatureGroup(licenseModelId, featureGroupId, version); + }, + fetchFeatureGroupsList(dispatch, {licenseModelId, version}) { return fetchFeatureGroupsList(licenseModelId, version).then(response => dispatch({ type: featureGroupsActionConstants.FEATURE_GROUPS_LIST_LOADED, @@ -73,10 +81,13 @@ export default { }, deleteFeatureGroup(dispatch, {licenseModelId, featureGroupId, version}) { - return deleteFeatureGroup(licenseModelId, featureGroupId, version).then(() => dispatch({ - type: featureGroupsActionConstants.DELETE_FEATURE_GROUPS, - featureGroupId - })); + return deleteFeatureGroup(licenseModelId, featureGroupId, version).then(() => { + dispatch({ + type: featureGroupsActionConstants.DELETE_FEATURE_GROUPS, + featureGroupId + }); + ItemsHelper.checkItemStatus(dispatch, {itemId: licenseModelId, versionId: version.id}); + }); }, saveFeatureGroup(dispatch, {licenseModelId, previousFeatureGroup, featureGroup, version}) { @@ -88,6 +99,7 @@ export default { }); EntitlementPoolsActionHelper.fetchEntitlementPoolsList(dispatch, {licenseModelId, version}); LicenseKeyGroupsActionHelper.fetchLicenseKeyGroupsList(dispatch, {licenseModelId, version}); + ItemsHelper.checkItemStatus(dispatch, {itemId: licenseModelId, versionId: version.id}); }); } else { @@ -102,6 +114,7 @@ export default { }); EntitlementPoolsActionHelper.fetchEntitlementPoolsList(dispatch, {licenseModelId, version}); LicenseKeyGroupsActionHelper.fetchLicenseKeyGroupsList(dispatch, {licenseModelId, version}); + ItemsHelper.checkItemStatus(dispatch, {itemId: licenseModelId, versionId: version.id}); }); } }, @@ -114,11 +127,14 @@ export default { }, openFeatureGroupsEditor(dispatch, {featureGroup, licenseModelId, version}) { - EntitlementPoolsActionHelper.fetchEntitlementPoolsList(dispatch, {licenseModelId, version}); - LicenseKeyGroupsActionHelper.fetchLicenseKeyGroupsList(dispatch, {licenseModelId, version}); - dispatch({ - type: featureGroupsActionConstants.featureGroupsEditor.OPEN, - featureGroup + return Promise.all([ + EntitlementPoolsActionHelper.fetchEntitlementPoolsList(dispatch, {licenseModelId, version}), + LicenseKeyGroupsActionHelper.fetchLicenseKeyGroupsList(dispatch, {licenseModelId, version}) + ]).then(() => { + dispatch({ + type: featureGroupsActionConstants.featureGroupsEditor.OPEN, + featureGroup + }); }); }, @@ -126,12 +142,5 @@ export default { dispatch({ type: featureGroupsActionConstants.featureGroupsEditor.CLOSE }); - }, - - - switchVersion(dispatch, {licenseModelId, version}) { - LicenseModelActionHelper.fetchLicenseModelById(dispatch, {licenseModelId, version}).then(() => { - this.fetchFeatureGroupsList(dispatch, {licenseModelId, version}); - }); } }; diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementActionHelper.js index e9d922c212..b4f03a68cd 100644 --- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementActionHelper.js +++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementActionHelper.js @@ -17,7 +17,7 @@ import RestAPIUtil from 'nfvo-utils/RestAPIUtil.js'; import Configuration from 'sdc-app/config/Configuration.js'; import {actionTypes as licenseAgreementActionTypes} from './LicenseAgreementConstants.js'; import FeatureGroupsActionHelper from 'sdc-app/onboarding/licenseModel/featureGroups/FeatureGroupsActionHelper.js'; -import LicenseModelActionHelper from 'sdc-app/onboarding/licenseModel/LicenseModelActionHelper.js'; +import ItemsHelper from 'sdc-app/common/helpers/ItemsHelper.js'; function baseUrl(licenseModelId, version) { const restPrefix = Configuration.get('restPrefix'); @@ -29,6 +29,10 @@ function fetchLicenseAgreementList(licenseModelId, version) { return RestAPIUtil.fetch(`${baseUrl(licenseModelId, version)}`); } +function fetchLicenseAgreement(licenseModelId, licenseAgreementId, version) { + return RestAPIUtil.fetch(`${baseUrl(licenseModelId, version)}/${licenseAgreementId}`); +} + function postLicenseAgreement(licenseModelId, licenseAgreement, version) { return RestAPIUtil.post(baseUrl(licenseModelId, version), { name: licenseAgreement.name, @@ -65,6 +69,10 @@ export default { })); }, + fetchLicenseAgreement(dispatch, {licenseModelId, licenseAgreementId, version}) { + return fetchLicenseAgreement(licenseModelId, licenseAgreementId, version); + }, + openLicenseAgreementEditor(dispatch, {licenseModelId, licenseAgreement, version}) { FeatureGroupsActionHelper.fetchFeatureGroupsList(dispatch, {licenseModelId, version}); dispatch({ @@ -84,12 +92,14 @@ export default { if (previousLicenseAgreement) { return putLicenseAgreement(licenseModelId, previousLicenseAgreement, licenseAgreement, version).then(() => { this.fetchLicenseAgreementList(dispatch, {licenseModelId, version}); + ItemsHelper.checkItemStatus(dispatch, {itemId: licenseModelId, versionId: version.id}); }); } else { return postLicenseAgreement(licenseModelId, licenseAgreement, version).then(() => { this.fetchLicenseAgreementList(dispatch, {licenseModelId, version}); FeatureGroupsActionHelper.fetchFeatureGroupsList(dispatch, {licenseModelId, version}); + ItemsHelper.checkItemStatus(dispatch, {itemId: licenseModelId, versionId: version.id}); }); } }, @@ -100,6 +110,7 @@ export default { type: licenseAgreementActionTypes.DELETE_LICENSE_AGREEMENT, licenseAgreementId }); + ItemsHelper.checkItemStatus(dispatch, {itemId: licenseModelId, versionId: version.id}); }); }, @@ -108,11 +119,5 @@ export default { type: licenseAgreementActionTypes.licenseAgreementEditor.SELECT_TAB, tab }); - }, - - switchVersion(dispatch, {licenseModelId, version}) { - LicenseModelActionHelper.fetchLicenseModelById(dispatch, {licenseModelId, version}).then(() => { - this.fetchLicenseAgreementList(dispatch, {licenseModelId, version}); - }); } }; diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementEditorView.jsx b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementEditorView.jsx index 0b418686fd..a3e73f4f14 100644 --- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementEditorView.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementEditorView.jsx @@ -14,7 +14,7 @@ * permissions and limitations under the License. */ import React from 'react'; - +import PropTypes from 'prop-types'; import GridSection from 'nfvo-components/grid/GridSection.jsx'; import GridItem from 'nfvo-components/grid/GridItem.jsx'; import {TabsForm as Form} from 'nfvo-components/input/validation/Form.jsx'; @@ -34,21 +34,21 @@ const dualBoxFilterTitle = { right: i18n('Selected Feature Groups') }; -const LicenseAgreementPropType = React.PropTypes.shape({ - id: React.PropTypes.string, - name: React.PropTypes.string, - description: React.PropTypes.string, - requirementsAndConstrains: React.PropTypes.string, - licenseTerm: React.PropTypes.object, - featureGroupsIds: React.PropTypes.arrayOf(React.PropTypes.string), - version: React.PropTypes.object +const LicenseAgreementPropType = PropTypes.shape({ + id: PropTypes.string, + name: PropTypes.string, + description: PropTypes.string, + requirementsAndConstrains: PropTypes.string, + licenseTerm: PropTypes.object, + featureGroupsIds: PropTypes.arrayOf(PropTypes.string), + version: PropTypes.object }); const GeneralTabContent = ({data, genericFieldInfo, onDataChanged, validateName}) => { let {name, description, requirementsAndConstrains, licenseTerm} = data; return ( - <GridSection> + <GridSection hasLastColSet> <GridItem colSpan={2}> <Input isValid={genericFieldInfo.name.isValid} @@ -86,7 +86,7 @@ const GeneralTabContent = ({data, genericFieldInfo, onDataChanged, validateName} isValid={genericFieldInfo.licenseTerm.isValid} errorText={genericFieldInfo.licenseTerm.errorText} /> </GridItem> - <GridItem colSpan={2} stretch> + <GridItem colSpan={2} stretch lastColInRow> <Input isValid={genericFieldInfo.description.isValid} errorText={genericFieldInfo.description.errorText} @@ -107,17 +107,17 @@ 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, - onCancel: React.PropTypes.func.isRequired, + LANames: PropTypes.object, + isReadOnlyMode: PropTypes.bool, + onDataChanged: PropTypes.func.isRequired, + onSubmit: PropTypes.func.isRequired, + onCancel: PropTypes.func.isRequired, - selectedTab: React.PropTypes.number, - onTabSelect: React.PropTypes.func, + selectedTab: PropTypes.number, + onTabSelect: PropTypes.func, - selectedFeatureGroupsButtonTab: React.PropTypes.number, - onFeatureGroupsButtonTabSelect: React.PropTypes.func, + selectedFeatureGroupsButtonTab: PropTypes.number, + onFeatureGroupsButtonTabSelect: PropTypes.func, featureGroupsList: DualListboxView.propTypes.availableList }; @@ -151,7 +151,7 @@ class LicenseAgreementEditorView extends React.Component { data-test-id='general-tab' title={i18n('General')}> <fieldset disabled={isReadOnlyMode}> - <GeneralTabContent data={data} genericFieldInfo={genericFieldInfo} onDataChanged={onDataChanged} + <GeneralTabContent data={data} genericFieldInfo={genericFieldInfo} onDataChanged={onDataChanged} validateLTChoice={(value)=>this.validateLTChoice(value)} validateName={(value)=>this.validateName(value)}/> </fieldset> </Tab> @@ -181,6 +181,12 @@ class LicenseAgreementEditorView extends React.Component { this.props.onSubmit({licenseAgreement, previousLicenseAgreement}); } + validateLTChoice(value) { + if (!value.choice) { + return {isValid: false, errorText: i18n('Field is required')}; + } + return {isValid: true, errorText: ''}; + } validateName(value) { const {data: {id}, LANames} = this.props; diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementListEditor.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementListEditor.js index 92c2550c1c..72474ecdd3 100644 --- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementListEditor.js +++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementListEditor.js @@ -17,24 +17,22 @@ import {connect} from 'react-redux'; import i18n from 'nfvo-utils/i18n/i18n.js'; import LicenseAgreementActionHelper from './LicenseAgreementActionHelper.js'; import LicenseAgreementListEditorView from './LicenseAgreementListEditorView.jsx'; -import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js'; import {actionTypes as globalMoadlActions} from 'nfvo-components/modal/GlobalModalConstants.js'; const mapStateToProps = ({licenseModel: {licenseAgreement, licenseModelEditor}}) => { + let {licenseAgreementList} = licenseAgreement; let {data} = licenseAgreement.licenseAgreementEditor; let {vendorName, version} = licenseModelEditor.data; - let isReadOnlyMode = VersionControllerUtils.isReadOnly(licenseModelEditor.data); - return { vendorName, version, licenseAgreementList, - isReadOnlyMode, isDisplayModal: Boolean(data), isModalInEditMode: Boolean(data && data.id) }; + }; const mapActionsToProps = (dispatch, {licenseModelId}) => { @@ -44,7 +42,7 @@ const mapActionsToProps = (dispatch, {licenseModelId}) => { onDeleteLicenseAgreement: (licenseAgreement, version) => dispatch({ type: globalMoadlActions.GLOBAL_MODAL_WARNING, data:{ - msg: i18n(`Are you sure you want to delete "${licenseAgreement.name}"?`), + msg: i18n('Are you sure you want to delete "{name}"?', {name: licenseAgreement.name}), confirmationButtonText: i18n('Delete'), title: i18n('Delete'), onConfirmed: ()=>LicenseAgreementActionHelper.deleteLicenseAgreement(dispatch, {licenseModelId, licenseAgreementId: licenseAgreement.id, version}) diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementListEditorView.jsx b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementListEditorView.jsx index 6247723d72..ad3cdb0b58 100644 --- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementListEditorView.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementListEditorView.jsx @@ -14,6 +14,7 @@ * permissions and limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import i18n from 'nfvo-utils/i18n/i18n.js'; import Modal from 'nfvo-components/modal/Modal.jsx'; @@ -24,15 +25,15 @@ import {extractValue} from './LicenseAgreementConstants'; class LicenseAgreementListEditorView extends React.Component { static propTypes = { - vendorName: React.PropTypes.string, - licenseModelId: React.PropTypes.string.isRequired, - licenseAgreementList: React.PropTypes.array, - isReadOnlyMode: React.PropTypes.bool.isRequired, - isDisplayModal: React.PropTypes.bool, - isModalInEditMode: React.PropTypes.bool, - onAddLicenseAgreementClick: React.PropTypes.func, - onEditLicenseAgreementClick: React.PropTypes.func, - onDeleteLicenseAgreement: React.PropTypes.func, + vendorName: PropTypes.string, + licenseModelId: PropTypes.string.isRequired, + licenseAgreementList: PropTypes.array, + isReadOnlyMode: PropTypes.bool.isRequired, + isDisplayModal: PropTypes.bool, + isModalInEditMode: PropTypes.bool, + onAddLicenseAgreementClick: PropTypes.func, + onEditLicenseAgreementClick: PropTypes.func, + onDeleteLicenseAgreement: PropTypes.func, }; static defaultProps = { @@ -49,7 +50,7 @@ class LicenseAgreementListEditorView extends React.Component { const {localFilter} = this.state; return ( - <div className='license-agreement-list-editor'> + <div className='license-model-list-editor license-agreement-list-editor'> <ListEditorView title={i18n('License Agreements')} plusButtonTitle={i18n('Add License Agreement')} 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 f22080a75c..4d86815276 100644 --- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsActionHelper.js +++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsActionHelper.js @@ -16,9 +16,9 @@ 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'; import {actionTypes as limitEditorActions} from 'sdc-app/onboarding/licenseModel/limits/LimitEditorConstants.js'; import {default as getValue, getStrValue} from 'nfvo-utils/getValue.js'; +import ItemsHelper from 'sdc-app/common/helpers/ItemsHelper.js'; function baseUrl(licenseModelId, version) { const restPrefix = Configuration.get('restPrefix'); @@ -128,6 +128,7 @@ export default { type: licenseKeyGroupsConstants.EDIT_LICENSE_KEY_GROUP, licenseKeyGroup }); + ItemsHelper.checkItemStatus(dispatch, {itemId: licenseModelId, versionId: version.id}); }); } else { @@ -140,6 +141,7 @@ export default { id: response.value } }); + ItemsHelper.checkItemStatus(dispatch, {itemId: licenseModelId, versionId: version.id}); }); } @@ -152,6 +154,7 @@ export default { type: licenseKeyGroupsConstants.DELETE_LICENSE_KEY_GROUP, licenseKeyGroupId }); + ItemsHelper.checkItemStatus(dispatch, {itemId: licenseModelId, versionId: version.id}); }); }, @@ -169,12 +172,6 @@ export default { }); }, - switchVersion(dispatch, {licenseModelId, version}) { - LicenseModelActionHelper.fetchLicenseModelById(dispatch, {licenseModelId, version}).then(() => { - this.fetchLicenseKeyGroupsList(dispatch, {licenseModelId, version}); - }); - }, - fetchLimits(dispatch, {licenseModelId, version, licenseKeyGroup}) { return fetchLimitsList(licenseModelId, licenseKeyGroup.id, version).then(response => { @@ -193,12 +190,14 @@ export default { type: limitEditorActions.CLOSE }); this.fetchLimits(dispatch, {licenseModelId, version, licenseKeyGroup}); + ItemsHelper.checkItemStatus(dispatch, {itemId: licenseModelId, versionId: version.id}); }); }, deleteLimit(dispatch, {licenseModelId, version, licenseKeyGroup, limit}) { return deleteLimit(licenseModelId,licenseKeyGroup.id, version, limit.id).then(() => { this.fetchLimits(dispatch, {licenseModelId, version, licenseKeyGroup}); + ItemsHelper.checkItemStatus(dispatch, {itemId: licenseModelId, versionId: version.id}); }); } diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsEditorView.jsx b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsEditorView.jsx index 70fb43ee88..87c947eb02 100644 --- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsEditorView.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsEditorView.jsx @@ -14,6 +14,7 @@ * permissions and limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import i18n from 'nfvo-utils/i18n/i18n.js'; import Validator from 'nfvo-utils/Validator.js'; @@ -36,26 +37,26 @@ import {DATE_FORMAT} from 'sdc-app/onboarding/OnboardingConstants.js'; import LicenseKeyGroupsLimits from './LicenseKeyGroupsLimits.js'; import {limitType, NEW_LIMIT_TEMP_ID} from '../limits/LimitEditorConstants.js'; - const LicenseKeyGroupPropType = React.PropTypes.shape({ - id: React.PropTypes.string, - name: React.PropTypes.string, - description: React.PropTypes.string, - increments: React.PropTypes.string, - operationalScope: React.PropTypes.shape({ - choices: React.PropTypes.array, - other: React.PropTypes.string + const LicenseKeyGroupPropType = PropTypes.shape({ + id: PropTypes.string, + name: PropTypes.string, + description: PropTypes.string, + increments: PropTypes.string, + operationalScope: PropTypes.shape({ + choices: PropTypes.array, + other: PropTypes.string }), - type: React.PropTypes.string, - thresholdUnits: React.PropTypes.string, - thresholdValue: React.PropTypes.number, - startDate: React.PropTypes.string, - expiryDate: React.PropTypes.string + type: PropTypes.string, + thresholdUnits: PropTypes.string, + thresholdValue: PropTypes.number, + startDate: PropTypes.string, + expiryDate: PropTypes.string }); const LicenseKeyGroupFormContent = ({data, onDataChanged, genericFieldInfo, validateName, validateStartDate, thresholdValueValidation}) => { let {name, description, increments, operationalScope, type, thresholdUnits, thresholdValue, startDate, expiryDate} = data; return ( - <GridSection> + <GridSection hasLostColSet> <GridItem colSpan={2}> <Input onChange={name => onDataChanged({name}, LKG_FORM_NAME, {name: validateName})} @@ -67,7 +68,7 @@ const LicenseKeyGroupFormContent = ({data, onDataChanged, genericFieldInfo, vali isRequired={true} type='text'/> </GridItem> - <GridItem colSpan={2}> + <GridItem colSpan={2} lastColInRow> <InputOptions onInputChange={()=>{}} isMultiSelect={true} @@ -95,7 +96,7 @@ const LicenseKeyGroupFormContent = ({data, onDataChanged, genericFieldInfo, vali type='textarea' overlayPos='bottom' /> </GridItem> - <GridItem colSpan={2}> + <GridItem colSpan={2} lastColInRow> <Input isRequired={true} onChange={e => { const selectedIndex = e.target.selectedIndex; @@ -108,6 +109,7 @@ const LicenseKeyGroupFormContent = ({data, onDataChanged, genericFieldInfo, vali errorText={genericFieldInfo.type.errorText} groupClassName='bootstrap-input-options' className='input-options-select' + overlayPos='bottom' type='select' > { licenseKeyGroupOptionsInputValues.TYPE.map(type => @@ -167,7 +169,7 @@ const LicenseKeyGroupFormContent = ({data, onDataChanged, genericFieldInfo, vali errorText={genericFieldInfo.startDate.errorText} selectsStart/> </GridItem> - <GridItem> + <GridItem lastColInRow> <Input type='date' label={i18n('Expiry Date')} @@ -199,18 +201,18 @@ 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, - onCancel: React.PropTypes.func.isRequired + LKGNames: PropTypes.object, + isReadOnlyMode: PropTypes.bool, + onDataChanged: PropTypes.func.isRequired, + onSubmit: PropTypes.func.isRequired, + onCancel: PropTypes.func.isRequired }; static defaultProps = { data: {} }; - componentDidUpdate(prevProps) { + componentDidUpdate(prevProps) { if (this.props.formReady && this.props.formReady !== prevProps.formReady) { // if form validation succeeded -> continue with submit this.submit(); } @@ -229,8 +231,8 @@ class LicenseKeyGroupsEditorView extends React.Component { return ( <div className='license-keygroup-editor'> <Tabs - type='menu' - activeTab={selectedTab} + type='menu' + activeTab={selectedTab} onTabClick={(tabIndex)=>{ if (tabIndex === tabIds.ADD_LIMIT_BUTTON) { this.onAddLimit(); @@ -239,7 +241,7 @@ class LicenseKeyGroupsEditorView extends React.Component { onCloseLimitEditor(); this.setState({selectedLimit: ''}); } - }} + }} invalidTabs={[]}> <Tab tabId={tabIds.GENERAL} data-test-id='general-tab' title={i18n('General')}> { genericFieldInfo && @@ -292,10 +294,10 @@ class LicenseKeyGroupsEditorView extends React.Component { {i18n('Add Limit')} </Button> : - <div></div> // Render empty div to not break tabs + <div></div> // Render empty div to not break tabs } </Tabs> - + <GridSection className='license-model-modal-buttons license-key-group-editor-buttons'> {!this.state.selectedLimit && <Button btnType='default' disabled={!this.props.isFormValid || isReadOnlyMode} onClick={() => this.submit()} type='reset'> diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsLimits.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsLimits.js index 0e20a6a486..bd8f21a7c5 100644 --- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsLimits.js +++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsLimits.js @@ -21,10 +21,10 @@ import Limits from 'sdc-app/onboarding/licenseModel/limits/Limits.jsx'; import LicenseKeyGroupsActionHelper from './LicenseKeyGroupsActionHelper.js'; -const mapStateToProps = ({licenseModel: {licenseKeyGroup: {licenseKeyGroupsEditor: {data}}, limitEditor}, currentScreen}) => { +const mapStateToProps = ({licenseModel: {licenseKeyGroup: {licenseKeyGroupsEditor: {data}}, limitEditor}, currentScreen}) => { let {props: {licenseModelId, version}} = currentScreen; return { - parent: data, + parent: data, limitEditor, licenseModelId, version @@ -39,14 +39,14 @@ const mapActionsToProps = (dispatch) => { limit, licenseKeyGroup, licenseModelId, - version}), + version}), onDelete: ({limit, parent, licenseModelId, version, onCloseLimitEditor, selectedLimit}) => dispatch({ type: globalModalActionTypes.GLOBAL_MODAL_WARNING, data:{ - msg: i18n(`Are you sure you want to delete ${limit.name}?`), + msg: i18n('Are you sure you want to delete {name}?', {name: limit.name}), confirmationButtonText: i18n('Delete'), title: i18n('Delete'), - onConfirmed: ()=> LicenseKeyGroupsActionHelper.deleteLimit(dispatch, {limit, licenseKeyGroup: parent, licenseModelId, version}).then(() => + onConfirmed: ()=> LicenseKeyGroupsActionHelper.deleteLimit(dispatch, {limit, licenseKeyGroup: parent, licenseModelId, version}).then(() => selectedLimit === limit.id && onCloseLimitEditor() ) } @@ -54,4 +54,4 @@ const mapActionsToProps = (dispatch) => { }; }; -export default connect(mapStateToProps, mapActionsToProps)(Limits);
\ No newline at end of file +export default connect(mapStateToProps, mapActionsToProps)(Limits); diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsListEditor.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsListEditor.js index c1d937394a..00c2092b83 100644 --- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsListEditor.js +++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsListEditor.js @@ -15,21 +15,20 @@ */ import {connect} from 'react-redux'; import i18n from 'nfvo-utils/i18n/i18n.js'; + +import {actionTypes as globalMoadlActions} from 'nfvo-components/modal/GlobalModalConstants.js'; + import LicenseKeyGroupsActionHelper from './LicenseKeyGroupsActionHelper.js'; 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; let {data} = licenseKeyGroup.licenseKeyGroupsEditor; let {vendorName} = licenseModelEditor.data; - let isReadOnlyMode = VersionControllerUtils.isReadOnly(licenseModelEditor.data); return { vendorName, licenseKeyGroupsList, - isReadOnlyMode, isDisplayModal: Boolean(data), isModalInEditMode: Boolean(data && data.id) }; @@ -45,11 +44,10 @@ const mapActionsToProps = (dispatch, {licenseModelId, version}) => { msg: generateConfirmationMsg(licenseKeyGroup), confirmationButtonText: i18n('Delete'), title: i18n('Delete'), - onConfirmed: ()=>LicenseKeyGroupsActionHelper.deleteLicenseKeyGroup(dispatch, {licenseModelId, licenseKeyGroupId:licenseKeyGroup.id, version}) + onConfirmed: () => LicenseKeyGroupsActionHelper.deleteLicenseKeyGroup(dispatch, {licenseModelId, licenseKeyGroupId:licenseKeyGroup.id, version}) } }) }; }; export default connect(mapStateToProps, mapActionsToProps)(LicenseKeyGroupsListEditorView); - 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 1a7f2b0b5b..5a98b7f575 100644 --- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsListEditorView.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsListEditorView.jsx @@ -14,7 +14,7 @@ * permissions and limitations under the License. */ import React from 'react'; - +import PropTypes from 'prop-types'; import i18n from 'nfvo-utils/i18n/i18n.js'; import Modal from 'nfvo-components/modal/Modal.jsx'; import ListEditorView from 'nfvo-components/listEditor/ListEditorView.jsx'; @@ -26,15 +26,15 @@ import {optionsInputValues} from './LicenseKeyGroupsConstants'; class LicenseKeyGroupsListEditorView extends React.Component { static propTypes = { - vendorName: React.PropTypes.string, - licenseModelId: React.PropTypes.string.isRequired, - licenseKeyGroupsList: React.PropTypes.array, - isReadOnlyMode: React.PropTypes.bool.isRequired, - isDisplayModal: React.PropTypes.bool, - isModalInEditMode: React.PropTypes.bool, - onAddLicenseKeyGroupClick: React.PropTypes.func, - onEditLicenseKeyGroupClick: React.PropTypes.func, - onDeleteLicenseKeyGroupClick: React.PropTypes.func + vendorName: PropTypes.string, + licenseModelId: PropTypes.string.isRequired, + licenseKeyGroupsList: PropTypes.array, + isReadOnlyMode: PropTypes.bool.isRequired, + isDisplayModal: PropTypes.bool, + isModalInEditMode: PropTypes.bool, + onAddLicenseKeyGroupClick: PropTypes.func, + onEditLicenseKeyGroupClick: PropTypes.func, + onDeleteLicenseKeyGroupClick: PropTypes.func }; static defaultProps = { @@ -51,7 +51,7 @@ class LicenseKeyGroupsListEditorView extends React.Component { const {localFilter} = this.state; return ( - <div className='license-key-groups-list-editor'> + <div className='license-model-list-editor license-key-groups-list-editor'> <ListEditorView title={i18n('License Key Groups')} plusButtonTitle={i18n('Add License Key Group')} @@ -122,26 +122,24 @@ class LicenseKeyGroupsListEditorView extends React.Component { } getOperationalScopes(operationalScope) { - - if(operationalScope.choices && operationalScope.choices.toString() === i18n(optionInputOther.OTHER)) { + + if (operationalScope.choices && operationalScope.choices.toString() === i18n(optionInputOther.OTHER)) { return operationalScope.other; - } - else if (operationalScope.choices) { + } else if (operationalScope.choices) { let allOpScopes = ''; for (let opScope of operationalScope.choices) { allOpScopes += allOpScopes === '' ? InputOptions.getTitleByName(optionsInputValues, opScope) : `, ${InputOptions.getTitleByName(optionsInputValues, opScope)}`; } return allOpScopes; - } - else { + } else { return ''; - } + } } extractValue(item) { if (item === undefined) { return ''; - } //TODO fix it later + } //TODO fix it sooner rather than later return item ? item.choice === optionInputOther.OTHER ? item.other : InputOptions.getTitleByName(optionsInputValues, item.choice) : ''; } @@ -151,7 +149,7 @@ export default LicenseKeyGroupsListEditorView; export function generateConfirmationMsg(licenseKeyGroupToDelete) { let name = licenseKeyGroupToDelete ? licenseKeyGroupToDelete.name : ''; - let msg = i18n(`Are you sure you want to delete "${name}"?`); + let msg = i18n('Are you sure you want to delete "{name}"?', {name: name}); let subMsg = licenseKeyGroupToDelete.referencingFeatureGroups && licenseKeyGroupToDelete.referencingFeatureGroups.length > 0 ? i18n('This license key group is associated with one or more feature groups') : diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/limits/LimitEditor.jsx b/openecomp-ui/src/sdc-app/onboarding/licenseModel/limits/LimitEditor.jsx index 110e5137e1..54f057eaa4 100644 --- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/limits/LimitEditor.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/limits/LimitEditor.jsx @@ -1,4 +1,5 @@ import React from 'react'; +import PropTypes from 'prop-types'; import i18n from 'nfvo-utils/i18n/i18n.js'; import Form from 'nfvo-components/input/validation/Form.jsx'; import Input from 'nfvo-components/input/validation/Input.jsx'; @@ -10,35 +11,35 @@ import Validator from 'nfvo-utils/Validator.js'; import {other as optionInputOther} from 'nfvo-components/input/validation/InputOptions.jsx'; import InputOptions from 'nfvo-components/input/validation/InputOptions.jsx'; -const LimitPropType = React.PropTypes.shape({ - id: React.PropTypes.string, - name: React.PropTypes.string, - description: React.PropTypes.string, - metric: React.PropTypes.shape({ - choice: React.PropTypes.string, - other: React.PropTypes.string +const LimitPropType = PropTypes.shape({ + id: PropTypes.string, + name: PropTypes.string, + description: PropTypes.string, + metric: PropTypes.shape({ + choice: PropTypes.string, + other: PropTypes.string }), - value: React.PropTypes.string, - aggregationFunction: React.PropTypes.string, - time: React.PropTypes.string, - unit: React.PropTypes.shape({ - choice: React.PropTypes.string, - other: React.PropTypes.string + value: PropTypes.string, + aggregationFunction: PropTypes.string, + time: PropTypes.string, + unit: PropTypes.shape({ + choice: PropTypes.string, + other: PropTypes.string }) }); class LimitEditor extends React.Component { static propTypes = { data: LimitPropType, - limitsNames: React.PropTypes.object, - isReadOnlyMode: React.PropTypes.bool, - isFormValid: React.PropTypes.bool, - formReady: React.PropTypes.bool, - genericFieldInfo: React.PropTypes.object.isRequired, - onDataChanged: React.PropTypes.func.isRequired, - onSubmit: React.PropTypes.func.isRequired, - onValidateForm: React.PropTypes.func.isRequired, - onCancel: React.PropTypes.func.isRequired + limitsNames: PropTypes.object, + isReadOnlyMode: PropTypes.bool, + isFormValid: PropTypes.bool, + formReady: PropTypes.bool, + genericFieldInfo: PropTypes.object.isRequired, + onDataChanged: PropTypes.func.isRequired, + onSubmit: PropTypes.func.isRequired, + onValidateForm: PropTypes.func.isRequired, + onCancel: PropTypes.func.isRequired }; componentDidUpdate(prevProps) { @@ -67,7 +68,7 @@ class LimitEditor extends React.Component { labledButtons={false} isReadOnlyMode={isReadOnlyMode} className='limit-editor-form'> - <GridSection className='limit-editor-form-grid-section'> + <GridSection className='limit-editor-form-grid-section' hasLastColSet> <GridItem colSpan={2}> <Input onChange={name => onDataChanged({name}, LIMITS_FORM_NAME, {name: () => this.validateName(name)})} @@ -79,7 +80,7 @@ class LimitEditor extends React.Component { isRequired={true} type='text'/> </GridItem> - <GridItem colSpan={2}> + <GridItem colSpan={2} lastColInRow> <Input onChange={description => onDataChanged({description}, LIMITS_FORM_NAME)} label={i18n('Description')} @@ -120,7 +121,7 @@ class LimitEditor extends React.Component { isRequired={true} type='text'/> </GridItem> - <GridItem> + <GridItem lastColInRow> <InputOptions onInputChange={()=>{}} isMultiSelect={false} diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/LicenseModelOverview.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/LicenseModelOverview.js index 9d714ec62d..54941aaaf0 100644 --- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/LicenseModelOverview.js +++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/LicenseModelOverview.js @@ -15,12 +15,20 @@ */ 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}}) => { +export const mapStateToProps = ({ + licenseModel: { + licenseModelEditor, + entitlementPool, + licenseAgreement, + featureGroup, + licenseKeyGroup, + licenseModelOverview + } +}) => { let modalHeader, licensingDataList; let isDisplayModal = false; @@ -128,6 +136,7 @@ export const mapStateToProps = ({licenseModel: {licenseModelEditor, entitlementP modalHeader = overviewEditorHeaders.LICENSE_KEY_GROUP; isDisplayModal = true; } + let orphanDataList = [ ...featureGroup.featureGroupsList.reduce(checkFG, []), ...entitlementPool.entitlementPoolsList.reduce(checkEP, []), @@ -140,8 +149,8 @@ export const mapStateToProps = ({licenseModel: {licenseModelEditor, entitlementP if (selectedTab === null) { selectedTab = (licensingDataList.length) ? selectedButton.VLM_LIST_VIEW : selectedButton.NOT_IN_USE; } + return { - isReadOnlyMode: VersionControllerUtils.isReadOnly(licenseModelEditor.data), isDisplayModal, modalHeader, licenseModelId: licenseModelEditor.data.id, diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/LicenseModelOverviewView.jsx b/openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/LicenseModelOverviewView.jsx index 77289a3e08..39109af9a3 100644 --- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/LicenseModelOverviewView.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/LicenseModelOverviewView.jsx @@ -14,6 +14,7 @@ * permissions and limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import i18n from 'nfvo-utils/i18n/i18n.js'; import Modal from 'nfvo-components/modal/Modal.jsx'; import classNames from 'classnames'; @@ -47,25 +48,25 @@ const setModalClassName = (modalHeader) => { class LicenseModelOverviewView extends React.Component { static propTypes = { - isDisplayModal: React.PropTypes.bool, - isReadOnlyMode: React.PropTypes.bool, - licenseModelId: React.PropTypes.string, - licensingDataList: React.PropTypes.array, - orphanDataList: React.PropTypes.array, - modalHeader: React.PropTypes.string, - selectedTab: React.PropTypes.string, - onTabSelect: React.PropTypes.func, - onCallVCAction: React.PropTypes.func, - onClose: React.PropTypes.func + isDisplayModal: PropTypes.bool, + isReadOnlyMode: PropTypes.bool, + licenseModelId: PropTypes.string, + licensingDataList: PropTypes.array, + orphanDataList: PropTypes.array, + modalHeader: PropTypes.string, + selectedTab: PropTypes.string, + onTabSelect: PropTypes.func, + onCallVCAction: PropTypes.func, + onClose: PropTypes.func }; render() { - let {isDisplayModal, modalHeader, licensingDataList, selectedTab, onTabSelect, orphanDataList} = this.props; + let {isDisplayModal, modalHeader, licensingDataList, selectedTab, onTabSelect, orphanDataList, isReadOnlyMode} = this.props; let selectedInUse = selectedTab !== selectedButton.NOT_IN_USE; let dataList = selectedInUse ? licensingDataList : orphanDataList; return( <div className='license-model-overview'> - <SummaryView/> + <SummaryView isReadOnlyMode={isReadOnlyMode}/> <div className={classNames('overview-list-section ', !selectedInUse ? 'overview-list-orphans' : '' )}> <div className='vlm-list-tab-panel'> <ListButtons onTabSelect={onTabSelect} @@ -91,16 +92,16 @@ class LicenseModelOverviewView extends React.Component { } renderModalBody(modalHeader) { - let {licenseModelId, version} = this.props; + let {licenseModelId, version, isReadOnlyMode} = this.props; switch (modalHeader) { case overviewEditorHeaders.ENTITLEMENT_POOL: - return <EntitlementPoolsEditor version={version} licenseModelId={licenseModelId} isReadOnlyMode={false}/>; + return <EntitlementPoolsEditor version={version} licenseModelId={licenseModelId} isReadOnlyMode={isReadOnlyMode}/>; case overviewEditorHeaders.LICENSE_AGREEMENT: - return <LicenseAgreementEditor version={version} licenseModelId={licenseModelId} isReadOnlyMode={false}/>; + return <LicenseAgreementEditor version={version} licenseModelId={licenseModelId} isReadOnlyMode={isReadOnlyMode}/>; case overviewEditorHeaders.FEATURE_GROUP: - return <FeatureGroupEditor version={version} licenseModelId={licenseModelId} isReadOnlyMode={false}/>; + return <FeatureGroupEditor version={version} licenseModelId={licenseModelId} isReadOnlyMode={isReadOnlyMode}/>; case overviewEditorHeaders.LICENSE_KEY_GROUP: - return <LicenseKeyGroupsEditor version={version} licenseModelId={licenseModelId} isReadOnlyMode={false}/>; + return <LicenseKeyGroupsEditor version={version} licenseModelId={licenseModelId} isReadOnlyMode={isReadOnlyMode}/>; } } } diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/SummaryView.jsx b/openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/SummaryView.jsx index 6fcdb477e6..4053f14ced 100644 --- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/SummaryView.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/SummaryView.jsx @@ -13,21 +13,24 @@ * or implied. See the License for the specific language governing * permissions and limitations under the License. */ -import React from 'react'; +import React, {Component} 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/> +class SummaryView extends Component { + render() { + const {isReadOnlyMode} = this.props; + return( + <div className='overview-top-section'> + <div className='page-title'>{i18n('overview')}</div> + <div className='license-model-overview-top'> + <VendorDataView isReadOnlyMode={isReadOnlyMode}/> + <SummaryCountList isReadOnlyMode={isReadOnlyMode}/> + </div> </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 index ec05e37681..012bd6e158 100644 --- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/VLMListView.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/VLMListView.jsx @@ -14,6 +14,7 @@ * permissions and limitations under the License. */ import React, {Component} from 'react'; +import PropTypes from 'prop-types'; import {Collapse} from 'react-bootstrap'; import LicenseAgreement from './listItems/LicenseAgreement.jsx'; import EntitlementPool from './listItems/EntitlementPool.jsx'; @@ -24,8 +25,8 @@ import {overviewEditorHeaders} from './LicenseModelOverviewConstants.js'; class VLMListView extends Component { static propTypes = { - licensingDataList: React.PropTypes.array, - showInUse: React.PropTypes.bool + licensingDataList: PropTypes.array, + showInUse: PropTypes.bool }; state = { 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 index 5b5daafb4f..ffc0991354 100644 --- 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 @@ -14,6 +14,7 @@ * permissions and limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; function AdditionalDataCol({children}) { return ( @@ -27,9 +28,9 @@ function AdditionalDataCol({children}) { } AdditionalDataCol.propTypes = { - children: React.PropTypes.oneOfType([ - React.PropTypes.arrayOf(React.PropTypes.node), - React.PropTypes.node + children: PropTypes.oneOfType([ + PropTypes.arrayOf(PropTypes.node), + PropTypes.node ]) }; @@ -43,9 +44,9 @@ function AdditionalDataElement({className, name, value}) { } AdditionalDataElement.propTypes = { - name: React.PropTypes.string, - value: React.PropTypes.string, - className: React.PropTypes.string + name: PropTypes.string, + value: PropTypes.string, + className: 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 index a5eb9d27dd..29aec64bdd 100644 --- 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 @@ -14,6 +14,7 @@ * permissions and limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import classNames from 'classnames'; function ArrowCol ({isCollapsed, length}) { @@ -28,8 +29,8 @@ function ArrowCol ({isCollapsed, length}) { } ArrowCol.propTypes = { - isCollapsed: React.PropTypes.bool, - length: React.PropTypes.number + isCollapsed: PropTypes.bool, + length: PropTypes.number }; export default ArrowCol; 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 index 655a0dd4a8..95ae123974 100644 --- 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 @@ -14,6 +14,7 @@ * permissions and limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; function ItemInfo({name, description, children}) { return ( @@ -28,11 +29,11 @@ function ItemInfo({name, description, children}) { } ItemInfo.propTypes = { - name: React.PropTypes.string, - description: React.PropTypes.string, - children: React.PropTypes.oneOfType([ - React.PropTypes.arrayOf(React.PropTypes.node), - React.PropTypes.node + name: PropTypes.string, + description: PropTypes.string, + children: PropTypes.oneOfType([ + PropTypes.arrayOf(PropTypes.node), + PropTypes.node ]) }; 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 index f4d6d4d42c..af759f1206 100644 --- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/summary/LicenseModelDescriptionEdit.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/summary/LicenseModelDescriptionEdit.jsx @@ -14,22 +14,23 @@ * permissions and limitations under the License. */ import React from 'react'; -import Input from 'nfvo-components/input/validation/Input.jsx'; import i18n from 'nfvo-utils/i18n/i18n.js'; +import Input from 'nfvo-components/input/validation/Input.jsx'; class LicenseModelDescriptionEdit extends React.Component { render() { //TODO check if buttons let {onDataChanged, description, genericFieldInfo} = this.props; - let saveButtonClassName = (genericFieldInfo.description.isValid) ? 'description-save' : 'description-save disabled'; + let {isValid, errorText} = genericFieldInfo.description; + let saveButtonClassName = 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} + isValid={isValid} + errorText={errorText} className='description-edit-textarea' type='textarea'/> <div className='buttons-row'> @@ -50,7 +51,7 @@ class LicenseModelDescriptionEdit extends React.Component { let {onSubmit, data, description} = this.props; onSubmit({ ...data, - description: description + description: description.trim() }); } } 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 index f02c82d205..3fcac3c1d8 100644 --- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/summary/ListButtons.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/summary/ListButtons.jsx @@ -14,6 +14,7 @@ * permissions and limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import {selectedButton} from '../LicenseModelOverviewConstants.js'; import Tabs from 'sdc-ui/lib/react/Tabs.js'; import Tab from 'sdc-ui/lib/react/Tab.js'; @@ -43,8 +44,8 @@ function ListButtons ({onTabSelect, selectedTab, hasOrphans, hasLicensing}) { } ListButtons.propTypes = { - onTabSelect: React.PropTypes.func, - selectedInUse: React.PropTypes.bool + onTabSelect: PropTypes.func, + selectedInUse: 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 index 6ec84e16ca..50c547e042 100644 --- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/summary/SummaryCountItem.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/summary/SummaryCountItem.jsx @@ -24,7 +24,8 @@ function SummaryCountItem ({name, counter, onAdd, onNavigate, isReadOnlyMode}) <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> - <SVGIcon name='plusCircle' disabled={isReadOnlyMode} color='secondary' onClick={onAdd} data-test-id={'vlm-summary-vendor-add-btn-' + name.toLowerCase().replace(/\s/g,'-')}/> + <SVGIcon name='plusCircle' disabled={isReadOnlyMode} className={isReadOnlyMode ? 'disabled' : ''} + color='secondary' onClick={onAdd} data-test-id={'vlm-summary-vendor-add-btn-' + name.toLowerCase().replace(/\s/g,'-')}/> </div> ); } 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 index c69a092d23..15b6649543 100644 --- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/summary/SummaryCountList.js +++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/summary/SummaryCountList.js @@ -16,9 +16,9 @@ import React from 'react'; import {connect} from 'react-redux'; -import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js'; +import ScreensHelper from 'sdc-app/common/helpers/ScreensHelper.js'; +import {enums, screenTypes} from 'sdc-app/onboarding/OnboardingConstants.js'; -import OnboardingActionHelper from '../../../OnboardingActionHelper.js'; import EntitlementPoolsActionHelper from '../../entitlementPools/EntitlementPoolsActionHelper.js'; import LicenseAgreementActionHelper from '../../licenseAgreement/LicenseAgreementActionHelper.js'; import LicenseKeyGroupsActionHelper from '../../licenseKeyGroups/LicenseKeyGroupsActionHelper.js'; @@ -27,27 +27,32 @@ import FeatureGroupsActionHelper from '../../featureGroups/FeatureGroupsActionHe import {overviewItems} from '../LicenseModelOverviewConstants.js'; import SummaryCountItem from './SummaryCountItem.jsx'; -export const mapStateToProps = ({licenseModel: {licenseModelEditor, licenseAgreement: {licenseAgreementList}, - featureGroup: {featureGroupsList}, entitlementPool: {entitlementPoolsList}, licenseKeyGroup: {licenseKeyGroupsList}}}) => { +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) => { @@ -71,22 +76,27 @@ const mapActionsToProps = (dispatch) => { } }, onNavigateClick: ({name, licenseModelId, version}) => { + let screenToNavigate; switch (name) { case overviewItems.ENTITLEMENT_POOLS: - OnboardingActionHelper.navigateToEntitlementPools(dispatch, {licenseModelId, version}); + screenToNavigate = enums.SCREEN.ENTITLEMENT_POOLS; break; case overviewItems.FEATURE_GROUPS: - OnboardingActionHelper.navigateToFeatureGroups(dispatch, {licenseModelId, version}); + screenToNavigate = enums.SCREEN.FEATURE_GROUPS; break; case overviewItems.LICENSE_AGREEMENTS: - OnboardingActionHelper.navigateToLicenseAgreements(dispatch, {licenseModelId, version}); + screenToNavigate = enums.SCREEN.LICENSE_AGREEMENTS; break; case overviewItems.LICENSE_KEY_GROUPS: - OnboardingActionHelper.navigateToLicenseKeyGroups(dispatch, {licenseModelId, version}); + screenToNavigate = enums.SCREEN.LICENSE_KEY_GROUPS; break; default: break; } + ScreensHelper.loadScreen(dispatch, { + screen: screenToNavigate, screenType: screenTypes.LICENSE_MODEL, + props: {licenseModelId, version} + }); } }; }; 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 index 532ca32f8e..616355de41 100644 --- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/summary/VendorDataView.js +++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/overview/summary/VendorDataView.js @@ -23,17 +23,19 @@ 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} }}}) => { +export const mapStateToProps = ({ + licenseModel: { + licenseModelEditor: {data}, + licenseModelOverview: {descriptionEditor: {data: descriptionData = {}, genericFieldInfo}} + } +}) => { let {description} = descriptionData; - let isReadOnlyMode = VersionControllerUtils.isReadOnly(data); return { data, description, - genericFieldInfo, - isReadOnlyMode + genericFieldInfo }; }; diff --git a/openecomp-ui/src/sdc-app/onboarding/onboard/CatalogItemDetails.jsx b/openecomp-ui/src/sdc-app/onboarding/onboard/CatalogItemDetails.jsx index 5939499ec5..dc3b3f5ab9 100644 --- a/openecomp-ui/src/sdc-app/onboarding/onboard/CatalogItemDetails.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/onboard/CatalogItemDetails.jsx @@ -14,117 +14,68 @@ * permissions and limitations under the License. */ import React from 'react'; -import {catalogItemTypeClasses, migrationStatusMapper} from './onboardingCatalog/OnboardingCatalogConstants.js'; -import CatalogTile from './CatalogTile.jsx'; -import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js'; -import {statusEnum, statusBarTextMap} from 'nfvo-components/panel/versionController/VersionControllerConstants.js'; -import SVGIcon from 'sdc-ui/lib/react/SVGIcon.js'; +import PropTypes from 'prop-types'; import i18n from 'nfvo-utils/i18n/i18n.js'; -import OverlayTrigger from 'react-bootstrap/lib/OverlayTrigger.js'; -import tooltip from './onboardingCatalog/Tooltip.jsx'; - - -const CatalogTileIcon = ({catalogItemTypeClass}) => ( - <div className={'catalog-tile-icon ' + catalogItemTypeClass}> - <div className='icon'><SVGIcon - name={catalogItemTypeClass === catalogItemTypeClasses.LICENSE_MODEL ? 'vlm' : 'vsp' }/> - </div> - </div> -); - -const ItemTypeTitle = ({catalogItemTypeClass}) => { - const itemTypeTitle = catalogItemTypeClass === catalogItemTypeClasses.LICENSE_MODEL ? i18n('VLM') : i18n('VSP'); - return ( - <div className={`catalog-tile-type ${catalogItemTypeClass}`}>{itemTypeTitle}</div> - ); -}; - -const CatalogTileVendorName = ({vendorName, catalogItemTypeClass}) => { - const name = catalogItemTypeClass === catalogItemTypeClasses.SOFTWARE_PRODUCT ? vendorName : ''; - return ( name ? - <OverlayTrigger placement='top' overlay={tooltip(name)}> - <div className='catalog-tile-vendor-name'>{name}</div> - </OverlayTrigger> : <div className='catalog-tile-vendor-name'>{name}</div> - ); -}; - -const CatalogTileItemName = ({name}) => ( - <OverlayTrigger placement='top' overlay={tooltip(name)}> - <div className='catalog-tile-item-name'>{name}</div> - </OverlayTrigger> -); - -const VersionInfo = ({version}) => ( - <div className='catalog-tile-version-info'> - <div className='catalog-tile-item-version' data-test-id='catalog-item-version'> - V {version} - </div> - </div> -); - -const EntityDetails = ({catalogItemData, catalogItemTypeClass}) => { - const {vendorName, name, version} = catalogItemData; - return ( - <div className='catalog-tile-entity-details'> - <CatalogTileVendorName catalogItemTypeClass={catalogItemTypeClass} vendorName={vendorName}/> - <CatalogTileItemName name={name}/> - <VersionInfo version={version.label}/> - </div> - ); -}; - - -const ItemStatusInfo = ({catalogItemTypeClass, lockingUser, itemStatus}) => { - const status = statusBarTextMap[itemStatus]; - const lockedBy = lockingUser ? ` by ${lockingUser}` : ''; - const toolTipMsg = `${status}${lockedBy}`; - - return ( - <div className={'catalog-tile-content ' + catalogItemTypeClass}> - <div className='catalog-tile-locking-user-name'>{i18n(status)}</div> - <OverlayTrigger placement='top' overlay={tooltip(toolTipMsg)}> - <div className='catalog-tile-check-in-status'><SVGIcon - name={itemStatus === statusEnum.CHECK_OUT_STATUS ? 'unlocked' : 'locked'} - data-test-id={itemStatus === statusEnum.CHECK_IN_STATUS ? 'catalog-item-checked-in' : 'catalog-item-checked-out'}/> - </div> - </OverlayTrigger> - </div> - - ); +import {catalogItemTypes, migrationStatusMapper} from './onboardingCatalog/OnboardingCatalogConstants.js'; +import {Tile, TileInfo, TileInfoLine} from 'sdc-ui/lib/react'; +import {TooltipWrapper} from './onboardingCatalog/Tooltip.jsx'; + +const ITEM_TYPE_MAP = { + [catalogItemTypes.LICENSE_MODEL]: { + headerText: i18n('VLM'), + contentIconName: 'vlm', + color: 'purple' + }, + [catalogItemTypes.SOFTWARE_PRODUCT]: { + headerText: i18n('VSP'), + contentIconName: 'vsp', + color: 'blue' + } }; const CatalogItemDetails = ({catalogItemData, catalogItemTypeClass, onSelect, onMigrate}) => { - let {status: itemStatus} = VersionControllerUtils.getCheckOutStatusKindByUserID(catalogItemData.status, catalogItemData.lockingUser); + let {vendorName, name} = catalogItemData; + let {headerText, color, contentIconName} = ITEM_TYPE_MAP[catalogItemTypeClass]; + + let onClick = (e) => { + e.stopPropagation(); + e.preventDefault(); + if (catalogItemData.isOldVersion && catalogItemData.isOldVersion === migrationStatusMapper.OLD_VERSION) { + onMigrate({softwareProduct: catalogItemData}); + } else { + onSelect(); + } + }; return ( - <CatalogTile catalogItemTypeClass={catalogItemTypeClass} onSelect={() => { - if (catalogItemData.isOldVersion && catalogItemData.isOldVersion === migrationStatusMapper.OLD_VERSION) { - onMigrate({ - softwareProduct: catalogItemData - }); - } - else { - onSelect(); - } - }} data-test-id={catalogItemTypeClass}> - <div className='catalog-tile-top item-details'> - <ItemTypeTitle catalogItemTypeClass={catalogItemTypeClass}/> - <CatalogTileIcon catalogItemTypeClass={catalogItemTypeClass}/> - <EntityDetails catalogItemTypeClass={catalogItemTypeClass} catalogItemData={catalogItemData}/> - <ItemStatusInfo itemStatus={itemStatus} catalogItemTypeClass={catalogItemTypeClass} lockingUser={catalogItemData.lockingUser}/> - </div> - </CatalogTile> + <Tile + headerText={headerText} + headerColor={color} + iconName={contentIconName} + iconColor={color} + onClick={onClick} + dataTestId={catalogItemTypeClass}> + <TileInfo data-test-id='catalog-item-content'> + {vendorName && + <TileInfoLine type='supertitle'> + <TooltipWrapper className='with-overlay' tooltipClassName='tile-super-info' dataTestId='catalog-item-vendor-name'>{vendorName}</TooltipWrapper> + </TileInfoLine> + } + <TileInfoLine type='title'> + <TooltipWrapper className='with-overlay' tooltipClassName='tile-title-info' dataTestId='catalog-item-name'>{name}</TooltipWrapper> + </TileInfoLine> + </TileInfo> + </Tile> ); }; CatalogItemDetails.PropTypes = { - catalogItemData: React.PropTypes.obj, - catalogItemTypeClass: React.PropTypes.string, - onSelect: React.PropTypes.func, - onMigrate: React.PropTypes.func + catalogItemData: PropTypes.obj, + catalogItemTypeClass: PropTypes.string, + onSelect: PropTypes.func, + onMigrate: PropTypes.func }; export default CatalogItemDetails; - diff --git a/openecomp-ui/src/sdc-app/onboarding/onboard/CatalogItemDetails.stories.js b/openecomp-ui/src/sdc-app/onboarding/onboard/CatalogItemDetails.stories.js index c4e2724eaf..156adfc5e7 100644 --- a/openecomp-ui/src/sdc-app/onboarding/onboard/CatalogItemDetails.stories.js +++ b/openecomp-ui/src/sdc-app/onboarding/onboard/CatalogItemDetails.stories.js @@ -2,35 +2,32 @@ import React from 'react'; import {storiesOf, action} from '@kadira/storybook'; import {select, withKnobs} from '@kadira/storybook-addon-knobs'; import CatalogItemDetails from './CatalogItemDetails.jsx'; +import {catalogItemTypes, catalogItemStatuses} from './onboardingCatalog/OnboardingCatalogConstants.js'; import {FinalizedLicenseModelFactory} from 'test-utils/factories/licenseModel/LicenseModelFactories.js'; -import {statusEnum} from 'nfvo-components/panel/versionController/VersionControllerConstants.js'; - - const stories = storiesOf('CatalogTiles', module); stories.addDecorator(withKnobs); const types = [ - 'license-model-type', - 'software-product-type' + catalogItemTypes.LICENSE_MODEL, + catalogItemTypes.SOFTWARE_PRODUCT ]; function selectType() { - return select('Item type' , types, types[0]); + return select('Item type' , types, types[0]); } -let vlm = FinalizedLicenseModelFactory.build({name: 'Test-VLM'}); -let unclockedVlm = {...vlm, status: statusEnum.CHECK_OUT_STATUS}; - +let vlm = {...FinalizedLicenseModelFactory.build({name: 'Test-VLM'}), itemStatus: catalogItemStatuses.DRAFT}; +let certifiedVlm = {...vlm, itemStatus: catalogItemStatuses.CERTIFIED}; stories - .add('preview', () => ( - <div className='catalog-view'> - <div className='catalog-list'> - <div className='catalog-items'> - <CatalogItemDetails catalogItemData={vlm} catalogItemTypeClass={selectType()} onSelect={action('onSelect')} onMigrate={action('onMigrate')}/> - <CatalogItemDetails catalogItemData={unclockedVlm} catalogItemTypeClass={selectType()} onSelect={action('onSelect')} onMigrate={action('onMigrate')}/> - </div> - </div> - </div> - )); + .add('preview', () => ( + <div className='catalog-view'> + <div className='catalog-list'> + <div className='catalog-items'> + <CatalogItemDetails catalogItemData={vlm} catalogItemTypeClass={selectType()} onSelect={action('onSelect')} onMigrate={action('onMigrate')}/> + <CatalogItemDetails catalogItemData={certifiedVlm} catalogItemTypeClass={selectType()} onSelect={action('onSelect')} onMigrate={action('onMigrate')}/> + </div> + </div> + </div> + )); diff --git a/openecomp-ui/src/sdc-app/onboarding/onboard/CatalogList.jsx b/openecomp-ui/src/sdc-app/onboarding/onboard/CatalogList.jsx index 7664f6abaa..03efa19533 100644 --- a/openecomp-ui/src/sdc-app/onboarding/onboard/CatalogList.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/onboard/CatalogList.jsx @@ -21,7 +21,7 @@ const SoftwareProductListHeader = ({selectedVendor, onBack}) => ( <div className='vendor-page-header'> <SVGIcon name='back' onClick={onBack}/> <div className='tab-separator' /> - <div className='vendor-name'>{selectedVendor.vendorName}</div> + <div className='vendor-name'>{selectedVendor.name}</div> </div> ); @@ -30,9 +30,8 @@ const CatalogList = ({children, onAddVLM, onAddVSP, vendorPageOptions}) => ( {vendorPageOptions && <SoftwareProductListHeader onBack={vendorPageOptions.onBack} selectedVendor={vendorPageOptions.selectedVendor}/>} <div className='catalog-items'> <div className='create-catalog-item-wrapper'> - {onAddVLM && <CreateItemTile onClick={onAddVLM} dataTestId={'catalog-add-new-lm'} className='vlm-type' title={i18n('CREATE NEW VLM')}/>} - {onAddVSP && - <CreateItemTile onClick={onAddVSP} dataTestId={'catalog-add-new-vsp'} className='vsp-type' title={i18n('CREATE NEW VSP')}/>} + {onAddVLM && <CreateItemTile onClick={onAddVLM} dataTestId={'catalog-add-new-vlm'} className='vlm-type' title={i18n('CREATE NEW VLM')}/>} + {onAddVSP && <CreateItemTile onClick={() => onAddVSP()} dataTestId={'catalog-add-new-vsp'} className='vsp-type' title={i18n('CREATE NEW VSP')}/>} </div> {children} </div> @@ -42,7 +41,7 @@ const CatalogList = ({children, onAddVLM, onAddVSP, vendorPageOptions}) => ( const CreateItemTile = ({onClick, dataTestId, title, className = ''}) => { //TODO check for buttons return ( - <div className={'create-catalog-item tile ' + className} onClick={() => onClick()} data-test-id={dataTestId}> + <div className={`create-catalog-item tile ${className}`} onClick={onClick} data-test-id={dataTestId}> <div className='create-item-plus-icon'><SVGIcon name='plus' /></div> <div className='create-item-text'>{title}</div> </div> diff --git a/openecomp-ui/src/sdc-app/onboarding/onboard/DetailsCatalogView.jsx b/openecomp-ui/src/sdc-app/onboarding/onboard/DetailsCatalogView.jsx index ef54848523..887517238b 100644 --- a/openecomp-ui/src/sdc-app/onboarding/onboard/DetailsCatalogView.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/onboard/DetailsCatalogView.jsx @@ -14,7 +14,8 @@ * permissions and limitations under the License. */ import React from 'react'; -import {catalogItemTypes, modalMapper, catalogItemTypeClasses} from './onboardingCatalog/OnboardingCatalogConstants.js'; +import PropTypes from 'prop-types'; +import {catalogItemTypes} from './onboardingCatalog/OnboardingCatalogConstants.js'; import {filterCatalogItemsByType} from './onboardingCatalog/OnboardingCatalogUtils.js'; import CatalogList from './CatalogList.jsx'; import CatalogItemDetails from './CatalogItemDetails.jsx'; @@ -22,33 +23,32 @@ import CatalogItemDetails from './CatalogItemDetails.jsx'; class DetailsCatalogView extends React.Component{ static propTypes = { - VLMList: React.PropTypes.array, - VSPList: React.PropTypes.array, - onSelectVLM: React.PropTypes.func.isRequired, - onSelectVSP: React.PropTypes.func.isRequired, - onAddVLM: React.PropTypes.func.isRequired, - onAddVSP: React.PropTypes.func.isRequired, - filter: React.PropTypes.string.isRequired + VLMList: PropTypes.array, + VSPList: PropTypes.array, + onSelectVLM: PropTypes.func.isRequired, + onSelectVSP: PropTypes.func.isRequired, + onAddVLM: PropTypes.func.isRequired, + onAddVSP: PropTypes.func.isRequired, + filter: PropTypes.string.isRequired }; - renderCatalogItems(items, type, filter, onSelect, onMigrate, tileType){ - return filterCatalogItemsByType(items, type, filter).map(item => - <CatalogItemDetails - key={item.id} - catalogItemData={type === catalogItemTypes.LICENSE_MODEL ? {...item, name: item.vendorName} : item} - catalogItemTypeClass={catalogItemTypeClasses[modalMapper[type]]} - onMigrate={onMigrate} - onSelect={() => onSelect(item)} - tileType={tileType} /> + renderCatalogItems({items, type, filter, onSelect, onMigrate, users}){ + return filterCatalogItemsByType({items, filter}).map(item => + <CatalogItemDetails + key={item.id} + catalogItemData={item} + catalogItemTypeClass={type} + onMigrate={onMigrate} + onSelect={() => onSelect(item, users)} /> ); } render() { - let {VLMList, VSPList, onAddVSP, onAddVLM, onSelectVLM, onSelectVSP, filter = '', onMigrate, tileType} = this.props; + let {VLMList, VSPList, users, onAddVSP, onAddVLM, onSelectVLM, onSelectVSP, filter = '', onMigrate} = this.props; return ( <CatalogList onAddVLM={onAddVLM} onAddVSP={onAddVSP}> - {this.renderCatalogItems(VLMList, catalogItemTypes.LICENSE_MODEL, filter, onSelectVLM, onMigrate, tileType)} - {this.renderCatalogItems(VSPList, catalogItemTypes.SOFTWARE_PRODUCT, filter, onSelectVSP, onMigrate, tileType)} + {this.renderCatalogItems({items: VLMList, type: catalogItemTypes.LICENSE_MODEL, filter, onSelect: onSelectVLM, onMigrate, users})} + {this.renderCatalogItems({items: VSPList, type: catalogItemTypes.SOFTWARE_PRODUCT, filter, onSelect: onSelectVSP, onMigrate, users})} </CatalogList> ); } diff --git a/openecomp-ui/src/sdc-app/onboarding/onboard/Onboard.js b/openecomp-ui/src/sdc-app/onboarding/onboard/Onboard.js index b13ccbbba2..3422920b3a 100644 --- a/openecomp-ui/src/sdc-app/onboarding/onboard/Onboard.js +++ b/openecomp-ui/src/sdc-app/onboarding/onboard/Onboard.js @@ -16,20 +16,36 @@ import {connect} from 'react-redux'; import OnboardView from './OnboardView.jsx'; -import OnboardingActionHelper from '../OnboardingActionHelper.js'; import OnboardingCatalogActionHelper from './onboardingCatalog/OnboardingCatalogActionHelper.js'; import OnboardActionHelper from './OnboardActionHelper.js'; import LicenseModelCreationActionHelper from '../licenseModel/creation/LicenseModelCreationActionHelper.js'; import SoftwareProductCreationActionHelper from '../softwareProduct/creation/SoftwareProductCreationActionHelper.js'; import sortByStringProperty from 'nfvo-utils/sortByStringProperty.js'; +import ScreensHelper from 'sdc-app/common/helpers/ScreensHelper.js'; +import {enums, screenTypes} from 'sdc-app/onboarding/OnboardingConstants.js'; + export const mapStateToProps = ({ - onboard: {onboardingCatalog, activeTab, searchValue}, licenseModelList, finalizedLicenseModelList, softwareProductList, finalizedSoftwareProductList + onboard: { + onboardingCatalog, + activeTab, + searchValue + }, + licenseModelList, + users, + finalizedLicenseModelList, + softwareProductList, + finalizedSoftwareProductList }) => { - const reduceLicenseModelList = (accum, vlm)=> { + const fullSoftwareProducts = softwareProductList.filter(vsp => + !finalizedSoftwareProductList + .find(fvsp => fvsp.id === vsp.id) + ).concat(finalizedSoftwareProductList); + + const reduceLicenseModelList = (accum, vlm) => { let currentSoftwareProductList = sortByStringProperty( - finalizedSoftwareProductList + fullSoftwareProducts .filter(vsp => vsp.vendorId === vlm.id), 'name' ); @@ -37,19 +53,22 @@ export const mapStateToProps = ({ return accum; }; - finalizedLicenseModelList = sortByStringProperty( + licenseModelList = sortByStringProperty( licenseModelList - .filter(vlm => finalizedLicenseModelList.map(finalVlm => finalVlm.id).includes(vlm.id)) .reduce(reduceLicenseModelList, []), - 'vendorName' + 'name' ); - finalizedSoftwareProductList = sortByStringProperty( - softwareProductList - .filter(vsp => finalizedSoftwareProductList.map(finalVsp => finalVsp.id).includes(vsp.id)), + finalizedLicenseModelList = sortByStringProperty( + finalizedLicenseModelList + .reduce(reduceLicenseModelList, []), 'name' ); + const fullLicenseModelList = licenseModelList.filter(vlm => + !finalizedLicenseModelList + .find(fvlm => fvlm.id === vlm.id) + ).concat(finalizedLicenseModelList); let {activeTab: catalogActiveTab, vendorCatalog: {vspOverlay, selectedVendor}} = onboardingCatalog; @@ -58,22 +77,32 @@ export const mapStateToProps = ({ finalizedSoftwareProductList, licenseModelList, softwareProductList, + fullLicenseModelList, activeTab, catalogActiveTab, searchValue, vspOverlay, - selectedVendor + selectedVendor, + users: users.usersList }; + }; const mapActionsToProps = (dispatch) => { + return { - onSelectLicenseModel({id: licenseModelId, version}) { - OnboardingActionHelper.navigateToLicenseModelOverview(dispatch, {licenseModelId, version}); + onSelectLicenseModel({id: licenseModelId, name}, users) { + ScreensHelper.loadScreen(dispatch, { + screen: enums.SCREEN.VERSIONS_PAGE, screenType: screenTypes.LICENSE_MODEL, + props: {licenseModelId, licenseModel: {name}, usersList: users} + }); }, - onSelectSoftwareProduct(softwareProduct) { - let {id: softwareProductId, vendorId: licenseModelId, licensingVersion, version} = softwareProduct; - OnboardingActionHelper.navigateToSoftwareProductLandingPage(dispatch, {softwareProductId, version, licenseModelId, licensingVersion}); + onSelectSoftwareProduct(softwareProduct, users) { + let {id: softwareProductId, vendorId: licenseModelId, licensingVersion, name} = softwareProduct; + ScreensHelper.loadScreen(dispatch, { + screen: enums.SCREEN.SOFTWARE_PRODUCT_VERSIONS_PAGE, screenType: screenTypes.SOFTWARE_PRODUCT, + props: {softwareProductId, softwareProduct: {name, vendorId: licenseModelId, licensingVersion}, usersList: users} + }); }, onAddSoftwareProductClick: (vendorId) => SoftwareProductCreationActionHelper.open(dispatch, vendorId), onAddLicenseModelClick: () => LicenseModelCreationActionHelper.open(dispatch), @@ -85,6 +114,7 @@ const mapActionsToProps = (dispatch) => { onVendorSelect: (vendor) => OnboardingCatalogActionHelper.onVendorSelect(dispatch, {vendor}), onMigrate: ({softwareProduct}) => OnboardingCatalogActionHelper.onMigrate(dispatch, softwareProduct) }; + }; export default connect(mapStateToProps, mapActionsToProps)(OnboardView); diff --git a/openecomp-ui/src/sdc-app/onboarding/onboard/OnboardView.jsx b/openecomp-ui/src/sdc-app/onboarding/onboard/OnboardView.jsx index b7a7fa5f68..f31ce4c805 100644 --- a/openecomp-ui/src/sdc-app/onboarding/onboard/OnboardView.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/onboard/OnboardView.jsx @@ -14,6 +14,7 @@ * permissions and limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import OnboardingCatalogView from './onboardingCatalog/OnboardingCatalogView.jsx'; import WorkspaceView from './workspace/WorkspaceView.jsx'; import {tabsMapping} from './OnboardConstants.js'; @@ -22,6 +23,7 @@ import classnames from 'classnames'; import ExpandableInput from 'nfvo-components/input/ExpandableInput.jsx'; import objectValues from 'lodash/values.js'; import {catalogItemTypes} from './onboardingCatalog/OnboardingCatalogConstants.js'; +import NotificationsView from 'sdc-app/onboarding/userNotifications/NotificationsView.jsx'; const OnboardHeaderTabs = ({onTabClick, activeTab}) => ( <div className='onboard-header-tabs'> @@ -47,29 +49,30 @@ const OnboardHeader = ({onSearch, activeTab, onTabClick, searchValue}) => ( onChange={onSearch} iconType='search' value={searchValue}/> + <NotificationsView /> </div> ); class OnboardView extends React.Component { static propTypes = { - licenseModelList: React.PropTypes.array, - softwareProductList: React.PropTypes.array, - finalizedLicenseModelList: React.PropTypes.array, - finalizedSoftwareProductList: React.PropTypes.array, - modalToShow: React.PropTypes.oneOf(objectValues(catalogItemTypes)), - onSelectLicenseModel: React.PropTypes.func.isRequired, - onSelectSoftwareProduct: React.PropTypes.func.isRequired, - onAddLicenseModelClick: React.PropTypes.func.isRequired, - onAddSoftwareProductClick: React.PropTypes.func.isRequired, - closeVspOverlay: React.PropTypes.func.isRequired, - onVspOverlayChange: React.PropTypes.func.isRequired, - onTabClick: React.PropTypes.func.isRequired, - onCatalogTabClick: React.PropTypes.func.isRequired, - onSearch: React.PropTypes.func.isRequired, - activeTab: React.PropTypes.number.isRequired, - catalogActiveTab: React.PropTypes.number.isRequired, - searchValue: React.PropTypes.string.isRequired, - onMigrate: React.PropTypes.func.isRequired, + licenseModelList: PropTypes.array, + softwareProductList: PropTypes.array, + finalizedLicenseModelList: PropTypes.array, + finalizedSoftwareProductList: PropTypes.array, + modalToShow: PropTypes.oneOf(objectValues(catalogItemTypes)), + onSelectLicenseModel: PropTypes.func.isRequired, + onSelectSoftwareProduct: PropTypes.func.isRequired, + onAddLicenseModelClick: PropTypes.func.isRequired, + onAddSoftwareProductClick: PropTypes.func.isRequired, + closeVspOverlay: PropTypes.func.isRequired, + onVspOverlayChange: PropTypes.func.isRequired, + onTabClick: PropTypes.func.isRequired, + onCatalogTabClick: PropTypes.func.isRequired, + onSearch: PropTypes.func.isRequired, + activeTab: PropTypes.number.isRequired, + catalogActiveTab: PropTypes.number.isRequired, + searchValue: PropTypes.string.isRequired, + onMigrate: PropTypes.func.isRequired, }; renderViewByTab(activeTab){ switch (activeTab){ @@ -82,9 +85,9 @@ class OnboardView extends React.Component { } render() { - let {closeVspOverlay, activeTab, onTabClick, onSearch, searchValue} = this.props; + let {activeTab, onTabClick, onSearch, searchValue} = this.props; return ( - <div className='catalog-view' onClick={closeVspOverlay}> + <div className='catalog-view'> <OnboardHeader activeTab={activeTab} onTabClick={onTabClick} searchValue={searchValue} onSearch={value => onSearch(value)}/> {this.renderViewByTab(activeTab)} </div> diff --git a/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/OnboardingCatalogActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/OnboardingCatalogActionHelper.js index 0d1e3992ce..a85c79edd9 100644 --- a/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/OnboardingCatalogActionHelper.js +++ b/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/OnboardingCatalogActionHelper.js @@ -17,8 +17,6 @@ import React from 'react'; import i18n from 'nfvo-utils/i18n/i18n.js'; import {actionTypes} from './OnboardingCatalogConstants.js'; import {actionTypes as modalActionTypes} from 'nfvo-components/modal/GlobalModalConstants.js'; -import {statusEnum} from 'nfvo-components/panel/versionController/VersionControllerConstants.js'; -import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js'; import OnboardActionHelper from '../OnboardActionHelper.js'; import SoftwareProductActionHelper from 'sdc-app/onboarding/softwareProduct/SoftwareProductActionHelper.js'; @@ -26,7 +24,7 @@ import SoftwareProductActionHelper from 'sdc-app/onboarding/softwareProduct/Soft function getMessageForMigration(name) { return ( <div> - <div>{i18n(`${name} needs to be updated. Click ‘Checkout & Update’, to proceed.`)}</div> + <div>{i18n('{name} needs to be updated. Click ‘Checkout & Update’, to proceed.', {name: name})}</div> <div>{i18n('Please don’t forget to submit afterwards')}</div> </div> ); @@ -57,28 +55,28 @@ const OnboardingCatalogActionHelper = { type: actionTypes.ONBOARDING_CATALOG_OPEN_VENDOR_PAGE, selectedVendor: vendor }); - }, + }, onMigrate(dispatch, softwareProduct) { - const {status, name, lockingUser} = softwareProduct; - if (status === statusEnum.CHECK_OUT_STATUS && !VersionControllerUtils.isCheckedOutByCurrentUser(softwareProduct)) { + const {name, lockingUser} = softwareProduct; + if (NaN === NaN) { // TODO dispatch({ - type: modalActionTypes.GLOBAL_MODAL_WARNING, + type: modalActionTypes.GLOBAL_MODAL_WARNING, data: { title: 'WARNING', - msg: i18n(`${name} is locked by user ${lockingUser} for self-healing`) + msg: i18n('{name} is locked by user {lockingUser} for self-healing', {name: name, lockingUser: lockingUser}) } }); - } else { + } else { dispatch({ type: modalActionTypes.GLOBAL_MODAL_WARNING, data:{ title: 'WARNING', - msg: getMessageForMigration(softwareProduct.name.toUpperCase()), + msg: getMessageForMigration(softwareProduct.name.toUpperCase()), confirmationButtonText: i18n('Checkout & Update'), onConfirmed: ()=>SoftwareProductActionHelper.migrateSoftwareProduct(dispatch, {softwareProduct}) } }); - } + } } }; diff --git a/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/OnboardingCatalogConstants.js b/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/OnboardingCatalogConstants.js index 071160c4fd..a1bf1b1fc8 100644 --- a/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/OnboardingCatalogConstants.js +++ b/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/OnboardingCatalogConstants.js @@ -24,7 +24,11 @@ export const catalogItemTypeClasses = { LICENSE_MODEL: 'license-model-type', SOFTWARE_PRODUCT: 'software-product-type', VENDOR: 'vendor-type' +}; +export const catalogItemStatuses = { + DRAFT: 'Draft', + CERTIFIED: 'Certified' }; export const modalMapper = { diff --git a/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/OnboardingCatalogUtils.js b/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/OnboardingCatalogUtils.js index ac623db920..78258255ec 100644 --- a/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/OnboardingCatalogUtils.js +++ b/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/OnboardingCatalogUtils.js @@ -13,9 +13,7 @@ * or implied. See the License for the specific language governing * permissions and limitations under the License. */ -import {catalogItemTypes} from './OnboardingCatalogConstants.js'; -export const filterCatalogItemsByType = (items, type, filter) => { - const fieldName = type === catalogItemTypes.LICENSE_MODEL ? 'vendorName' : 'name'; - return items.filter(item => item[fieldName].toLowerCase().indexOf(filter.toLowerCase()) > -1); +export const filterCatalogItemsByType = ({items, filter}) => { + return items.filter(item => item.name.toLowerCase().indexOf(filter.toLowerCase()) > -1); }; diff --git a/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/OnboardingCatalogView.jsx b/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/OnboardingCatalogView.jsx index b1f002d2fb..1004472ec3 100644 --- a/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/OnboardingCatalogView.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/OnboardingCatalogView.jsx @@ -46,14 +46,16 @@ const CatalogHeader = ({activeTab, onTabPress}) => ( class OnboardingCatalogView extends React.Component { renderViewByTab(activeTab){ - const {finalizedLicenseModelList: licenseModelList, vspOverlay, finalizedSoftwareProductList: softwareProductList, onSelectLicenseModel, onSelectSoftwareProduct, + const {finalizedLicenseModelList: licenseModelList, fullLicenseModelList, users, vspOverlay, finalizedSoftwareProductList: softwareProductList, onSelectLicenseModel, onSelectSoftwareProduct, onAddLicenseModelClick, onAddSoftwareProductClick, onVspOverlayChange, onVendorSelect, selectedVendor, searchValue, onMigrate} = this.props; + switch (activeTab){ case tabsMapping.ALL: return ( <DetailsCatalogView VLMList={licenseModelList} VSPList={softwareProductList} + users={users} onAddVLM={onAddLicenseModelClick} onAddVSP={onAddSoftwareProductClick} onSelectVLM={onSelectLicenseModel} @@ -65,7 +67,8 @@ class OnboardingCatalogView extends React.Component { default: return ( <VendorCatalogView - licenseModelList={licenseModelList} + licenseModelList={fullLicenseModelList} + users={users} onAddVSP={onAddSoftwareProductClick} onAddVLM={onAddLicenseModelClick} onSelectVSP={onSelectSoftwareProduct} diff --git a/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/Tooltip.jsx b/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/Tooltip.jsx index 8d8d1162a0..80d9b07ac9 100644 --- a/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/Tooltip.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/Tooltip.jsx @@ -16,9 +16,16 @@ import React from 'react'; import Tooltip from 'react-bootstrap/lib/Tooltip.js'; +import OverlayTrigger from 'react-bootstrap/lib/OverlayTrigger.js'; -export default function tooltip (msg) { - return ( - <Tooltip className='tile-tooltip' id='tile-tooltip'>{msg}</Tooltip> - ); -}; +const tooltip = (msg, className = '') => ( + <Tooltip className={className} id={className}>{msg}</Tooltip> +); + +export const TooltipWrapper = ({placement = 'top', className = '', tooltipClassName = '', dataTestId, delayShow = 0, children}) => ( + <OverlayTrigger placement={placement} overlay={tooltip(children, tooltipClassName)} delayShow={delayShow}> + <div className={className} data-test-id={dataTestId}>{children}</div> + </OverlayTrigger> +); + +export default tooltip; diff --git a/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/VSPOverlay.jsx b/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/VSPOverlay.jsx index 1ba4834fa3..a2852e5afa 100644 --- a/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/VSPOverlay.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/VSPOverlay.jsx @@ -14,6 +14,7 @@ * permissions and limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import i18n from 'nfvo-utils/i18n/i18n.js'; import {migrationStatusMapper} from './OnboardingCatalogConstants.js'; @@ -43,8 +44,8 @@ const VSPOverlay = ({VSPList, onSelectVSP, onSeeMore, onMigrate}) => ( ); VSPOverlay.PropTypes = { - VSPList: React.PropTypes.array, - onSelectVSP: React.PropTypes.func + VSPList: PropTypes.array, + onSelectVSP: PropTypes.func }; export default VSPOverlay; diff --git a/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/VendorCatalogView.jsx b/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/VendorCatalogView.jsx index c4e0599d85..9914ea2154 100644 --- a/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/VendorCatalogView.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/VendorCatalogView.jsx @@ -17,20 +17,20 @@ import React from 'react'; import VendorItem from './VendorItem.jsx'; import CatalogList from '../CatalogList.jsx'; import CatalogItemDetails from '../CatalogItemDetails.jsx'; -import {catalogItemTypes, catalogItemTypeClasses} from './OnboardingCatalogConstants.js'; +import {catalogItemTypes} from './OnboardingCatalogConstants.js'; import {filterCatalogItemsByType} from './OnboardingCatalogUtils.js'; -const VendorList = ({onAddVLM, onAddVSP, onSelectVSP, licenseModelList = [], vspOverlay: currentOverlay, onVspOverlayChange, onVendorSelect, filter, onMigrate}) => { +const VendorList = ({onAddVLM, onAddVSP, onSelectVSP, licenseModelList = [], vspOverlay: currentOverlay, onVspOverlayChange, onVendorSelect, filter, onMigrate, users}) => { return( <CatalogList onAddVLM={onAddVLM} onAddVSP={onAddVSP}> { - filterCatalogItemsByType(licenseModelList, catalogItemTypes.LICENSE_MODEL, filter).map(vlm => + filterCatalogItemsByType({items: licenseModelList, filter}).map(vlm => <VendorItem key={vlm.id} onAddVSP={onAddVSP} - onSelectVSP={onSelectVSP} + onSelectVSP={(vsp) => onSelectVSP(vsp, users)} shouldShowOverlay={currentOverlay === vlm.id} - onVSPIconClick={(hasVSP) => onVspOverlayChange(vlm.id === currentOverlay || !hasVSP ? null : vlm)} + onVSPButtonClick={(hasVSP) => onVspOverlayChange(vlm.id === currentOverlay || !hasVSP ? null : vlm)} onVendorSelect={onVendorSelect} onMigrate={onMigrate} vendor={vlm}/>) @@ -39,23 +39,23 @@ const VendorList = ({onAddVLM, onAddVSP, onSelectVSP, licenseModelList = [], vsp ); }; -const SoftwareProductListByVendor = ({onAddVSP, selectedVendor, onVendorSelect, onSelectVSP, onSelectVLM, filter, onMigrate}) => { +const SoftwareProductListByVendor = ({onAddVSP, selectedVendor, onVendorSelect, onSelectVSP, onSelectVLM, filter, onMigrate, users}) => { return( <div> <CatalogList onAddVSP={()=>{onAddVSP(selectedVendor.id);}} vendorPageOptions={{selectedVendor, onBack: () => onVendorSelect(false)}}> <CatalogItemDetails key={selectedVendor.id} - onSelect={() => onSelectVLM(selectedVendor)} - catalogItemTypeClass={catalogItemTypeClasses.LICENSE_MODEL} + onSelect={() => onSelectVLM(selectedVendor, users)} + catalogItemTypeClass={catalogItemTypes.LICENSE_MODEL} onMigrate={onMigrate} - catalogItemData={{...selectedVendor, name: selectedVendor.vendorName}}/> + catalogItemData={selectedVendor}/> { - filterCatalogItemsByType(selectedVendor.softwareProductList, catalogItemTypes.SOFTWARE_PRODUCT, filter).map(vsp => + filterCatalogItemsByType({items: selectedVendor.softwareProductList, filter}).map(vsp => <CatalogItemDetails key={vsp.id} - catalogItemTypeClass={catalogItemTypeClasses.SOFTWARE_PRODUCT} + catalogItemTypeClass={catalogItemTypes.SOFTWARE_PRODUCT} onMigrate={onMigrate} - onSelect={() => onSelectVSP(vsp)} + onSelect={() => onSelectVSP(vsp, users)} catalogItemData={vsp}/> ) } diff --git a/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/VendorItem.jsx b/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/VendorItem.jsx index d3d6f9ce37..158282cc48 100644 --- a/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/VendorItem.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/VendorItem.jsx @@ -14,81 +14,82 @@ * permissions and limitations under the License. */ import React from 'react'; -import {catalogItemTypeClasses} from './OnboardingCatalogConstants.js'; -import CatalogTile from '../CatalogTile.jsx'; -import classnames from 'classnames'; -import VSPOverlay from './VSPOverlay.jsx'; +import PropTypes from 'prop-types'; import i18n from 'nfvo-utils/i18n/i18n.js'; -import SVGIcon from 'sdc-ui/lib/react/SVGIcon.js'; -import OverlayTrigger from 'react-bootstrap/lib/OverlayTrigger.js'; -import tooltip from './Tooltip.jsx'; +import {Tile, TileInfo, TileInfoLine, TileFooter, TileFooterCell, Button} from 'sdc-ui/lib/react'; +import VSPOverlay from './VSPOverlay.jsx'; +import {TooltipWrapper} from './Tooltip.jsx'; class VendorItem extends React.Component { static PropTypes = { - softwareProductList: React.PropTypes.array, - vendor: React.PropTypes.object, - onSelectVSP: React.PropTypes.func, - shouldShowOverlay: React.PropTypes.boolm, - onVendorSelect: React.PropTypes.func, - onAddVSP: React.PropTypes.func, - onVSPIconClick: React.PropTypes.func, - + softwareProductList: PropTypes.array, + vendor: PropTypes.object, + shouldShowOverlay: PropTypes.bool, + onSelectVSP: PropTypes.func, + onVendorSelect: PropTypes.func, + onAddVSP: PropTypes.func, + onVSPButtonClick: PropTypes.func }; render() { let {vendor, onSelectVSP, shouldShowOverlay, onVendorSelect, onMigrate} = this.props; - let {softwareProductList = [], vendorName} = vendor; + let {softwareProductList = [], name} = vendor; return ( - <CatalogTile - catalogItemTypeClass={catalogItemTypeClasses.VENDOR} - onSelect={() => onVendorSelect(vendor)}> - <div className='catalog-tile-top'> - <div className='catalog-tile-icon vendor-type'> - <div className='icon'><SVGIcon name='vendor'/></div> - </div> - <OverlayTrigger placement='top' overlay={tooltip(vendorName)}> - <div className='catalog-tile-item-name'>{vendorName}</div> - </OverlayTrigger> - <div - className={classnames('catalog-tile-vsp-count', {active: shouldShowOverlay}, {clickable: softwareProductList.length})} - onClick={(event) => this.handleVspCountClick(event)} - data-test-id='catalog-vsp-count'> - {i18n(`${softwareProductList.length} VSPs`)} - </div> - <div className='catalog-tile-content' onClick={(event) => this.onCreateVspClick(event)} data-test-id='catalog-create-new-vsp-from-vendor'> - <div className='create-new-vsp-button'> - <SVGIcon name='plus'/> {i18n('Create new VSP')} - </div> - </div> - </div> - - {shouldShowOverlay && softwareProductList.length > 0 - && <VSPOverlay onMigrate={onMigrate} VSPList={softwareProductList} onSelectVSP={onSelectVSP} onSeeMore={() => onVendorSelect(vendor)}/>} - </CatalogTile> + <Tile + iconName='vendor' + onClick={() => onVendorSelect(vendor)}> + <TileInfo align='center'> + <TileInfoLine type='title'> + <TooltipWrapper className='with-overlay' dataTestId='catalog-item-name'>{name}</TooltipWrapper> + </TileInfoLine> + <TileInfoLine> + <Button + btnType='outline-rounded' + color='dark-gray' + onClick={e => this.handleVspCountClick(e)} + data-test-id='catalog-vsp-count' + disabled={!softwareProductList.length}> + {i18n('{length} VSPs', {length: softwareProductList.length})} + </Button> + {shouldShowOverlay && softwareProductList.length > 0 && + <VSPOverlay + onMigrate={onMigrate} + VSPList={softwareProductList} + onSelectVSP={onSelectVSP} + onSeeMore={() => onVendorSelect(vendor)} /> + } + </TileInfoLine> + </TileInfo> + <TileFooter align='center'> + <TileFooterCell dataTestId='catalog-create-new-vsp-from-vendor'> + <Button + btnType='link' + color='primary' + iconName='plusThin' + onClick={e => this.onCreateVspClick(e)}> + {i18n('Create new VSP')} + </Button> + </TileFooterCell> + </TileFooter> + </Tile> ); } - onClick(vlm) { - this.setState({ - licenseModelToShow: vlm - }); - } - - onCreateVspClick(event) { - let {onAddVSP, vendor: {id}} = this.props; - event.stopPropagation(); - event.preventDefault(); + onCreateVspClick(e) { + e.stopPropagation(); + e.preventDefault(); + const {onAddVSP, vendor: {id}} = this.props; onAddVSP(id); } handleVspCountClick(e){ - let {onVSPIconClick, vendor: {softwareProductList}} = this.props; e.stopPropagation(); e.preventDefault(); + const {onVSPButtonClick, vendor: {softwareProductList}} = this.props; const hasVSP = Boolean(softwareProductList.length); - onVSPIconClick(hasVSP); + onVSPButtonClick(hasVSP); } } diff --git a/openecomp-ui/src/sdc-app/onboarding/onboard/workspace/WorkspaceView.jsx b/openecomp-ui/src/sdc-app/onboarding/onboard/workspace/WorkspaceView.jsx index d86b674f13..523bbb2c8e 100644 --- a/openecomp-ui/src/sdc-app/onboarding/onboard/workspace/WorkspaceView.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/onboard/workspace/WorkspaceView.jsx @@ -15,43 +15,31 @@ */ import React from 'react'; import DetailsCatalogView from '../DetailsCatalogView.jsx'; -import {statusEnum} from 'nfvo-components/panel/versionController/VersionControllerConstants.js'; -import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js'; import i18n from 'nfvo-utils/i18n/i18n.js'; -import {tabsMapping} from 'sdc-app/onboarding/onboard/OnboardConstants.js'; const WorkspaceView = (props) => { let { - licenseModelList, softwareProductList, onAddLicenseModelClick, + licenseModelList, softwareProductList, onAddLicenseModelClick, users, onAddSoftwareProductClick, onSelectLicenseModel, onSelectSoftwareProduct, searchValue, onMigrate } = props; - let {getCheckOutStatusKindByUserID} = VersionControllerUtils; - let unfinalizedLicenseModelList = licenseModelList.filter(vlm => { - let {status} = getCheckOutStatusKindByUserID(vlm.status, vlm.lockingUser); - return status !== statusEnum.SUBMIT_STATUS && status !== statusEnum.LOCK_STATUS; - }); - let unfinalizedSoftwareProductList = softwareProductList.filter(vsp =>{ - let {status} = getCheckOutStatusKindByUserID(vsp.status, vsp.lockingUser); - return status !== statusEnum.SUBMIT_STATUS && status !== statusEnum.LOCK_STATUS; - }); - return ( <div className='catalog-wrapper workspace-view'> <div className='catalog-header workspace-header'> {i18n('WORKSPACE')} </div> <DetailsCatalogView - VLMList={unfinalizedLicenseModelList} - VSPList={unfinalizedSoftwareProductList} + VLMList={licenseModelList} + VSPList={softwareProductList} + users={users} onAddVLM={onAddLicenseModelClick} onAddVSP={onAddSoftwareProductClick} onSelectVLM={onSelectLicenseModel} onSelectVSP={onSelectSoftwareProduct} onMigrate={onMigrate} - filter={searchValue} - tileType={tabsMapping.WORKSPACE} /> - </div>); + filter={searchValue} /> + </div> + ); }; export default WorkspaceView; diff --git a/openecomp-ui/src/sdc-app/onboarding/permissions/PermissionsActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/permissions/PermissionsActionHelper.js new file mode 100644 index 0000000000..c25d93f2fc --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/permissions/PermissionsActionHelper.js @@ -0,0 +1,108 @@ +/*! + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +import i18n from 'nfvo-utils/i18n/i18n.js'; +import {actionTypes as modalActionTypes} from 'nfvo-components/modal/GlobalModalConstants.js'; +import {actionTypes} from './PermissionsConstants.js'; +import {permissionTypes} from './PermissionsConstants.js'; +import {modalContentMapper} from 'sdc-app/common/modal/ModalContentMapper.js'; +import {askForRightsMsg} from './PermissionsManager.jsx'; +import ItemsHelper from 'sdc-app/common/helpers/ItemsHelper.js'; + +const PermissionsActionHelper = { + openPermissonsManager(dispatch, {itemId, askForRights}) { + if (askForRights) { + dispatch({ + type: modalActionTypes.GLOBAL_MODAL_SHOW, + data: { + title: i18n('Ask For Contributers Rights'), + msg: askForRightsMsg(), + confirmationButtonText: i18n('SEND'), + onConfirmed: () => this.askForContributorRights() + } + }); + } else { + dispatch({ + type: modalActionTypes.GLOBAL_MODAL_SHOW, + data: { + modalComponentName: modalContentMapper.MANAGE_PERMISSIONS, + title: i18n('Manage Permissions'), + modalComponentProps: { + itemId + } + } + }); + } + }, + + closePermissionManager(dispatch) { + dispatch({ + type: modalActionTypes.GLOBAL_MODAL_CLOSE + }); + }, + + saveItemUsers(dispatch, {itemId, removedUsersIds, addedUsersIds, allUsers}) { + return ItemsHelper.updateContributors({itemId, removedUsersIds, addedUsersIds}).then(() => + PermissionsActionHelper.fetchItemUsers(dispatch, {itemId, allUsers}) + ); + }, + + changeOwner(dispatch, {itemId, newOwnerId, allUsers}) { + return ItemsHelper.changeOwner({itemId, ownerId: newOwnerId}).then(() => + PermissionsActionHelper.fetchItemUsers(dispatch, {itemId, allUsers}) + ); + }, + + fetchItemUsers(dispatch, {itemId, allUsers}) { + return ItemsHelper.fetchUsers({itemId}).then(response => { + + let allContributors = response.results; + + let owner = {}; + let contributors = []; + allContributors.map(user => { + let userObject = allUsers.find(userObject => userObject.userId === user.userId); + if (userObject) { + user = {...user, fullName: userObject.fullName, role: userObject.role}; + + switch(user.permission) { + case permissionTypes.OWNER: + owner = user; + break; + case permissionTypes.CONTRIBUTOR: + contributors.push(user); + break; + } + } + }); + + dispatch({ + type: actionTypes.ITEM_USERS_LOADED, + contributors, + owner + }); + }); + }, + + askForContributorRights() { + console.log('asked for contributor rights'); + } + + + +}; + +export default PermissionsActionHelper; diff --git a/openecomp-ui/src/sdc-app/onboarding/permissions/PermissionsConstants.js b/openecomp-ui/src/sdc-app/onboarding/permissions/PermissionsConstants.js new file mode 100644 index 0000000000..48a3461799 --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/permissions/PermissionsConstants.js @@ -0,0 +1,27 @@ +/*! + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ +import keyMirror from 'nfvo-utils/KeyMirror.js'; + +export const actionTypes = keyMirror({ + ITEM_USERS_LOADED: null +}); + +export const permissionTypes = { + OWNER: 'Owner', + CONTRIBUTOR: 'Contributor' +}; + +export const changeOwnerMessage = 'You will no longer be able to manage the permissions of this item.\nYour permission level will be set to contributor.'; diff --git a/openecomp-ui/src/sdc-app/onboarding/permissions/PermissionsManager.js b/openecomp-ui/src/sdc-app/onboarding/permissions/PermissionsManager.js new file mode 100644 index 0000000000..ba6562b28f --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/permissions/PermissionsManager.js @@ -0,0 +1,43 @@ +/*! + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +import {connect} from 'react-redux'; +import PermissionsManager from './PermissionsManager.jsx'; +import PermissionsActionHelper from './PermissionsActionHelper.js'; + +export const mapStateToProps = ({versionsPage, users: {usersList, userInfo}}) => { + let {permissions} = versionsPage; + + return { + users: usersList, + userInfo, + owner: permissions.owner, + itemUsers: permissions.contributors + }; +}; + +const mapActionsToProps = (dispatch) => { + return { + onCancel: () => PermissionsActionHelper.closePermissionManager(dispatch), + onSubmit: ({itemId, addedUsersIds, removedUsersIds, allUsers, newOwnerId}) => { + return PermissionsActionHelper.saveItemUsers(dispatch,{itemId, addedUsersIds, removedUsersIds, allUsers}).then(() => { + return newOwnerId ? PermissionsActionHelper.changeOwner(dispatch, {itemId, newOwnerId, allUsers}) : Promise.resolve(); + }).then(() => PermissionsActionHelper.closePermissionManager(dispatch)); + } + }; +}; + +export default connect(mapStateToProps, mapActionsToProps)(PermissionsManager); diff --git a/openecomp-ui/src/sdc-app/onboarding/permissions/PermissionsManager.jsx b/openecomp-ui/src/sdc-app/onboarding/permissions/PermissionsManager.jsx new file mode 100644 index 0000000000..b7d5d57cca --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/permissions/PermissionsManager.jsx @@ -0,0 +1,117 @@ +/*! + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ +import React from 'react'; +import Form from 'nfvo-components/input/validation/Form.jsx'; +import Select from 'nfvo-components/input/SelectInput.jsx'; +import SVGIcon from 'sdc-ui/lib/react/SVGIcon.js'; +import OverlayTrigger from 'react-bootstrap/lib/OverlayTrigger.js'; +import Tooltip from 'react-bootstrap/lib/Tooltip.js'; +import i18n from 'nfvo-utils/i18n/i18n.js'; + +import {permissionTypes, changeOwnerMessage} from './PermissionsConstants.js'; + +export const askForRightsMsg = () => { + return ( + <div> + <p>{i18n('Send a Contributor rights reguest to Owner')}</p> + </div> + ); +}; + + +class Permissions extends React.Component { + constructor(props) { + super(props); + this.state = { + itemUsers: props.itemUsers, + newOwnerId: '', + showChangeOwner: false + }; + } + + buildUserOptions() { + let {users, owner} = this.props; + return users.filter(user => user.userId !== owner.userId).map(item => {return {label: item.fullName, value: item.userId};}); + } + + render() { + let {onCancel, owner} = this.props; + let {newOwnerId} = this.state; + return ( + <div className='manage-permissions-page'> + <Form + hasButtons={true} + onSubmit={() => this.onsaveItemUsers()} + onReset={() => onCancel() } + labledButtons={true}> + <div className='manage-permissions-title'>{i18n('Owner')}</div> + <div className='owner-details'> + <span>{owner.fullName}</span> + <span className='change-owner' onClick={() => this.setState({showChangeOwner: !this.state.showChangeOwner})}>{i18n('Change Owner')}</span> + </div> + {this.state.showChangeOwner && <div className='change-owner-wrapper'> + <div className='change-owner-title'> + <span className='manage-permissions-title' data-test-id='change-owner'>{i18n('Change Owner')}</span> + <OverlayTrigger placement='right' trigger='click' overlay={ + <Tooltip id='manage-permissions-owner-tooltip' className='manage-permissions-owner-tooltip'>{i18n(changeOwnerMessage)}</Tooltip> }> + <SVGIcon name='questionMark' /> + </OverlayTrigger> + </div> + <Select + data-test-id='selected-owner' + value={newOwnerId} + onChange={(item) => this.setState({newOwnerId: item ? item.value : ''})} + options={this.buildUserOptions()} /> + </div>} + <div className='manage-permissions-title'>{i18n('Contributors')}</div> + <Select + data-test-id='selected-contributors' + value={this.state.itemUsers.map(item => item.userId)} + className='options-input contributors-select' + clearable={false} + onMultiSelectChanged={(value) => {this.onChangeItemUsers({itemUsers: value});}} + options={this.buildUserOptions()} + multi/> + </Form> + </div> + ); + } + + onChangeItemUsers({itemUsers}) { + this.setState({ + itemUsers: itemUsers.map(contributor => { + let contributorFromProps = this.props.itemUsers.find(user => user.userId === contributor.userId); + return { + userId: contributor.value, + fullName: contributor.label, + permission: contributorFromProps ? contributorFromProps.permission : permissionTypes.CONTRIBUTOR + }; + }) + }); + } + + onsaveItemUsers() { + let {itemUsers: newUsers, newOwnerId} = this.state; + let {itemUsers: oldUsers, onSubmit, itemId, users} = this.props; + let addedUsersIds = newUsers.filter(newUser => !oldUsers.map(oldUser => oldUser.userId).includes(newUser.userId)) + .map(user => user.userId); + let removedUsersIds = oldUsers.filter(oldUser => !newUsers.map(newUser => newUser.userId).includes(oldUser.userId)) + .map(user => user.userId); + onSubmit({itemId, addedUsersIds, removedUsersIds, allUsers: users, newOwnerId}); + } +} + +export default Permissions; diff --git a/openecomp-ui/src/sdc-app/onboarding/permissions/PermissionsReducer.js b/openecomp-ui/src/sdc-app/onboarding/permissions/PermissionsReducer.js new file mode 100644 index 0000000000..b4ab78964d --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/permissions/PermissionsReducer.js @@ -0,0 +1,28 @@ +/*! + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ +import {actionTypes} from './PermissionsConstants.js'; + +export default (state = {}, action) => { + switch (action.type) { + case actionTypes.ITEM_USERS_LOADED: + return { + owner: action.owner, + contributors: action.contributors + }; + default: + return state; + } +};
\ No newline at end of file diff --git a/openecomp-ui/src/sdc-app/onboarding/revisions/Revisions.js b/openecomp-ui/src/sdc-app/onboarding/revisions/Revisions.js new file mode 100644 index 0000000000..73ee5dea21 --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/revisions/Revisions.js @@ -0,0 +1,37 @@ +/*! + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +import {connect} from 'react-redux'; +import RevisionsView from './RevisionsView.jsx'; +import RevisionsActionHelper from './RevisionsActionHelper.js'; + +export const mapStateToProps = ({revisions, users}) => { + return { + revisions: revisions, + users: users.usersList + }; +}; + +export const mapActionsToProps = (dispatch, {itemId, version, itemType}) => { + return { + onCancel: () => RevisionsActionHelper.closeRevisionsView(dispatch), + onRevert: (revisionId) => { + RevisionsActionHelper.revertToRevision(dispatch, {itemId, version, revisionId, itemType}); + } + }; +}; + +export default connect(mapStateToProps, mapActionsToProps, null, {withRef: true})(RevisionsView); diff --git a/openecomp-ui/src/sdc-app/onboarding/revisions/RevisionsActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/revisions/RevisionsActionHelper.js new file mode 100644 index 0000000000..4fd9082b5b --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/revisions/RevisionsActionHelper.js @@ -0,0 +1,100 @@ +/*! + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +import i18n from 'nfvo-utils/i18n/i18n.js'; +import RestAPIUtil from 'nfvo-utils/RestAPIUtil.js'; +import {actionTypes as modalActionTypes} from 'nfvo-components/modal/GlobalModalConstants.js'; +import {actionsEnum as vcActionsEnum} from 'nfvo-components/panel/versionController/VersionControllerConstants.js'; + +import Configuration from 'sdc-app/config/Configuration.js'; +import {modalContentMapper} from 'sdc-app/common/modal/ModalContentMapper.js'; +import ScreensHelper from 'sdc-app/common/helpers/ScreensHelper.js'; +import {enums, screenTypes} from 'sdc-app/onboarding/OnboardingConstants.js'; + +import {actionTypes} from './RevisionsConstants.js'; + +function baseUrl(itemId, version) { + const restPrefix = Configuration.get('restPrefix'); + return `${restPrefix}/v1.0/items/${itemId}/versions/${version.id}`; +} + +function fetchRevisions(itemId, version){ + let fetchUrl = `${baseUrl(itemId, version)}/revisions`; + return RestAPIUtil.fetch(fetchUrl); +} + +function revertToRevision(itemId, version, revisionId) { + let putUrl = `${baseUrl(itemId, version)}/actions`; + let requestBody = { + action: vcActionsEnum.REVERT, + revisionRequest: { + revisionId: revisionId + } + }; + return RestAPIUtil.put(putUrl, requestBody); +} + +const RevisionaActionHelper = { + openRevisionsView(dispatch, {itemId, version, itemType}) { + this.fetchRevisions(dispatch, {itemId, version}).then(() => { + dispatch({ + type: modalActionTypes.GLOBAL_MODAL_SHOW, + data: { + modalComponentName: modalContentMapper.REVISIONS_LIST, + modalClassName: 'manage-revisions-modal', + title: i18n('Revert'), + modalComponentProps: { + itemId: itemId, + version: version, + itemType + } + } + }); + }); + }, + + closeRevisionsView(dispatch) { + dispatch({ + type: modalActionTypes.GLOBAL_MODAL_CLOSE + }); + }, + + + fetchRevisions(dispatch, {itemId, version}) { + return fetchRevisions(itemId, version).then((response) => { + dispatch({ + type: actionTypes.ITEM_REVISIONS_LOADED, + response: response + }); + }); + }, + + revertToRevision(dispatch, {itemId, version, revisionId, itemType}) { + return revertToRevision(itemId, version, revisionId).then(() => { + this.closeRevisionsView(dispatch); + if (itemType === screenTypes.LICENSE_MODEL) { + ScreensHelper.loadScreen(dispatch, {screen: enums.SCREEN.LICENSE_MODEL_OVERVIEW, screenType: screenTypes.LICENSE_MODEL, + props: {licenseModelId: itemId, version}}); + } else { + ScreensHelper.loadScreen(dispatch, {screen: enums.SCREEN.SOFTWARE_PRODUCT_LANDING_PAGE, screenType: screenTypes.SOFTWARE_PRODUCT, + props: {softwareProductId: itemId, version}}); + } + }); + + } +}; + +export default RevisionaActionHelper; diff --git a/openecomp-ui/src/sdc-app/onboarding/revisions/RevisionsConstants.js b/openecomp-ui/src/sdc-app/onboarding/revisions/RevisionsConstants.js new file mode 100644 index 0000000000..28a9fa0ff5 --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/revisions/RevisionsConstants.js @@ -0,0 +1,20 @@ +/*! + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ +import keyMirror from 'nfvo-utils/KeyMirror.js'; + +export const actionTypes = keyMirror({ + ITEM_REVISIONS_LOADED: null +}); diff --git a/openecomp-ui/src/sdc-app/onboarding/revisions/RevisionsReducer.js b/openecomp-ui/src/sdc-app/onboarding/revisions/RevisionsReducer.js new file mode 100644 index 0000000000..778350b93f --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/revisions/RevisionsReducer.js @@ -0,0 +1,25 @@ +/*! + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ +import {actionTypes} from './RevisionsConstants.js'; + +export default (state = [], action) => { + switch (action.type) { + case actionTypes.ITEM_REVISIONS_LOADED: + return action.response.results; + default: + return state; + } +};
\ No newline at end of file diff --git a/openecomp-ui/src/sdc-app/onboarding/revisions/RevisionsView.jsx b/openecomp-ui/src/sdc-app/onboarding/revisions/RevisionsView.jsx new file mode 100644 index 0000000000..d6ef604a22 --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/revisions/RevisionsView.jsx @@ -0,0 +1,87 @@ +/*! + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing + * revisions and limitations under the License. + */ +import React from 'react'; +import Form from 'nfvo-components/input/validation/Form.jsx'; +import i18n from 'nfvo-utils/i18n/i18n.js'; +import ShowMore from 'react-show-more'; +import SVGIcon from 'sdc-ui/lib/react/SVGIcon.js'; + +import ListEditorView from 'nfvo-components/listEditor/ListEditorView.jsx'; +import ListEditorItemView from 'nfvo-components/listEditor/ListEditorItemView.jsx'; +import ListEditorItemViewField from 'nfvo-components/listEditor/ListEditorItemViewField.jsx'; + + +class RevisionsView extends React.Component { + constructor(props) { + super(props); + this.state = { + revertId : null + }; + } + + render() { + let {onCancel, onRevert, revisions, users} = this.props; + return ( + <div className='manage-revisions-page'> + <Form + hasButtons={true} + onSubmit={() => onRevert(this.state.revertId)} + onReset={() => onCancel() } + submitButtonText={i18n('Revert')} + labledButtons={true}> + <ListEditorView + title={i18n('Select a Commit')} + isReadOnlyMode={false}> + {revisions.map((revision) => { + return ( + <div key={revision.id} data-test-id='revision-list-item' className={`revision-list-item ${this.state.revertId === revision.id ? 'selected' : ''}`}> + <ListEditorItemView + isReadOnlyMode={false} + onSelect={() => this.setState({revertId : revision.id})}> + <ListEditorItemViewField> + <div className='revision-list-item-fields'> + <div data-test-id='revision-user' className='revision-user'> + <SVGIcon name='user' label={users.find(userObject => userObject.userId === revision.user).fullName} labelPosition='right'/> + </div> + <div className='revision-date' data-test-id='revision-date'> + <span className='revision-date'>{i18n.dateNormal(revision.time, { + year: 'numeric', month: 'numeric', day: 'numeric' + })}</span> + <span className='revision-time'>{i18n.dateNormal(revision.time, { + hour: 'numeric', minute: 'numeric', + hour12: true + })}</span> + </div> + <div className='revision-message'data-test-id='revision-message'> + {revision.message && <ShowMore anchorClass='more-less' lines={2} more={i18n('More')} less={i18n('Less')}> + {revision.message} + </ShowMore>}</div> + </div> + </ListEditorItemViewField> + </ListEditorItemView> + </div> + + ); + })} + </ListEditorView> + </Form> + </div> + ); + } + +} + +export default RevisionsView; diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProduct.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProduct.js index ae3d3932ed..cdaf189fc0 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProduct.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProduct.js @@ -16,64 +16,69 @@ import {connect} from 'react-redux'; import i18n from 'nfvo-utils/i18n/i18n.js'; -import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js'; +import ScreensHelper from 'sdc-app/common/helpers/ScreensHelper.js'; import TabulatedEditor from 'src/nfvo-components/editor/TabulatedEditor.jsx'; -import {enums} from 'sdc-app/onboarding/OnboardingConstants.js'; -import OnboardingActionHelper from 'sdc-app/onboarding/OnboardingActionHelper.js'; +import {enums, screenTypes} from 'sdc-app/onboarding/OnboardingConstants.js'; -import {navigationItems, mapScreenToNavigationItem, onboardingMethod as onboardingMethodTypes, onboardingOriginTypes} from './SoftwareProductConstants.js'; +import {onboardingMethod as onboardingMethodTypes, onboardingOriginTypes} from './SoftwareProductConstants.js'; import SoftwareProductActionHelper from './SoftwareProductActionHelper.js'; import SoftwareProductComponentsActionHelper from './components/SoftwareProductComponentsActionHelper.js'; -import SoftwareProductDependenciesActionHelper from './dependencies/SoftwareProductDependenciesActionHelper.js'; - +import PermissionsActionHelper from './../permissions/PermissionsActionHelper.js'; +import RevisionsActionHelper from './../revisions/RevisionsActionHelper.js'; import HeatSetupActionHelper from './attachments/setup/HeatSetupActionHelper.js'; import { actionsEnum as versionControllerActions } from 'nfvo-components/panel/versionController/VersionControllerConstants.js'; +import {actionTypes as modalActionTypes} from 'nfvo-components/modal/GlobalModalConstants.js'; +import {modalContentMapper} from 'sdc-app/common/modal/ModalContentMapper.js'; +import {CommitModalType} from 'nfvo-components/panel/versionController/components/CommitCommentModal.jsx'; +import {onboardingMethod as onboardingMethodType} from 'sdc-app/onboarding/softwareProduct/SoftwareProductConstants.js'; +import {SyncStates} from 'sdc-app/common/merge/MergeEditorConstants.js'; +import {catalogItemStatuses} from 'sdc-app/onboarding/onboard/onboardingCatalog/OnboardingCatalogConstants.js'; function getActiveNavigationId(screen, componentId) { - let activeItemId = componentId ? mapScreenToNavigationItem[screen] + '|' + componentId : mapScreenToNavigationItem[screen]; + let activeItemId = componentId ? screen + '|' + componentId : screen; return activeItemId; } const buildComponentNavigationBarGroups = ({componentId, meta}) => { const groups = ([ { - id: navigationItems.GENERAL + '|' + componentId, + id: enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_GENERAL + '|' + componentId, name: i18n('General'), disabled: false, meta }, { - id: navigationItems.COMPUTE + '|' + componentId, + id: enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_COMPUTE + '|' + componentId, name: i18n('Compute'), disabled: false, meta }, { - id: navigationItems.LOAD_BALANCING + '|' + componentId, + id: enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_LOAD_BALANCING + '|' + componentId, name: i18n('High Availability & Load Balancing'), disabled: false, meta }, { - id: navigationItems.NETWORKS + '|' + componentId, + id: enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_NETWORK + '|' + componentId, name: i18n('Networks'), disabled: false, meta }, { - id: navigationItems.STORAGE + '|' + componentId, + id: enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_STORAGE + '|' + componentId, name: i18n('Storage'), disabled: false, meta }, { - id: navigationItems.IMAGES + '|' + componentId, + id: enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_IMAGES + '|' + componentId, name: i18n('Images'), disabled: false, meta }, { - id: navigationItems.PROCESS_DETAILS + '|' + componentId, + id: enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_PROCESSES + '|' + componentId, name: i18n('Process Details'), disabled: false, meta }, { - id: navigationItems.MONITORING + '|' + componentId, + id: enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_MONITORING + '|' + componentId, name: i18n('Monitoring'), disabled: false, meta @@ -85,67 +90,67 @@ const buildComponentNavigationBarGroups = ({componentId, meta}) => { const buildNavigationBarProps = ({softwareProduct, meta, screen, componentId, componentsList, mapOfExpandedIds}) => { const {softwareProductEditor: {data: currentSoftwareProduct = {}}} = softwareProduct; - const {id, name, onboardingMethod, onboardingOrigin} = currentSoftwareProduct; + const {id, name, onboardingMethod, candidateOnboardingOrigin} = currentSoftwareProduct; const groups = [{ id: id, name: name, items: [ { - id: navigationItems.VENDOR_SOFTWARE_PRODUCT, + id: enums.SCREEN.SOFTWARE_PRODUCT_LANDING_PAGE, name: i18n('Overview'), disabled: false, meta }, { - id: navigationItems.GENERAL, + id: enums.SCREEN.SOFTWARE_PRODUCT_DETAILS, name: i18n('General'), disabled: false, meta }, { - id: navigationItems.DEPLOYMENT_FLAVORS, + id: enums.SCREEN.SOFTWARE_PRODUCT_DEPLOYMENT, name: i18n('Deployment Flavors'), disabled: false, hidden: onboardingMethod !== onboardingMethodTypes.MANUAL, meta }, { - id: navigationItems.PROCESS_DETAILS, + id: enums.SCREEN.SOFTWARE_PRODUCT_PROCESSES, name: i18n('Process Details'), disabled: false, meta }, { - id: navigationItems.NETWORKS, + id: enums.SCREEN.SOFTWARE_PRODUCT_NETWORKS, name: i18n('Networks'), disabled: false, meta }, { - id: navigationItems.ATTACHMENTS, + id: enums.SCREEN.SOFTWARE_PRODUCT_ATTACHMENTS, name: i18n('Attachments'), disabled: false, - hidden: onboardingOrigin === onboardingOriginTypes.NONE, + hidden: candidateOnboardingOrigin === onboardingOriginTypes.NONE, meta }, { - id: navigationItems.ACTIVITY_LOG, + id: enums.SCREEN.SOFTWARE_PRODUCT_ACTIVITY_LOG, name: i18n('Activity Log'), disabled: false, meta }, { - id: navigationItems.DEPENDENCIES, + id: enums.SCREEN.SOFTWARE_PRODUCT_DEPENDENCIES, name: i18n('Component Dependencies'), hidden: componentsList.length <= 1, disabled: false, meta }, { - id: navigationItems.COMPONENTS, + id: enums.SCREEN.SOFTWARE_PRODUCT_COMPONENTS, name: i18n('Components'), hidden: componentsList.length <= 0, meta, - expanded: mapOfExpandedIds[navigationItems.COMPONENTS] === true && screen !== enums.SCREEN.SOFTWARE_PRODUCT_LANDING_PAGE, + expanded: mapOfExpandedIds[enums.SCREEN.SOFTWARE_PRODUCT_COMPONENTS] === true && screen !== enums.SCREEN.SOFTWARE_PRODUCT_LANDING_PAGE, items: [ ...componentsList.map(({id, displayName}) => ({ - id: navigationItems.COMPONENTS + '|' + id, + id: enums.SCREEN.SOFTWARE_PRODUCT_COMPONENTS + '|' + id, name: displayName, meta, - expanded: mapOfExpandedIds[navigationItems.COMPONENTS + '|' + id] === true && screen !== enums.SCREEN.SOFTWARE_PRODUCT_LANDING_PAGE, + expanded: mapOfExpandedIds[enums.SCREEN.SOFTWARE_PRODUCT_COMPONENTS + '|' + id] === true && screen !== enums.SCREEN.SOFTWARE_PRODUCT_LANDING_PAGE, items: buildComponentNavigationBarGroups({componentId: id, meta}) })) ] @@ -158,24 +163,28 @@ const buildNavigationBarProps = ({softwareProduct, meta, screen, componentId, co }; }; -const buildVersionControllerProps = (softwareProduct) => { - const {softwareProductEditor} = softwareProduct; - const {data: currentSoftwareProduct = {}, isValidityData = true} = softwareProductEditor; - - const {version, viewableVersions, status: currentStatus, lockingUser} = currentSoftwareProduct; - const {status, isCheckedOut} = VersionControllerUtils.getCheckOutStatusKindByUserID(currentStatus, lockingUser); +const buildVersionControllerProps = ({softwareProduct, versions, currentVersion, permissions, userInfo, usersList, itemPermission, isReadOnlyMode}) => { + const {softwareProductEditor = {data: {}}} = softwareProduct; + const {isValidityData = true, data: {name, onboardingMethod}} = softwareProductEditor; return { - status, isCheckedOut, version, viewableVersions, - isFormDataValid: isValidityData + version: currentVersion, + viewableVersions: versions, + isFormDataValid: isValidityData, + permissions, + itemName: name, + itemPermission, + isReadOnlyMode, + userInfo, + usersList, + isManual: onboardingMethod === onboardingMethodType.MANUAL }; }; -function buildMeta({softwareProduct, componentId, softwareProductDependencies}) { +function buildMeta({softwareProduct, componentId, softwareProductDependencies, isReadOnlyMode}) { const {softwareProductEditor, softwareProductComponents, softwareProductQuestionnaire, softwareProductAttachments} = softwareProduct; const {data: currentSoftwareProduct = {}} = softwareProductEditor; - const {version, onboardingOrigin} = currentSoftwareProduct; - const isReadOnlyMode = VersionControllerUtils.isReadOnly(currentSoftwareProduct); + const {version, onboardingOrigin, candidateOnboardingOrigin} = currentSoftwareProduct; const {qdata} = softwareProductQuestionnaire; const {heatSetup, heatSetupCache} = softwareProductAttachments; let currentComponentMeta = {}; @@ -183,35 +192,52 @@ function buildMeta({softwareProduct, componentId, softwareProductDependencies}) const {componentEditor: {data: componentData = {} , qdata: componentQdata}} = softwareProductComponents; currentComponentMeta = {componentData, componentQdata}; } - const meta = {softwareProduct: currentSoftwareProduct, qdata, version, onboardingOrigin, heatSetup, heatSetupCache, isReadOnlyMode, currentComponentMeta, softwareProductDependencies}; + const meta = {softwareProduct: currentSoftwareProduct, qdata, version, onboardingOrigin, candidateOnboardingOrigin, heatSetup, heatSetupCache, + isReadOnlyMode, currentComponentMeta, softwareProductDependencies}; return meta; } -const mapStateToProps = ({softwareProduct}, {currentScreen: {screen, props: {componentId}}}) => { +const mapStateToProps = ( + { + softwareProduct, + users: {usersList, userInfo}, + versionsPage: {versionsList: {versions}, permissions} + }, + { + currentScreen: {screen, itemPermission, props: {version: currentVersion, componentId, isReadOnlyMode}} + } +) => { const {softwareProductEditor, softwareProductComponents, softwareProductDependencies} = softwareProduct; const {mapOfExpandedIds = []} = softwareProductEditor; const {componentsList = []} = softwareProductComponents; - const meta = buildMeta({softwareProduct, componentId, softwareProductDependencies}); + const meta = buildMeta({softwareProduct, componentId, softwareProductDependencies, isReadOnlyMode}); return { - versionControllerProps: buildVersionControllerProps(softwareProduct), + versionControllerProps: buildVersionControllerProps({ + softwareProduct, + versions, + currentVersion, + userInfo, + usersList, + permissions, + itemPermission: {...itemPermission, isDirty: true}, + isReadOnlyMode + }), navigationBarProps: buildNavigationBarProps({softwareProduct, meta, screen, componentId, componentsList, mapOfExpandedIds}), meta }; }; -const autoSaveBeforeNavigate = ({dispatch, screen, softwareProductId, componentId, - meta: {isReadOnlyMode, softwareProduct, version, qdata, softwareProductDependencies, +const autoSaveBeforeNavigate = ({dispatch, screen, softwareProductId, version, componentId, + meta: {isReadOnlyMode, softwareProduct, qdata, currentComponentMeta: {componentData, componentQdata}}}) => { let promise; if (isReadOnlyMode) { promise = Promise.resolve(); } else { switch(screen) { - case enums.SCREEN.SOFTWARE_PRODUCT_DEPENDENCIES: - promise = SoftwareProductDependenciesActionHelper.saveDependencies(dispatch,{softwareProductId, version, dependenciesList: softwareProductDependencies}); case enums.SCREEN.SOFTWARE_PRODUCT_DETAILS: - promise = SoftwareProductActionHelper.updateSoftwareProduct(dispatch, {softwareProduct, qdata}); + promise = SoftwareProductActionHelper.updateSoftwareProduct(dispatch, {softwareProduct, version, qdata}); break; case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_GENERAL: promise = SoftwareProductComponentsActionHelper.updateSoftwareProductComponent(dispatch, @@ -233,96 +259,65 @@ const autoSaveBeforeNavigate = ({dispatch, screen, softwareProductId, componentI }; -const onComponentNavigate = (dispatch, {id, softwareProductId, version, currentComponentId}) => { - const [nextScreen, nextComponentId] = id.split('|'); - switch(nextScreen) { - case navigationItems.COMPONENTS: - if(nextComponentId === currentComponentId) { - OnboardingActionHelper.navigateToSoftwareProductComponents(dispatch, {softwareProductId}); - } else { - OnboardingActionHelper.navigateToSoftwareProductComponentGeneral(dispatch, {softwareProductId, componentId: nextComponentId, version}); - } - break; - case navigationItems.GENERAL: - OnboardingActionHelper.navigateToSoftwareProductComponentGeneral(dispatch, {softwareProductId, componentId: nextComponentId, version}); - break; - case navigationItems.COMPUTE: - OnboardingActionHelper.navigateToComponentCompute(dispatch, {softwareProductId, componentId: nextComponentId, version}); - break; - case navigationItems.LOAD_BALANCING: - OnboardingActionHelper.navigateToComponentLoadBalancing(dispatch, {softwareProductId, componentId: nextComponentId, version}); - break; - case navigationItems.NETWORKS: - OnboardingActionHelper.navigateToComponentNetwork(dispatch, {softwareProductId, componentId: nextComponentId, version}); - break; - case navigationItems.IMAGES: - OnboardingActionHelper.navigateToComponentImages(dispatch, {softwareProductId, componentId: nextComponentId, version}); - break; - case navigationItems.STORAGE: - OnboardingActionHelper.navigateToComponentStorage(dispatch, {softwareProductId, componentId: nextComponentId, version}); - break; - case navigationItems.PROCESS_DETAILS: - OnboardingActionHelper.navigateToSoftwareProductComponentProcesses(dispatch, {softwareProductId, componentId: nextComponentId, version}); - break; - case navigationItems.MONITORING: - OnboardingActionHelper.navigateToSoftwareProductComponentMonitoring(dispatch, {softwareProductId, componentId: nextComponentId, version}); - break; - } -}; - -const mapActionsToProps = (dispatch, {currentScreen: {screen, props: {softwareProductId, componentId: currentComponentId}}}) => { +const mapActionsToProps = (dispatch, {currentScreen: {screen, props: {softwareProductId, licenseModelId, version, componentId: currentComponentId}}}) => { const props = { - onVersionSwitching: (version, meta) => { - const screenToLoad = !currentComponentId ? screen : enums.SCREEN.SOFTWARE_PRODUCT_COMPONENTS; - SoftwareProductActionHelper.fetchSoftwareProduct(dispatch, {softwareProductId, version}); - props.onNavigate({id: getActiveNavigationId(screenToLoad), meta, version}); + onVersionSwitching: (versionToSwitch, meta) => { + ScreensHelper.loadScreen(dispatch, {screen: enums.SCREEN.SOFTWARE_PRODUCT_LANDING_PAGE, screenType: screenTypes.SOFTWARE_PRODUCT, + props: {softwareProductId: meta.softwareProduct.id, version: versionToSwitch}}); + }, + onOpenPermissions: ({users}) => { + return PermissionsActionHelper.fetchItemUsers(dispatch, {itemId: softwareProductId, allUsers: users}); + }, + onOpenRevisionsModal: () => { + return RevisionsActionHelper.openRevisionsView(dispatch, {itemId: softwareProductId, version: version, itemType: screenTypes.SOFTWARE_PRODUCT}); + }, + onOpenCommentCommitModal: ({onCommit, title}) => dispatch({ + type: modalActionTypes.GLOBAL_MODAL_SHOW, + data: { + modalComponentName: modalContentMapper.COMMIT_COMMENT, + modalComponentProps: { + onCommit, + type: CommitModalType.COMMIT + }, + title + } + }), + onMoreVersionsClick: ({itemName, users}) => { + ScreensHelper.loadScreen(dispatch, {screen: enums.SCREEN.SOFTWARE_PRODUCT_VERSIONS_PAGE, screenType: screenTypes.SOFTWARE_PRODUCT, + props: {softwareProductId, softwareProduct: {name: itemName, vendorId: licenseModelId}, usersList: users}}); + }, onToggle: (groups, itemIdToExpand) => groups.map(({items}) => SoftwareProductActionHelper.toggleNavigationItems(dispatch, {items, itemIdToExpand})), - onNavigate: ({id, meta, version}) => { - let {onboardingOrigin, heatSetup, heatSetupCache} = meta; + onNavigate: ({id, meta, newVersion}) => { + let navigationVersion = newVersion || version; + let {onboardingOrigin, candidateOnboardingOrigin, heatSetup, heatSetupCache} = meta; let heatSetupPopupPromise = screen === enums.SCREEN.SOFTWARE_PRODUCT_ATTACHMENTS ? HeatSetupActionHelper.heatSetupLeaveConfirmation(dispatch, {softwareProductId, heatSetup, heatSetupCache}) : Promise.resolve(); - let preNavigate = meta ? autoSaveBeforeNavigate({dispatch, screen, meta, softwareProductId, componentId: currentComponentId}) : Promise.resolve(); + let preNavigate = meta ? autoSaveBeforeNavigate({dispatch, screen, meta, version, softwareProductId, componentId: currentComponentId}) : Promise.resolve(); version = version || (meta ? meta.version : undefined); Promise.all([preNavigate, heatSetupPopupPromise]).then(() => { - switch(id) { - case navigationItems.VENDOR_SOFTWARE_PRODUCT: - OnboardingActionHelper.navigateToSoftwareProductLandingPage(dispatch, {softwareProductId, version}); - break; - case navigationItems.GENERAL: - OnboardingActionHelper.navigateToSoftwareProductDetails(dispatch, {softwareProductId, version}); - break; - case navigationItems.DEPLOYMENT_FLAVORS: - OnboardingActionHelper.navigateToSoftwareProductDeployment(dispatch, {softwareProductId, version}); - break; - case navigationItems.PROCESS_DETAILS: - OnboardingActionHelper.navigateToSoftwareProductProcesses(dispatch, {softwareProductId, version}); - break; - case navigationItems.NETWORKS: - OnboardingActionHelper.navigateToSoftwareProductNetworks(dispatch, {softwareProductId, version}); - break; - case navigationItems.DEPENDENCIES: - OnboardingActionHelper.navigateToSoftwareProductDependencies(dispatch, {softwareProductId, version}); - break; - case navigationItems.ATTACHMENTS: - if(onboardingOrigin === onboardingOriginTypes.ZIP) { - OnboardingActionHelper.navigateToSoftwareProductAttachmentsSetupTab(dispatch, {softwareProductId, version}); + let [nextScreen, nextComponentId] = id.split('|'); + if(nextScreen === enums.SCREEN.SOFTWARE_PRODUCT_COMPONENTS && nextComponentId && nextComponentId === currentComponentId) { + ScreensHelper.loadScreen(dispatch, { + screen: nextScreen, screenType: screenTypes.SOFTWARE_PRODUCT, + props: {softwareProductId, version: navigationVersion} + }); + } + else { + if(nextScreen === enums.SCREEN.SOFTWARE_PRODUCT_ATTACHMENTS) { + if(onboardingOrigin === onboardingOriginTypes.ZIP || candidateOnboardingOrigin === onboardingOriginTypes.ZIP) { + nextScreen = enums.SCREEN.SOFTWARE_PRODUCT_ATTACHMENTS_SETUP; } else if(onboardingOrigin === onboardingOriginTypes.CSAR) { - OnboardingActionHelper.navigateToSoftwareProductAttachmentsValidationTab(dispatch, {softwareProductId, version}); + nextScreen = enums.SCREEN.SOFTWARE_PRODUCT_ATTACHMENTS_VALIDATION; } - break; - case navigationItems.COMPONENTS: - OnboardingActionHelper.navigateToSoftwareProductComponents(dispatch, {softwareProductId, version}); - break; - case navigationItems.ACTIVITY_LOG: - OnboardingActionHelper.navigateToSoftwareProductActivityLog(dispatch, {softwareProductId, version}); - break; - default: - onComponentNavigate(dispatch, {id, softwareProductId, version, screen, currentComponentId}); - break; + } + ScreensHelper.loadScreen(dispatch, { + screen: nextScreen, screenType: screenTypes.SOFTWARE_PRODUCT, + props: {softwareProductId, version: navigationVersion, componentId: nextComponentId} + }); } }).catch((e) => {console.error(e);}); } @@ -342,25 +337,33 @@ const mapActionsToProps = (dispatch, {currentScreen: {screen, props: {softwarePr props.onSave = () => Promise.resolve(); break; default: - props.onSave = ({softwareProduct, qdata}) => SoftwareProductActionHelper.updateSoftwareProduct(dispatch, {softwareProduct, qdata}); + props.onSave = ({softwareProduct, qdata}) => SoftwareProductActionHelper.updateSoftwareProduct(dispatch, {softwareProduct, qdata, version}); break; } - props.onVersionControllerAction = (action, version, meta) => { + props.onVersionControllerAction = (action, version, comment, meta) => { let {heatSetup, heatSetupCache} = meta; - let heatSetupPopupPromise = screen === enums.SCREEN.SOFTWARE_PRODUCT_ATTACHMENTS && action === versionControllerActions.CHECK_IN ? + let autoSavePromise = meta ? autoSaveBeforeNavigate({dispatch, screen, meta, version, softwareProductId, componentId: currentComponentId}) : Promise.resolve(); + let heatSetupPopupPromise = screen === enums.SCREEN.SOFTWARE_PRODUCT_ATTACHMENTS && action === versionControllerActions.COMMIT ? HeatSetupActionHelper.heatSetupLeaveConfirmation(dispatch, {softwareProductId, heatSetup, heatSetupCache}) : Promise.resolve(); - heatSetupPopupPromise.then(() => { - return SoftwareProductActionHelper.performVCAction(dispatch, {softwareProductId, action, version}).then(({newVersion}) => { - //props.onNavigate({id: getActiveNavigationId(screen, currentComponentId), version}); - if(screen === enums.SCREEN.SOFTWARE_PRODUCT_ACTIVITY_LOG) { - OnboardingActionHelper.navigateToSoftwareProductActivityLog(dispatch, {softwareProductId, version: newVersion}); + Promise.all([autoSavePromise, heatSetupPopupPromise]).then(() => { + return SoftwareProductActionHelper.performVCAction(dispatch, {softwareProductId, action, version, comment, meta}).then(updatedVersion => { + const inMerge = updatedVersion && updatedVersion.state && updatedVersion.state.synchronizationState === SyncStates.MERGE; + if((action === versionControllerActions.SYNC && !inMerge) || + ((action === versionControllerActions.COMMIT || action === versionControllerActions.SYNC) && updatedVersion.status === catalogItemStatuses.CERTIFIED)) { + ScreensHelper.loadLandingScreen(dispatch, {previousScreenName: screen, props: {softwareProductId, version: updatedVersion}}); + + } else { + ScreensHelper.loadScreen(dispatch, {screen, screenType: screenTypes.SOFTWARE_PRODUCT, + props: {softwareProductId, version: updatedVersion, componentId: currentComponentId}}); } }); }).catch((e) => {console.error(e);}); }; + + props.onManagePermissions = () => PermissionsActionHelper.openPermissonsManager(dispatch, {itemId: softwareProductId, askForRights: false}); return props; }; diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductActionHelper.js index db7afd27d9..735c6d7f8b 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductActionHelper.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductActionHelper.js @@ -31,8 +31,26 @@ import {actionTypes as componentActionTypes} from './components/SoftwareProductC import ValidationHelper from 'sdc-app/common/helpers/ValidationHelper.js'; import {actionTypes as modalActionTypes} from 'nfvo-components/modal/GlobalModalConstants.js'; import {modalContentMapper} from 'sdc-app/common/modal/ModalContentMapper.js'; -import {statusEnum} from 'nfvo-components/panel/versionController/VersionControllerConstants.js'; +import ItemsHelper from 'sdc-app/common/helpers/ItemsHelper.js'; +import ScreensHelper from 'sdc-app/common/helpers/ScreensHelper.js'; +import {enums, screenTypes} from 'sdc-app/onboarding/OnboardingConstants.js'; +import MergeEditorActionHelper from 'sdc-app/common/merge/MergeEditorActionHelper.js'; +import {CommitModalType} from 'nfvo-components/panel/versionController/components/CommitCommentModal.jsx'; import {actionTypes as commonActionTypes} from 'sdc-app/common/reducers/PlainDataReducerConstants.js'; +import versionPageActionHelper from 'sdc-app/onboarding/versionsPage/VersionsPageActionHelper.js'; +import {itemTypes} from 'sdc-app/onboarding/versionsPage/VersionsPageConstants.js'; +import {catalogItemStatuses} from 'sdc-app/onboarding/onboard/onboardingCatalog/OnboardingCatalogConstants.js'; +import getValue from 'nfvo-utils/getValue.js'; + +function getLicensingData(licensingData = {}) { + const {licenseAgreement, featureGroups} = licensingData; + const newlicenseAgreement = getValue(licenseAgreement); + const newfeatureGroups = getValue(featureGroups); + return newlicenseAgreement ? { + licenseAgreement: newlicenseAgreement, + featureGroups: newfeatureGroups + } : undefined; +}; function baseUrl() { const restPrefix = Configuration.get('restPrefix'); @@ -48,20 +66,17 @@ function uploadFile(vspId, formData, version) { } -function putSoftwareProduct(softwareProduct) { - return RestAPIUtil.put(`${baseUrl()}${softwareProduct.id}/versions/${softwareProduct.version.id}`, { +function putSoftwareProduct({softwareProduct, version}) { + return RestAPIUtil.put(`${baseUrl()}${softwareProduct.id}/versions/${version.id}`, { name: softwareProduct.name, description: softwareProduct.description, category: softwareProduct.category, subCategory: softwareProduct.subCategory, vendorId: softwareProduct.vendorId, vendorName: softwareProduct.vendorName, - licensingVersion: softwareProduct.licensingVersion && softwareProduct.licensingVersion.id ? softwareProduct.licensingVersion : {} , + licensingVersion: softwareProduct.licensingVersion ? softwareProduct.licensingVersion : undefined, icon: softwareProduct.icon, - licensingData: softwareProduct.licensingData, - onboardingMethod: softwareProduct.onboardingMethod, - networkPackageName: softwareProduct.networkPackageName, - onboardingOrigin: softwareProduct.onboardingOrigin + licensingData: getLicensingData(softwareProduct.licensingData) }); } @@ -74,11 +89,11 @@ function putSoftwareProductAction(id, action, version) { } function fetchSoftwareProductList() { - return RestAPIUtil.fetch(baseUrl()); + return RestAPIUtil.fetch(`${baseUrl()}?versionFilter=Draft`); } function fetchFinalizedSoftwareProductList() { - return RestAPIUtil.fetch(`${baseUrl()}?versionFilter=Final`); + return RestAPIUtil.fetch(`${baseUrl()}?versionFilter=Certified`); } function fetchSoftwareProduct(vspId, version) { @@ -138,10 +153,12 @@ function fetchSoftwareProductCategories(dispatch) { } function loadLicensingData(dispatch, {licenseModelId, licensingVersion}) { - return Promise.all([ - LicenseAgreementActionHelper.fetchLicenseAgreementList(dispatch, {licenseModelId, version: licensingVersion}), - FeatureGroupsActionHelper.fetchFeatureGroupsList(dispatch, {licenseModelId, version: licensingVersion}) - ]); + return ItemsHelper.fetchVersion({itemId: licenseModelId, versionId: licensingVersion}).then(() => { + return Promise.all([ + LicenseAgreementActionHelper.fetchLicenseAgreementList(dispatch, {licenseModelId, version: {id: licensingVersion}}), + FeatureGroupsActionHelper.fetchFeatureGroupsList(dispatch, {licenseModelId, version: {id: licensingVersion}}) + ]); + }); } function getExpandedItemsId(items, itemIdToToggle) { @@ -203,15 +220,7 @@ function migrateSoftwareProduct(vspId, version) { return RestAPIUtil.put(`${baseUrl()}${vspId}/versions/${version.id}/heal`); } -function adjustMinorVersion(version, value) { - let ar = version.split('.'); - return ar[0] + '.' + (parseInt(ar[1]) + value); -} -function adjustMajorVersion(version, value) { - let ar = version.split('.'); - return (parseInt(ar[0]) + value) + '.0'; -} const SoftwareProductActionHelper = { @@ -229,7 +238,10 @@ const SoftwareProductActionHelper = { loadSoftwareProductDetailsData(dispatch, {licenseModelId, licensingVersion}) { SoftwareProductActionHelper.loadSoftwareProductAssociatedData(dispatch); - return loadLicensingData(dispatch, {licenseModelId, licensingVersion}); + if (licensingVersion) { + return loadLicensingData(dispatch, {licenseModelId, licensingVersion}); + } + return Promise.resolve(); }, fetchSoftwareProductList(dispatch) { @@ -246,6 +258,14 @@ const SoftwareProductActionHelper = { })); }, + loadLicensingVersionsList(dispatch, {licenseModelId}){ + return ItemsHelper.fetchVersions({itemId: licenseModelId}).then(response => { + dispatch({ + type: actionTypes.LOAD_LICENSING_VERSIONS_LIST, + licensingVersionsList: response.results + }); + }); + }, updateSoftwareProductHeatCandidate(dispatch, {softwareProductId, heatCandidate, version}){ return updateSoftwareProductHeatCandidate(softwareProductId, heatCandidate, version); }, @@ -276,10 +296,16 @@ const SoftwareProductActionHelper = { }); switch(response.onboardingOrigin){ case onboardingOriginTypes.ZIP: - OnboardingActionHelper.navigateToSoftwareProductAttachmentsSetupTab(dispatch, {softwareProductId, version}); + ScreensHelper.loadScreen(dispatch, { + screen: enums.SCREEN.SOFTWARE_PRODUCT_ATTACHMENTS_SETUP, screenType: screenTypes.SOFTWARE_PRODUCT, + props: {softwareProductId, version} + }); break; case onboardingOriginTypes.CSAR: - OnboardingActionHelper.navigateToSoftwareProductAttachmentsValidationTab(dispatch, {softwareProductId, version}); + ScreensHelper.loadScreen(dispatch, { + screen: enums.SCREEN.SOFTWARE_PRODUCT_ATTACHMENTS_VALIDATION, screenType: screenTypes.SOFTWARE_PRODUCT, + props: {softwareProductId, version} + }); break; } } @@ -292,7 +318,7 @@ const SoftwareProductActionHelper = { type: modalActionTypes.GLOBAL_MODAL_ERROR, data: { title: failedNotificationTitle, - msg: error.message + msg: error.message || (error.responseJSON && error.responseJSON.message) } }); }); @@ -311,9 +337,9 @@ const SoftwareProductActionHelper = { type: actionTypes.softwareProductEditor.UPLOAD_CONFIRMATION }); }, - updateSoftwareProduct(dispatch, {softwareProduct, qdata}) { + updateSoftwareProduct(dispatch, {softwareProduct, version, qdata}) { return Promise.all([ - SoftwareProductActionHelper.updateSoftwareProductData(dispatch, {softwareProduct}).then( + SoftwareProductActionHelper.updateSoftwareProductData(dispatch, {softwareProduct, version}).then( () => dispatch({ type: actionTypes.SOFTWARE_PRODUCT_LIST_EDIT, payload: {softwareProduct} @@ -322,13 +348,13 @@ const SoftwareProductActionHelper = { SoftwareProductActionHelper.updateSoftwareProductQuestionnaire(dispatch, { softwareProductId: softwareProduct.id, qdata, - version: softwareProduct.version + version }) ]); }, - updateSoftwareProductData(dispatch, {softwareProduct}) { - return putSoftwareProduct(softwareProduct); + updateSoftwareProductData(dispatch, {softwareProduct, version}) { + return putSoftwareProduct({softwareProduct, version}); }, updateSoftwareProductQuestionnaire(dispatch, {softwareProductId, qdata, version}) { @@ -350,19 +376,18 @@ const SoftwareProductActionHelper = { }, softwareProductEditorVendorChanged(dispatch, {deltaData, formName}) { - if (deltaData.licensingVersion.id){ - let p = Promise.all([ - LicenseAgreementActionHelper.fetchLicenseAgreementList(dispatch, { - licenseModelId: deltaData.vendorId, - version: {id: deltaData.licensingVersion.id} - }), - FeatureGroupsActionHelper.fetchFeatureGroupsList(dispatch, { - licenseModelId: deltaData.vendorId, - version: {id: deltaData.licensingVersion.id} - }) - ]); + if (deltaData.licensingVersion){ + return loadLicensingData(dispatch, {licenseModelId: deltaData.vendorId, licensingVersion: deltaData.licensingVersion}).then(() => { + ValidationHelper.dataChanged(dispatch, {deltaData, formName}); + return Promise.resolve(); + }); + } else if (deltaData.vendorId) { ValidationHelper.dataChanged(dispatch, {deltaData, formName}); - return p; + return SoftwareProductActionHelper.loadLicensingVersionsList(dispatch, { + licenseModelId: deltaData.vendorId + }).then( () => + OnboardingActionHelper.forceBreadCrumbsUpdate(dispatch) + ); } else { ValidationHelper.dataChanged(dispatch, {deltaData, formName}); @@ -386,13 +411,6 @@ const SoftwareProductActionHelper = { }); }, - addSoftwareProduct(dispatch, {softwareProduct}) { - dispatch({ - type: actionTypes.ADD_SOFTWARE_PRODUCT, - softwareProduct - }); - }, - fetchSoftwareProduct(dispatch, {softwareProductId, version}) { return Promise.all([ fetchSoftwareProduct(softwareProductId, version).then(response => { @@ -409,10 +427,33 @@ const SoftwareProductActionHelper = { ]); }, - performVCAction(dispatch, {softwareProductId, action, version}) { - if (action === VersionControllerActionsEnum.SUBMIT) { - return putSoftwareProductAction(softwareProductId, action, version).then(() => { - return putSoftwareProductAction(softwareProductId, VersionControllerActionsEnum.CREATE_PACKAGE, version).then(() => { + manageSubmitAction(dispatch, {softwareProductId, version, isDirty}) { + if (isDirty) { + const onCommit = comment => { + return this.performVCAction(dispatch, {softwareProductId, action: VersionControllerActionsEnum.COMMIT, version, comment}).then(() => { + return this.performSubmitAction(dispatch, {softwareProductId, version}); + }); + }; + dispatch({ + type: modalActionTypes.GLOBAL_MODAL_SHOW, + data: { + modalComponentName: modalContentMapper.COMMIT_COMMENT, + modalComponentProps: { + onCommit, + type: CommitModalType.COMMIT_SUBMIT + }, + title: i18n('Commit & Submit') + } + }); + return Promise.resolve(version); + } + return this.performSubmitAction(dispatch, {softwareProductId, version}); + }, + + performSubmitAction(dispatch, {softwareProductId, version}) { + return putSoftwareProductAction(softwareProductId, VersionControllerActionsEnum.SUBMIT, version).then(() => { + return putSoftwareProductAction(softwareProductId, VersionControllerActionsEnum.CREATE_PACKAGE, version).then(() => { + return ItemsHelper.checkItemStatus(dispatch, {itemId: softwareProductId, versionId: version.id}).then(updatedVersion => { dispatch({ type: modalActionTypes.GLOBAL_MODAL_SUCCESS, data: { @@ -422,12 +463,13 @@ const SoftwareProductActionHelper = { timeout: 2000 } }); - const newVersionId = adjustMajorVersion(version.label, 1); - OnboardingActionHelper.updateCurrentScreenVersion(dispatch, {label: newVersionId, id: newVersionId}); - SoftwareProductActionHelper.fetchSoftwareProduct(dispatch,{softwareProductId, version: {id: newVersionId}}); - return Promise.resolve({newVersion: {id: newVersionId}}); + versionPageActionHelper.fetchVersions(dispatch, {itemType: itemTypes.SOFTWARE_PRODUCT, itemId: softwareProductId}); + return Promise.resolve(updatedVersion); }); - }, error => dispatch({ + }); + }, error => + { + dispatch({ type: modalActionTypes.GLOBAL_MODAL_ERROR, data: { modalComponentName: modalContentMapper.SUMBIT_ERROR_RESPONSE, @@ -435,36 +477,57 @@ const SoftwareProductActionHelper = { modalComponentProps: { validationResponse: error.responseJSON }, - cancelButtonText: i18n('Ok') + cancelButtonText: i18n('OK') } - })); - } - else { - return putSoftwareProductAction(softwareProductId, action, version).then(() => { - let newVersionId = version.id; - /* - TODO Temorary switch to change version label - */ - switch(action) { - case VersionControllerActionsEnum.CHECK_OUT: - newVersionId = adjustMinorVersion(version.label, 1); - break; - case VersionControllerActionsEnum.UNDO_CHECK_OUT: - newVersionId = adjustMinorVersion(version.label, -1); - break; - } - OnboardingActionHelper.updateCurrentScreenVersion(dispatch, {label: newVersionId, id: newVersionId}); - SoftwareProductActionHelper.fetchSoftwareProduct(dispatch,{softwareProductId, version:{id: newVersionId}}); - return Promise.resolve({newVersion: {id: newVersionId}}); }); - } + return Promise.reject(error.responseJSON); + }); }, - switchVersion(dispatch, {softwareProductId, licenseModelId, version}) { - OnboardingActionHelper.navigateToSoftwareProductLandingPage(dispatch, { - softwareProductId, - licenseModelId, - version + performVCAction(dispatch, {softwareProductId, action, version, comment}) { + return MergeEditorActionHelper.analyzeSyncResult(dispatch, {itemId: softwareProductId, version}).then(({inMerge, isDirty, updatedVersion}) => { + if (updatedVersion.status === catalogItemStatuses.CERTIFIED && + (action === VersionControllerActionsEnum.COMMIT || action === VersionControllerActionsEnum.SYNC)) { + versionPageActionHelper.fetchVersions(dispatch, {itemType: itemTypes.SOFTWARE_PRODUCT, itemId: softwareProductId}); + dispatch({ + type: modalActionTypes.GLOBAL_MODAL_WARNING, + data: { + title: i18n('Commit error'), + msg: i18n('Item version already Certified'), + cancelButtonText: i18n('Cancel') + } + }); + return Promise.resolve(updatedVersion); + } + if (!inMerge) { + if (action === VersionControllerActionsEnum.SUBMIT) { + return this.manageSubmitAction(dispatch, {softwareProductId, version, isDirty}); + } + else { + let isCallActionValid = action !== VersionControllerActionsEnum.COMMIT || isDirty; + if(isCallActionValid) { + return ItemsHelper.performVCAction({itemId: softwareProductId, action, version, comment}).then(() => { + versionPageActionHelper.fetchVersions(dispatch, {itemType: itemTypes.LICENSE_MODEL, itemId: softwareProductId}); + if (action === VersionControllerActionsEnum.SYNC) { + return MergeEditorActionHelper.analyzeSyncResult(dispatch, {itemId: softwareProductId, version}).then(({updatedVersion}) => { + return Promise.resolve(updatedVersion); + }); + } else { + return ItemsHelper.checkItemStatus(dispatch, {itemId: softwareProductId, versionId: version.id}); + } + }); + } + else { + dispatch({ + type: modalActionTypes.GLOBAL_MODAL_ERROR, + data: { + title: i18n('Commit Failed'), + msg: i18n('There is nothing to commit') + } + }); + } + } + } }); }, @@ -477,7 +540,7 @@ const SoftwareProductActionHelper = { }, /** for the next verision */ - addComponent(dispatch, {softwareProductId, modalClassName}) { + addComponent(dispatch, {softwareProductId, modalClassName, version}) { SoftwareProductComponentsActionHelper.clearComponentCreationData(dispatch); dispatch({ type: componentActionTypes.COMPONENT_CREATE_OPEN @@ -486,7 +549,7 @@ const SoftwareProductActionHelper = { type: modalActionTypes.GLOBAL_MODAL_SHOW, data: { modalComponentName: modalContentMapper.COMPONENT_CREATION, - modalComponentProps: {softwareProductId}, + modalComponentProps: {softwareProductId, version}, modalClassName, title: 'Create Virtual Function Component' } @@ -494,12 +557,12 @@ const SoftwareProductActionHelper = { }, migrateSoftwareProduct(dispatch, {softwareProduct}) { - let {licenseModelId, licensingVersion, id: softwareProductId, version, status} = softwareProduct; - const newVer = status === statusEnum.CHECK_IN_STATUS || status === statusEnum.SUBMIT_STATUS ? - adjustMinorVersion(version.id, 1) : version.id; - migrateSoftwareProduct(softwareProductId, version) - .then(() =>OnboardingActionHelper.navigateToSoftwareProductLandingPage(dispatch, - {softwareProductId, version: {id: newVer, label: newVer}, licenseModelId, licensingVersion})); + let {id: softwareProductId, version} = softwareProduct; + const newVer = version.id; + migrateSoftwareProduct(softwareProductId, version).then(() => ScreensHelper.loadScreen(dispatch, { + screen: enums.SCREEN.SOFTWARE_PRODUCT_LANDING_PAGE, screenType: screenTypes.SOFTWARE_PRODUCT, + props: {softwareProductId, version: {id: newVer, label: newVer}} + })); } }; diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductConstants.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductConstants.js index 2c094ac36a..7df46589c3 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductConstants.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductConstants.js @@ -14,7 +14,6 @@ * permissions and limitations under the License. */ import keyMirror from 'nfvo-utils/KeyMirror.js'; -import {enums} from 'sdc-app/onboarding/OnboardingConstants.js'; export const actionTypes = keyMirror({ SOFTWARE_PRODUCT_LOADED: null, @@ -23,7 +22,7 @@ export const actionTypes = keyMirror({ SOFTWARE_PRODUCT_LIST_EDIT: null, SOFTWARE_PRODUCT_CATEGORIES_LOADED: null, SOFTWARE_PRODUCT_QUESTIONNAIRE_UPDATE: null, - ADD_SOFTWARE_PRODUCT: null, + LOAD_LICENSING_VERSIONS_LIST: null, TOGGLE_NAVIGATION_ITEM: null, softwareProductEditor: { @@ -34,23 +33,7 @@ export const actionTypes = keyMirror({ } }); -export const navigationItems = keyMirror({ - VENDOR_SOFTWARE_PRODUCT: 'vendor-software-product', - GENERAL: 'general', - PROCESS_DETAILS: 'process-details', - DEPLOYMENT_FLAVORS: 'deployment-flavor', - NETWORKS: 'networks', - IMAGES: 'images', - ATTACHMENTS: 'attachments', - ACTIVITY_LOG: 'activity-log', - COMPONENTS: 'components', - DEPENDENCIES: 'dependencies', - COMPUTE: 'compute', - LOAD_BALANCING: 'load-balancing', - STORAGE: 'storage', - MONITORING: 'monitoring' -}); export const onboardingMethod = { MANUAL: 'Manual', @@ -69,22 +52,3 @@ export const forms = keyMirror({ export const PRODUCT_QUESTIONNAIRE = 'product'; -export const mapScreenToNavigationItem = { - [enums.SCREEN.SOFTWARE_PRODUCT_LANDING_PAGE]: navigationItems.VENDOR_SOFTWARE_PRODUCT, - [enums.SCREEN.SOFTWARE_PRODUCT_DETAILS]: navigationItems.GENERAL, - [enums.SCREEN.SOFTWARE_PRODUCT_ATTACHMENTS]: navigationItems.ATTACHMENTS, - [enums.SCREEN.SOFTWARE_PRODUCT_PROCESSES]: navigationItems.PROCESS_DETAILS, - [enums.SCREEN.SOFTWARE_PRODUCT_DEPLOYMENT]: navigationItems.DEPLOYMENT_FLAVORS, - [enums.SCREEN.SOFTWARE_PRODUCT_NETWORKS]: navigationItems.NETWORKS, - [enums.SCREEN.SOFTWARE_PRODUCT_ACTIVITY_LOG]: navigationItems.ACTIVITY_LOG, - [enums.SCREEN.SOFTWARE_PRODUCT_DEPENDENCIES]: navigationItems.DEPENDENCIES, - [enums.SCREEN.SOFTWARE_PRODUCT_COMPONENTS]: navigationItems.COMPONENTS, - [enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_GENERAL]: navigationItems.GENERAL, - [enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_COMPUTE]: navigationItems.COMPUTE, - [enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_LOAD_BALANCING]: navigationItems.LOAD_BALANCING, - [enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_NETWORK]: navigationItems.NETWORKS, - [enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_IMAGES]: navigationItems.IMAGES, - [enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_STORAGE]: navigationItems.STORAGE, - [enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_PROCESSES]: navigationItems.PROCESS_DETAILS, - [enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_MONITORING]: navigationItems.MONITORING, -}; diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductListReducer.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductListReducer.js index 2fde8c2216..31be338ff5 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductListReducer.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductListReducer.js @@ -22,8 +22,6 @@ export default (state = [], action) => { case actionTypes.SOFTWARE_PRODUCT_LIST_EDIT: const indexForEdit = state.findIndex(vsp => vsp.id === action.payload.softwareProduct.id); return [...state.slice(0, indexForEdit), action.payload.softwareProduct, ...state.slice(indexForEdit + 1)]; - case actionTypes.ADD_SOFTWARE_PRODUCT: - return [...state, action.softwareProduct]; default: return state; } diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachments.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachments.js index f14c988866..234953ec3b 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachments.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachments.js @@ -20,13 +20,12 @@ import SoftwareProductActionHelper from 'sdc-app/onboarding/softwareProduct/Soft import HeatSetupActionHelper from './setup/HeatSetupActionHelper.js'; import SoftwareProductAttachmentsView from './SoftwareProductAttachmentsView.jsx'; import {errorLevels} from 'sdc-app/onboarding/softwareProduct/attachments/validation/HeatValidationConstants.js'; -import OnboardingActionHelper from 'sdc-app/onboarding/OnboardingActionHelper.js'; import HeatSetup from './setup/HeatSetup.js'; import {doesHeatDataExist} from './SoftwareProductAttachmentsUtils.js'; +import ScreensHelper from 'sdc-app/common/helpers/ScreensHelper.js'; +import {enums, screenTypes} from 'sdc-app/onboarding/OnboardingConstants.js'; import SoftwareProductAttachmentsActionHelper from './SoftwareProductAttachmentsActionHelper.js'; -import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js'; - export const mapStateToProps = (state) => { let { softwareProduct: { @@ -46,8 +45,6 @@ export const mapStateToProps = (state) => { } let heatDataExist = doesHeatDataExist(heatSetup); - let isReadOnlyMode = currentSoftwareProduct && currentSoftwareProduct.version ? - VersionControllerUtils.isReadOnly(currentSoftwareProduct) : false; let {version, onboardingOrigin} = currentSoftwareProduct; return { isValidationAvailable: unassigned.length === 0 && modules.length > 0, @@ -56,17 +53,16 @@ export const mapStateToProps = (state) => { heatDataExist, goToOverview, HeatSetupComponent: HeatSetup, - isReadOnlyMode, version, onboardingOrigin, activeTab }; }; -export const mapActionsToProps = (dispatch, {softwareProductId}) => { +export const mapActionsToProps = (dispatch, {softwareProductId, version}) => { return { - onDownload: ({heatCandidate, isReadOnlyMode, version}) => SoftwareProductActionHelper.downloadHeatFile(dispatch, {softwareProductId, heatCandidate, isReadOnlyMode, version}), - onUpload: (formData, version) => dispatch({ + onDownload: ({heatCandidate, isReadOnlyMode}) => SoftwareProductActionHelper.downloadHeatFile(dispatch, {softwareProductId, heatCandidate, isReadOnlyMode, version}), + onUpload: (formData) => dispatch({ type: modalActionTypes.GLOBAL_MODAL_WARNING, data:{ msg: i18n('Upload will erase existing data. Do you want to continue?'), @@ -79,15 +75,25 @@ export const mapActionsToProps = (dispatch, {softwareProductId}) => { }) } }), - onSave: (heatCandidate, version) => SoftwareProductActionHelper.updateSoftwareProductHeatCandidate(dispatch, {softwareProductId, heatCandidate, version}), - onGoToOverview: ({version}) => { - OnboardingActionHelper.navigateToSoftwareProductLandingPage(dispatch, {softwareProductId, version}); - }, - onProcessAndValidate: ({heatData, heatDataCache, isReadOnlyMode, version}) => { + onInvalidFileUpload: () => dispatch({ + type: modalActionTypes.GLOBAL_MODAL_ERROR, + data: { + title: i18n('Upload Failed'), + confirmationButtonText: i18n('Continue'), + msg: i18n('no zip or csar file was uploaded or expected file doesn\'t exist') + } + }), + onSave: (heatCandidate) => SoftwareProductActionHelper.updateSoftwareProductHeatCandidate(dispatch, {softwareProductId, heatCandidate, version}), + onGoToOverview: () => ScreensHelper.loadScreen(dispatch, { + screen: enums.SCREEN.SOFTWARE_PRODUCT_LANDING_PAGE, screenType: screenTypes.SOFTWARE_PRODUCT, + props: {softwareProductId, version} + }), + onProcessAndValidate: ({heatData, heatDataCache, isReadOnlyMode}) => { return HeatSetupActionHelper.processAndValidateHeat(dispatch, {softwareProductId, heatData, heatDataCache, isReadOnlyMode, version}); }, setActiveTab: ({activeTab}) => SoftwareProductAttachmentsActionHelper.setActiveTab(dispatch, {activeTab}) + }; }; diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachmentsView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachmentsView.jsx index 8c59b2b1cc..a23015732b 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachmentsView.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachmentsView.jsx @@ -13,12 +13,12 @@ * or implied. See the License for the specific language governing * permissions and limitations under the License. */ -import React, {Component, PropTypes} from 'react'; -import Tabs from 'react-bootstrap/lib/Tabs.js'; -import Tab from 'react-bootstrap/lib/Tab.js'; +import React, {Component} from 'react'; +import PropTypes from 'prop-types'; +import accept from 'attr-accept'; +import {SVGIcon, Tab, Tabs} from 'sdc-ui/lib/react'; import {tabsMapping} from './SoftwareProductAttachmentsConstants.js'; import i18n from 'nfvo-utils/i18n/i18n.js'; -import SVGIcon from 'sdc-ui/lib/react/SVGIcon.js'; import HeatValidation from './validation/HeatValidation.js'; import {onboardingOriginTypes} from 'sdc-app/onboarding/softwareProduct/SoftwareProductConstants.js'; @@ -27,7 +27,7 @@ class HeatScreenView extends Component { static propTypes = { isValidationAvailable: PropTypes.bool, goToOverview: PropTypes.bool, - setActiveTab: PropTypes.function + setActiveTab: PropTypes.func }; render() { @@ -64,7 +64,7 @@ class HeatScreenView extends Component { labelPosition='right' color='secondary' disabled={isReadOnlyMode} - onClick={evt => {this.refs.hiddenImportFileInput.click(evt);}} + onClick={isReadOnlyMode ? undefined : evt => this.refs.hiddenImportFileInput.click(evt)} data-test-id='upload-heat'/> <input ref='hiddenImportFileInput' @@ -73,8 +73,12 @@ class HeatScreenView extends Component { accept='.zip, .csar' onChange={evt => this.handleImport(evt)}/> </div> - <Tabs id='attachments-tabs' activeKey={activeTab} onSelect={key => this.handleTabPress(key)}> - <Tab eventKey={tabsMapping.SETUP} title='Setup' disabled={onboardingOrigin === onboardingOriginTypes.CSAR}> + <Tabs + className='attachments-tabs' + type='header' + activeTab={activeTab} + onTabClick={key => this.handleTabPress(key)}> + <Tab tabId={tabsMapping.SETUP} title='Setup' disabled={onboardingOrigin === onboardingOriginTypes.CSAR}> <HeatSetupComponent heatDataExist={heatDataExist} changeAttachmentsTab={tab => setActiveTab({activeTab: tab})} @@ -83,7 +87,7 @@ class HeatScreenView extends Component { isReadOnlyMode={isReadOnlyMode} version={version}/> </Tab> - <Tab eventKey={tabsMapping.VALIDATION} title='Validation' disabled={!isValidationAvailable}> + <Tab tabId={tabsMapping.VALIDATION} title='Validation' disabled={!isValidationAvailable}> <HeatValidation {...other}/> </Tab> </Tabs> @@ -107,9 +111,14 @@ class HeatScreenView extends Component { handleImport(evt) { evt.preventDefault(); + let file = this.refs.hiddenImportFileInput.files[0]; + if(! (file && file.size && accept(file, ['.zip', '.csar'])) ) { + this.props.onInvalidFileUpload(); + return; + } let {version} = this.props; let formData = new FormData(); - formData.append('upload', this.refs.hiddenImportFileInput.files[0]); + formData.append('upload', file); this.refs.hiddenImportFileInput.value = ''; this.props.onUpload(formData, version); } diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/validation/HeatValidationView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/validation/HeatValidationView.jsx index 2308527220..3fdaa9c591 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/validation/HeatValidationView.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/validation/HeatValidationView.jsx @@ -13,7 +13,8 @@ * or implied. See the License for the specific language governing * permissions and limitations under the License. */ -import React, {Component, PropTypes} from 'react'; +import React, {Component} from 'react'; +import PropTypes from 'prop-types'; import classNames from 'classnames'; import Collapse from 'react-bootstrap/lib/Collapse.js'; import SVGIcon from 'sdc-ui/lib/react/SVGIcon.js'; @@ -95,7 +96,7 @@ function HeatFileTreeHeader(props) { <div className='tree-header-title' > {/*<SVGIcon name='zip' color={props.selectedNode === nodeFilters.ALL ? 'primary' : ''} iconClassName='header-icon' />*/} <span className={classNames({'tree-header-title-text' : true, - 'tree-header-title-selected' : props.selectedNode === nodeFilters.ALL})}>{i18n(`${props.headerTitle} ${hasErrors ? '(Draft)' : ''}`)}</span> + 'tree-header-title-selected' : props.selectedNode === nodeFilters.ALL})}>{i18n('{title} {hasErrors}', {title: props.headerTitle, hasErrors: hasErrors ? '(Draft)' : ''})}</span> </div> <ErrorsAndWarningsCount errorList={props.errorList} size='large' /> </div>); @@ -199,7 +200,6 @@ class HeatMessageBoard extends Component { } renderError(error) { let rand = Math.random() * (3000 - 1) + 1; - console.log(this.props.selectedNode ); return ( <div key={error.name + error.errorMessage + error.parentName + rand} diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponents.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponents.js index 61aebdf293..f74b2fe2fb 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponents.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponents.js @@ -1,62 +1,47 @@ import {connect} from 'react-redux'; -import React from 'react'; import i18n from 'nfvo-utils/i18n/i18n.js'; -import SoftwareProductComponentsList from './SoftwareProductComponentsList.js'; -import OnboardingActionHelper from 'sdc-app/onboarding/OnboardingActionHelper.js'; -import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js'; import SoftwareProductComponentsActionHelper from '../components/SoftwareProductComponentsActionHelper.js'; -import {onboardingMethod} from '../SoftwareProductConstants.js'; +import {onboardingMethod as onboardingMethodTypes} from '../SoftwareProductConstants.js'; import ConfirmationModalConstants from 'nfvo-components/modal/GlobalModalConstants.js'; +import ScreensHelper from 'sdc-app/common/helpers/ScreensHelper.js'; +import {screenTypes} from 'sdc-app/onboarding/OnboardingConstants.js'; +import SoftwareProductComponentsView from './SoftwareProductComponentsListView.jsx'; +import SoftwareProductActionHelper from 'sdc-app/onboarding/softwareProduct/SoftwareProductActionHelper.js'; const generateMessage = (name) => { - return i18n(`Are you sure you want to delete ${name}?`); + return i18n('Are you sure you want to delete {name}?', {name: name}); }; -const mapStateToProps = ({softwareProduct}) => { - let {softwareProductEditor: {data: currentSoftwareProduct}, softwareProductComponents} = softwareProduct; +const mapStateToProps = ({softwareProduct, currentScreen: {props: {version}}}) => { + let {softwareProductEditor: {data: currentSoftwareProduct = {}}, softwareProductComponents} = softwareProduct; let {componentsList} = softwareProductComponents; - let isReadOnlyMode = VersionControllerUtils.isReadOnly(currentSoftwareProduct); - + let {onboardingMethod = onboardingMethodTypes.HEAT} = currentSoftwareProduct; return { currentSoftwareProduct, - isReadOnlyMode, componentsList, - isManual: currentSoftwareProduct.onboardingMethod === onboardingMethod.MANUAL - + isManual: onboardingMethod === onboardingMethodTypes.MANUAL, + version }; }; -class SoftwareProductComponentsView extends React.Component { - render() { - let {currentSoftwareProduct, isReadOnlyMode, componentsList, isManual, onDeleteComponent} = this.props; - return ( - <SoftwareProductComponentsList - isReadOnlyMode={isReadOnlyMode} - componentsList={componentsList} - onDeleteComponent={onDeleteComponent} - isManual={isManual} - currentSoftwareProduct={currentSoftwareProduct}/>); - } - -} - const mapActionToProps = (dispatch) => { return { - onComponentSelect: ({id: softwareProductId, componentId, version}) => { - OnboardingActionHelper.navigateToSoftwareProductComponentGeneralAndUpdateLeftPanel(dispatch, {softwareProductId, componentId, version }); - }, - onAddComponent: (softwareProductId) => SoftwareProductComponentsActionHelper.addComponent(dispatch, {softwareProductId}), + onComponentSelect: ({id: softwareProductId, componentId, version}) => + ScreensHelper.loadScreen(dispatch, { + screen: screenTypes.SOFTWARE_PRODUCT_COMPONENT_DEFAULT_GENERAL, screenType: screenTypes.SOFTWARE_PRODUCT, + props: {softwareProductId, version, componentId} + }), + onAddComponent: (softwareProductId, version) => SoftwareProductActionHelper.addComponent(dispatch, {softwareProductId, version, modalClassName: 'create-vfc-modal'}), onDeleteComponent: (component, softwareProductId, version) => dispatch({ type: ConfirmationModalConstants.GLOBAL_MODAL_WARNING, data:{ msg: generateMessage(component.displayName), - onConfirmed: ()=>SoftwareProductComponentsActionHelper.deleteComponent(dispatch, - { - softwareProductId, - componentId: component.id, - version - }) + onConfirmed: ()=>SoftwareProductComponentsActionHelper.deleteComponent(dispatch, { + softwareProductId, + componentId: component.id, + version + }) } }) }; diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsActionHelper.js index 8085c875f4..cf63ad79d0 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsActionHelper.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsActionHelper.js @@ -74,6 +74,7 @@ const SoftwareProductComponentsActionHelper = { type: actionTypes.COMPONENTS_LIST_UPDATE, componentsList: response.results }); + return response; }); }, diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsList.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsList.js deleted file mode 100644 index bd4c2fa884..0000000000 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsList.js +++ /dev/null @@ -1,51 +0,0 @@ -/*! - * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ -import {connect} from 'react-redux'; -import i18n from 'nfvo-utils/i18n/i18n.js'; - -import SoftwareProductComponentsListView from './SoftwareProductComponentsListView.jsx'; -import OnboardingActionHelper from 'sdc-app/onboarding/OnboardingActionHelper.js'; -import SoftwareProductActionHelper from 'sdc-app/onboarding/softwareProduct/SoftwareProductActionHelper.js'; -import SoftwareProductComponentsActionHelper from '../components/SoftwareProductComponentsActionHelper.js'; -import {actionTypes as globalModalActions} from 'nfvo-components/modal/GlobalModalConstants.js'; - -const generateMessage = (name) => { - return i18n(`Are you sure you want to delete ${name}?`); -}; - - -const mapActionToProps = (dispatch) => { - return { - onComponentSelect: ({id: softwareProductId, componentId, version}) => { - OnboardingActionHelper.navigateToSoftwareProductComponentGeneralAndUpdateLeftPanel(dispatch, {softwareProductId, componentId, version }); - }, - onAddComponent: (softwareProductId) => SoftwareProductActionHelper.addComponent(dispatch, {softwareProductId, modalClassName: 'create-vfc-modal'}), - onDeleteComponent: (component, softwareProductId, version) => dispatch({ - type: globalModalActions.GLOBAL_MODAL_WARNING, - data:{ - msg: generateMessage(component.displayName), - onConfirmed: ()=>SoftwareProductComponentsActionHelper.deleteComponent(dispatch, - { - softwareProductId, - componentId: component.id, - version - }) - } - }) - }; -}; - -export default connect(null, mapActionToProps, null, {withRef: true})(SoftwareProductComponentsListView); diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsListView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsListView.jsx index 88a01becfc..0bf32df1a3 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsListView.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsListView.jsx @@ -14,17 +14,18 @@ * permissions and limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import i18n from 'nfvo-utils/i18n/i18n.js'; import ListEditorView from 'nfvo-components/listEditor/ListEditorView.jsx'; import ListEditorItemView from 'nfvo-components/listEditor/ListEditorItemView.jsx'; import ListEditorItemViewField from 'nfvo-components/listEditor/ListEditorItemViewField.jsx'; -const ComponentPropType = React.PropTypes.shape({ - id: React.PropTypes.string, - name: React.PropTypes.string, - displayName: React.PropTypes.string, - description: React.PropTypes.string +const ComponentPropType = PropTypes.shape({ + id: PropTypes.string, + name: PropTypes.string, + displayName: PropTypes.string, + description: PropTypes.string }); class SoftwareProductComponentsListView extends React.Component { @@ -34,9 +35,9 @@ class SoftwareProductComponentsListView extends React.Component { }; static propTypes = { - isReadOnlyMode: React.PropTypes.bool, - componentsList: React.PropTypes.arrayOf(ComponentPropType), - onComponentSelect: React.PropTypes.func + isReadOnlyMode: PropTypes.bool, + componentsList: PropTypes.arrayOf(ComponentPropType), + onComponentSelect: PropTypes.func }; render() { @@ -52,7 +53,7 @@ class SoftwareProductComponentsListView extends React.Component { renderComponents() { const {localFilter} = this.state; - const {isManual, onAddComponent, isReadOnlyMode, currentSoftwareProduct: {id: softwareProductId}, componentsList } = this.props; + const {isManual, onAddComponent, isReadOnlyMode, version, currentSoftwareProduct: {id: softwareProductId}, componentsList } = this.props; return ( <ListEditorView title={i18n('Virtual Function Components')} @@ -61,7 +62,7 @@ class SoftwareProductComponentsListView extends React.Component { onFilter={value => this.setState({localFilter: value})} isReadOnlyMode={isReadOnlyMode || !!this.filterList().length} plusButtonTitle={i18n('Add Component')} - onAdd={isManual && componentsList.length === 0 ? () => onAddComponent(softwareProductId) : false} + onAdd={isManual && componentsList.length === 0 ? () => onAddComponent(softwareProductId, version) : false} twoColumns> {this.filterList().map(component => this.renderComponentsListItem(component))} </ListEditorView> @@ -70,7 +71,7 @@ class SoftwareProductComponentsListView extends React.Component { renderComponentsListItem(component) { let {id: componentId, name, displayName, description = ''} = component; - let {currentSoftwareProduct: {id, version}, onComponentSelect} = this.props; + let {currentSoftwareProduct: {id}, onComponentSelect, version} = this.props; return ( <ListEditorItemView key={name + Math.floor(Math.random() * (100 - 1) + 1).toString()} 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 bb8df29b82..574828c9ef 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 @@ -16,24 +16,19 @@ 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'; import {onboardingMethod} from 'sdc-app/onboarding/softwareProduct/SoftwareProductConstants.js'; -const mapStateToProps = ({softwareProduct, currentScreen: {props: {softwareProductId, componentId}}}) => { +const mapStateToProps = ({softwareProduct}) => { let {softwareProductEditor: {data: currentVSP}, softwareProductComponents} = softwareProduct; let {componentEditor: {qdata, dataMap, qgenericFieldInfo}, computeFlavor: {computesList: computeFlavorsList}} = softwareProductComponents; - let isReadOnlyMode = VersionControllerUtils.isReadOnly(currentVSP); return { qdata, dataMap, qgenericFieldInfo, - isReadOnlyMode, - softwareProductId, - componentId, computeFlavorsList, isManual: currentVSP.onboardingMethod === onboardingMethod.MANUAL }; diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/SoftwareProductComponentComputeView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/SoftwareProductComponentComputeView.jsx index dd524a35f3..55e5e2b30b 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/SoftwareProductComponentComputeView.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/SoftwareProductComponentComputeView.jsx @@ -14,6 +14,7 @@ * permissions and limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import Form from 'nfvo-components/input/validation/Form.jsx'; import NumberOfVms from './computeComponents/NumberOfVms.jsx'; import GuestOs from './computeComponents/GuestOs.jsx'; @@ -23,13 +24,13 @@ import Validator from 'nfvo-utils/Validator.js'; class SoftwareProductComponentComputeView extends React.Component { static propTypes = { - dataMap: React.PropTypes.object, - qgenericFieldInfo: React.PropTypes.object, - isReadOnlyMode: React.PropTypes.bool, - isManual: React.PropTypes.bool, - onQDataChanged: React.PropTypes.func.isRequired, - qValidateData: React.PropTypes.func.isRequired, - onSubmit: React.PropTypes.func.isRequired + dataMap: PropTypes.object, + qgenericFieldInfo: PropTypes.object, + isReadOnlyMode: PropTypes.bool, + isManual: PropTypes.bool, + onQDataChanged: PropTypes.func.isRequired, + qValidateData: PropTypes.func.isRequired, + onSubmit: PropTypes.func.isRequired }; render() { diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/computeComponents/ComputeFlavors.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/computeComponents/ComputeFlavors.js index c72d42c11f..2b6d84f381 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/computeComponents/ComputeFlavors.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/computeComponents/ComputeFlavors.js @@ -14,6 +14,7 @@ * permissions and limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import {connect} from 'react-redux'; import i18n from 'nfvo-utils/i18n/i18n.js'; import ListEditorView from 'nfvo-components/listEditor/ListEditorView.jsx'; @@ -28,26 +29,26 @@ const mapActionsToProps = (dispatch, {softwareProductId, componentId, version}) onDeleteCompute: ({id, name}) => dispatch({ type: modalActionTypes.GLOBAL_MODAL_WARNING, data:{ - msg: i18n(`Are you sure you want to delete "${name}"?`), + msg: i18n('Are you sure you want to delete "{name}"?', {name: name}), onConfirmed: () => ComputeFlavorActionHelper.deleteCompute(dispatch, {softwareProductId, componentId, computeId: id, version}) } }) }; }; -const computeItemPropType = React.PropTypes.shape({ - id: React.PropTypes.string, - name: React.PropTypes.string, - description: React.PropTypes.string +const computeItemPropType = PropTypes.shape({ + id: PropTypes.string, + name: PropTypes.string, + description: PropTypes.string }); class ComputeFlavors extends React.Component { static propTypes = { - isReadOnlyMode: React.PropTypes.bool, - isManual: React.PropTypes.bool, - onAddComputeClick: React.PropTypes.func, - computeFlavorsList: React.PropTypes.arrayOf(computeItemPropType) + isReadOnlyMode: PropTypes.bool, + isManual: PropTypes.bool, + onAddComputeClick: PropTypes.func, + computeFlavorsList: PropTypes.arrayOf(computeItemPropType) }; state = { diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/computeComponents/GuestOs.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/computeComponents/GuestOs.jsx index 16bf599834..8ae9961859 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/computeComponents/GuestOs.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/computeComponents/GuestOs.jsx @@ -23,7 +23,7 @@ import GridItem from 'nfvo-components/grid/GridItem.jsx'; const GuestOs = ({qgenericFieldInfo, dataMap, onQDataChanged}) => { return( <div> - <GridSection title={i18n('Guest OS')} > + <GridSection title={i18n('Guest OS')} hasLastColSet> <GridItem> <div className='vertical-flex'> <label key='label' className='control-label'>{i18n('OS Bit Size')}</label> @@ -55,7 +55,7 @@ const GuestOs = ({qgenericFieldInfo, dataMap, onQDataChanged}) => { errorText={qgenericFieldInfo['compute/guestOS/name'].errorText} value={dataMap['compute/guestOS/name']} /> </GridItem> - <GridItem colSpan={2}> + <GridItem colSpan={2} lastColInRow> <Input data-test-id='guestOS-tools' type='textarea' diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/computeComponents/NumberOfVms.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/computeComponents/NumberOfVms.jsx index ddde4391d9..967c6f7aef 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/computeComponents/NumberOfVms.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/computeComponents/NumberOfVms.jsx @@ -14,6 +14,7 @@ * permissions and limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import i18n from 'nfvo-utils/i18n/i18n.js'; import Input from 'nfvo-components/input/validation/Input.jsx'; import GridSection from 'nfvo-components/grid/GridSection.jsx'; @@ -50,7 +51,7 @@ const NumberOfVms = ({qgenericFieldInfo, dataMap, onQDataChanged, qValidateData, }; NumberOfVms.propTypes = { - minNumberOfVMsSelectedByUser: React.PropTypes.number + minNumberOfVMsSelectedByUser: PropTypes.number }; export default NumberOfVms; diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/computeComponents/computeFlavor/ComputeFlavorEditor.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/computeComponents/computeFlavor/ComputeFlavorEditor.js index caec0702fd..a3ba5fbc4a 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/computeComponents/computeFlavor/ComputeFlavorEditor.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/computeComponents/computeFlavor/ComputeFlavorEditor.js @@ -16,15 +16,21 @@ import {connect} from 'react-redux'; import ComputeFlavorEditorView from './ComputeFlavorEditorView.jsx'; import {COMPUTE_FLAVOR_FORM} from './ComputeFlavorConstants.js'; -import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js'; import ComputeFlavorActionHelper from 'sdc-app/onboarding/softwareProduct/components/compute/ComputeFlavorActionHelper.js'; import ValidationHelper from 'sdc-app/common/helpers/ValidationHelper.js'; import {COMPONENTS_COMPUTE_QUESTIONNAIRE} from 'sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsConstants.js'; import {onboardingMethod} from 'sdc-app/onboarding/softwareProduct/SoftwareProductConstants.js'; -export const mapStateToProps = ({softwareProduct: {softwareProductEditor, softwareProductComponents: {computeFlavor: {computeEditor = {}}}}}) => { +export const mapStateToProps = ({ + softwareProduct: { + softwareProductEditor, + softwareProductComponents: {computeFlavor: {computeEditor = {}}} + }, + currentScreen: { + props: {isReadOnlyMode} + } +}) => { const {data: currentSoftwareProduct = {}} = softwareProductEditor; - const isReadOnlyMode = VersionControllerUtils.isReadOnly(currentSoftwareProduct); let {data , qdata, qgenericFieldInfo, dataMap, genericFieldInfo, formReady} = computeEditor; let isFormValid = ValidationHelper.checkFormValid(genericFieldInfo); diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/computeComponents/computeFlavor/ComputeFlavorEditorView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/computeComponents/computeFlavor/ComputeFlavorEditorView.jsx index 8f8a504629..e542ce1fd1 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/computeComponents/computeFlavor/ComputeFlavorEditorView.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/computeComponents/computeFlavor/ComputeFlavorEditorView.jsx @@ -14,6 +14,7 @@ * permissions and limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import Form from 'nfvo-components/input/validation/Form.jsx'; import Input from 'nfvo-components/input/validation/Input.jsx'; import GridSection from 'nfvo-components/grid/GridSection.jsx'; @@ -24,15 +25,15 @@ import i18n from 'nfvo-utils/i18n/i18n.js'; class ComputeEditorView extends React.Component { static propTypes = { - data: React.PropTypes.object, - qdata: React.PropTypes.object, - qschema: React.PropTypes.object, - isReadOnlyMode: React.PropTypes.bool, - isManual: React.PropTypes.bool, - onDataChanged: React.PropTypes.func.isRequired, - onQDataChanged: React.PropTypes.func.isRequired, - onSubmit: React.PropTypes.func.isRequired, - onCancel: React.PropTypes.func.isRequired + data: PropTypes.object, + qdata: PropTypes.object, + qschema: PropTypes.object, + isReadOnlyMode: PropTypes.bool, + isManual: PropTypes.bool, + onDataChanged: PropTypes.func.isRequired, + onQDataChanged: PropTypes.func.isRequired, + onSubmit: PropTypes.func.isRequired, + onCancel: PropTypes.func.isRequired }; render() { @@ -57,8 +58,8 @@ class ComputeEditorView extends React.Component { onValidateForm={() => onValidateForm() } className='component-questionnaire-validation-form' submitButtonText={edittingComputeMode ? i18n('Save') : i18n('Create')}> - <GridSection> - <GridItem colSpan={edittingComputeMode ? 2 : 4}> + <GridSection hasLostColSet> + <GridItem colSpan={edittingComputeMode ? 2 : 4} lastColInRow={!edittingComputeMode}> <Input disabled={!isManual} data-test-id='name' @@ -70,7 +71,7 @@ class ComputeEditorView extends React.Component { errorText={genericFieldInfo['name'].errorText} isRequired/> </GridItem> - <GridItem colSpan={edittingComputeMode ? 2 : 4}> + <GridItem colSpan={edittingComputeMode ? 2 : 4} lastColInRow> <Input data-test-id='description' type='textarea' diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/computeComponents/computeFlavor/VmSizing.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/computeComponents/computeFlavor/VmSizing.jsx index 8b30468362..54f22e0760 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/computeComponents/computeFlavor/VmSizing.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/compute/computeComponents/computeFlavor/VmSizing.jsx @@ -20,7 +20,7 @@ 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')}> + <GridSection title={i18n('VM Sizing')} hasLastColSet> <GridItem> <Input data-test-id='numOfCPUs' @@ -51,7 +51,7 @@ const VmSizing = ({qgenericFieldInfo, dataMap, onQDataChanged}) => { errorText={qgenericFieldInfo['vmSizing/persistentStorageVolumeSize'].errorText} value={dataMap['vmSizing/persistentStorageVolumeSize']} /> </GridItem> - <GridItem> + <GridItem lastColInRow> <Input data-test-id='ioOperationsPerSec' type='number' diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/creation/SoftwareProductComponentCreation.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/creation/SoftwareProductComponentCreation.js index e85b6b6504..9f59cd5b27 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/creation/SoftwareProductComponentCreation.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/creation/SoftwareProductComponentCreation.js @@ -21,23 +21,22 @@ import ValidationHelper from 'sdc-app/common/helpers/ValidationHelper.js'; import {forms} from '../SoftwareProductComponentsConstants.js'; export const mapStateToProps = ({softwareProduct}) => { - let {softwareProductComponents: {componentEditor: {data, genericFieldInfo, formReady}}, softwareProductEditor: {data: {version}}} = softwareProduct; + let {softwareProductComponents: {componentEditor: {data, genericFieldInfo, formReady}}} = softwareProduct; let isFormValid = ValidationHelper.checkFormValid(genericFieldInfo); return { data, genericFieldInfo, formReady, - isFormValid, - version + isFormValid }; }; -const mapActionsToProps = (dispatch, {softwareProductId}) => { +const mapActionsToProps = (dispatch, {softwareProductId, version}) => { return { onDataChanged: (deltaData) => ValidationHelper.dataChanged(dispatch, {deltaData, formName: forms.CREATE_FORM}), //onDataChanged: deltaData => SoftwareProductComponentsActionHelper.componentDataChanged(dispatch, {deltaData}), - onSubmit: (componentData, version) => { + onSubmit: (componentData) => { return SoftwareProductComponentsActionHelper.createSoftwareProductComponent(dispatch, {softwareProductId, componentData, version}); }, diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/creation/SoftwareProductComponentCreationView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/creation/SoftwareProductComponentCreationView.jsx index 55bcc818f5..42804ce5a6 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/creation/SoftwareProductComponentCreationView.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/creation/SoftwareProductComponentCreationView.jsx @@ -28,7 +28,7 @@ class ComponentCreationView extends React.Component { let {data = {}, onDataChanged, onCancel, genericFieldInfo} = this.props; let {displayName, description} = data; return( - <div> + <div> { genericFieldInfo && <Form ref='validationForm' @@ -41,8 +41,8 @@ class ComponentCreationView extends React.Component { formReady={this.props.formReady} onValidateForm={() => this.props.onValidateForm(forms.CREATE_FORM) } className='entitlement-pools-form'> - <GridSection> - <GridItem colSpan={4}> + <GridSection hasLastColSet> + <GridItem colSpan={4} lastColInRow> <Input data-test-id='name' onChange={displayName => onDataChanged({displayName})} @@ -53,7 +53,7 @@ class ComponentCreationView extends React.Component { value={displayName} type='text'/> </GridItem> - <GridItem colSpan={4}> + <GridItem colSpan={4} lastColInRow> <Input label={i18n('Description')} onChange={description => onDataChanged({description})} @@ -66,13 +66,13 @@ class ComponentCreationView extends React.Component { </GridSection> </Form> } - </div> + </div> ); } submit() { - const {onSubmit, data, version} = this.props; - onSubmit(data, version); + const {onSubmit, data} = this.props; + onSubmit(data); } } diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/general/SoftwareProductComponentsGeneral.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/general/SoftwareProductComponentsGeneral.js index 7b4135028b..8c06fd0ab8 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/general/SoftwareProductComponentsGeneral.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/general/SoftwareProductComponentsGeneral.js @@ -16,25 +16,20 @@ import {connect} from 'react-redux'; import SoftwareProductComponentsGeneralView from './SoftwareProductComponentsGeneralView.jsx'; import SoftwareProductComponentsActionHelper from '../SoftwareProductComponentsActionHelper.js'; -import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js'; import ValidationHelper from 'sdc-app/common/helpers/ValidationHelper.js'; import SoftwareProductActionHelper from 'sdc-app/onboarding/softwareProduct/SoftwareProductActionHelper.js'; - import {forms, COMPONENTS_QUESTIONNAIRE} from '../SoftwareProductComponentsConstants.js'; import {onboardingMethod} from '../../SoftwareProductConstants.js'; - export const mapStateToProps = ({softwareProduct}) => { let {softwareProductEditor: {data: currentVSP}, softwareProductComponents} = softwareProduct; let {componentEditor: {data: componentData = {} , qdata, qgenericFieldInfo : qGenericFieldInfo, dataMap, genericFieldInfo}} = softwareProductComponents; - let isReadOnlyMode = VersionControllerUtils.isReadOnly(currentVSP); let isFormValid = ValidationHelper.checkFormValid(genericFieldInfo); return { componentData, qdata, - isReadOnlyMode, isManual: currentVSP.onboardingMethod === onboardingMethod.MANUAL, genericFieldInfo, qGenericFieldInfo, @@ -43,7 +38,6 @@ export const mapStateToProps = ({softwareProduct}) => { }; }; - const mapActionsToProps = (dispatch, {softwareProductId, version, componentId}) => { return { onDataChanged: (deltaData) => ValidationHelper.dataChanged(dispatch, {deltaData, formName: forms.ALL_SPC_FORMS}), diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/SoftwareProductComponentsImageActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/SoftwareProductComponentsImageActionHelper.js index 34198281b7..8d70d6f14c 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/SoftwareProductComponentsImageActionHelper.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/SoftwareProductComponentsImageActionHelper.js @@ -87,7 +87,7 @@ const SoftwareProductComponentImagesActionHelper = { return fetchImage({softwareProductId, componentId, imageId, version}); }, - openEditImageEditor(dispatch, {image, softwareProductId, componentId, version, isReadOnlyMode, modalClassName}) { + openEditImageEditor(dispatch, {image, softwareProductId, componentId, version, isReadOnlyMode}) { return SoftwareProductComponentImagesActionHelper.loadImageData({softwareProductId, componentId, imageId: image.id, version}).then(({data}) => { SoftwareProductComponentImagesActionHelper.loadImageQuestionnaire(dispatch, { softwareProductId, @@ -100,7 +100,6 @@ const SoftwareProductComponentImagesActionHelper = { componentId, version, isReadOnlyMode, - modalClassName, image, data }); @@ -110,12 +109,13 @@ const SoftwareProductComponentImagesActionHelper = { openImageEditor(dispatch, {image = {}, data = {}, softwareProductId, componentId, version, isReadOnlyMode}) { - let title = (image && image.id) ? i18n('Edit Image') : i18n('Create New Image'); - let className = (image && image.id) ? 'image-edit-editor-model' : 'image-new-editor-modal'; + let {id} = image; + let title = id ? i18n('Edit Image') : i18n('Create New Image'); + let className = id ? 'image-modal-edit' : 'image-modal-new'; dispatch({ type: actionTypes.ImageEditor.OPEN, - image: {...data, id: image.id} + image: {...data, id} }); dispatch({ @@ -123,9 +123,11 @@ const SoftwareProductComponentImagesActionHelper = { data: { modalComponentName: modalContentMapper.SOFTWARE_PRODUCT_COMPONENT_IMAGE_EDITOR, title: title, - modalComponentProps: {softwareProductId, componentId, version, isReadOnlyMode, dialogClassName:className} + modalClassName: className, + modalComponentProps: {softwareProductId, componentId, version, isReadOnlyMode} } }); + }, closeImageEditor(dispatch) { @@ -137,6 +139,7 @@ const SoftwareProductComponentImagesActionHelper = { dispatch({ type: actionTypes.ImageEditor.CLOSE }); + }, loadImageQuestionnaire(dispatch, {softwareProductId, componentId, imageId, version}) { @@ -166,4 +169,5 @@ const SoftwareProductComponentImagesActionHelper = { } } }; + export default SoftwareProductComponentImagesActionHelper; diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/SoftwareProductComponentsImageEditor.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/SoftwareProductComponentsImageEditor.js index 5c81f05e80..c5f23e7681 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/SoftwareProductComponentsImageEditor.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/SoftwareProductComponentsImageEditor.js @@ -17,18 +17,19 @@ import {connect} from 'react-redux'; import ValidationHelper from 'sdc-app/common/helpers/ValidationHelper.js'; import SoftwareProductComponentsImageActionHelper from './SoftwareProductComponentsImageActionHelper.js'; import SoftwareProductComponentsImageEditorView from './SoftwareProductComponentsImageEditorView.jsx'; -import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js'; import {onboardingMethod as onboardingMethodTypes} from '../../SoftwareProductConstants.js'; import {forms} from 'sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsConstants.js'; import {IMAGE_QUESTIONNAIRE} from './SoftwareProductComponentsImageConstants.js'; -export const mapStateToProps = ({softwareProduct}) => { +export const mapStateToProps = ({ + softwareProduct, + currentScreen: {props: {isReadOnlyMode}} +}) => { let {softwareProductEditor: {data:currentSoftwareProduct = {}, isValidityData = true}, softwareProductComponents} = softwareProduct; let {images: {imageEditor = {}}} = softwareProductComponents; let {data, qdata, genericFieldInfo, qgenericFieldInfo, dataMap, formReady} = imageEditor; - let isReadOnlyMode = VersionControllerUtils.isReadOnly(currentSoftwareProduct); let {version, onboardingMethod} = currentSoftwareProduct; let isManual = onboardingMethod === onboardingMethodTypes.MANUAL; let isFormValid = ValidationHelper.checkFormValid(genericFieldInfo) && ValidationHelper.checkFormValid(qgenericFieldInfo); @@ -47,6 +48,7 @@ export const mapStateToProps = ({softwareProduct}) => { isReadOnlyMode, isManual: isManual }; + }; const mapActionsToProps = (dispatch, {softwareProductId, componentId, version}) => { diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/SoftwareProductComponentsImageEditorView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/SoftwareProductComponentsImageEditorView.jsx index 7c1a3f5b55..a5ef152e01 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/SoftwareProductComponentsImageEditorView.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/SoftwareProductComponentsImageEditorView.jsx @@ -14,6 +14,7 @@ * permissions and limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import i18n from 'nfvo-utils/i18n/i18n.js'; import Form from 'nfvo-components/input/validation/Form.jsx'; @@ -24,9 +25,9 @@ import {imageCustomValidations} from './ImageValidations.js'; class SoftwareProductComponentsImageEditorView extends React.Component { static propTypes = { - onDataChanged: React.PropTypes.func.isRequired, - onSubmit: React.PropTypes.func.isRequired, - onCancel: React.PropTypes.func.isRequired + onDataChanged: PropTypes.func.isRequired, + onSubmit: PropTypes.func.isRequired, + onCancel: PropTypes.func.isRequired }; render() { diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/SoftwareProductComponentsImageList.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/SoftwareProductComponentsImageList.js index fb3bd35eb2..d071647058 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/SoftwareProductComponentsImageList.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/SoftwareProductComponentsImageList.js @@ -16,7 +16,6 @@ import {connect} from 'react-redux'; import i18n from 'nfvo-utils/i18n/i18n.js'; -import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js'; import {actionTypes as modalActionTypes} from 'nfvo-components/modal/GlobalModalConstants.js'; import SoftwareProductComponentsImageListView from './SoftwareProductComponentsImageListView.jsx'; import ImageHelper from './SoftwareProductComponentsImageActionHelper.js'; @@ -31,38 +30,35 @@ export const mapStateToProps = ({softwareProduct}) => { let {softwareProductEditor: {data: currentSoftwareProduct = {}, isValidityData = true}, softwareProductComponents} = softwareProduct; let {images: {imagesList = []}, componentEditor: {data: componentData, qdata, dataMap, qgenericFieldInfo}} = softwareProductComponents; - let isReadOnlyMode = VersionControllerUtils.isReadOnly(currentSoftwareProduct); - let {version, onboardingMethod} = currentSoftwareProduct; + let {onboardingMethod} = currentSoftwareProduct; let isManual = onboardingMethod === onboardingMethodTypes.MANUAL; return { - version, componentData, qdata, dataMap, qgenericFieldInfo, isValidityData, imagesList, - isReadOnlyMode, isManual : isManual }; }; -const mapActionsToProps = (dispatch, {softwareProductId, componentId}) => { +const mapActionsToProps = (dispatch, {softwareProductId, componentId, version}) => { return { onQDataChanged: (deltaData) => ValidationHelper.qDataChanged(dispatch, {deltaData, qName: COMPONENTS_QUESTIONNAIRE}), - onAddImage: (version, isReadOnlyMode) => { + onAddImage: (isReadOnlyMode) => { SoftwareProductComponentsImagesActionHelper.openImageEditor(dispatch, {isReadOnlyMode, softwareProductId, componentId, version} );}, - onDeleteImage: ((image, version) => { + onDeleteImage: (image) => { let shortenedFileName = (image.fileName.length > 40) ? image.fileName.substr(0,40) + '...' : image.fileName; dispatch({ type: modalActionTypes.GLOBAL_MODAL_WARNING, data: { - msg: i18n(`Are you sure you want to delete "${shortenedFileName}"?`), + msg: i18n('Are you sure you want to delete "{shortenedFileName}"?', {shortenedFileName: shortenedFileName}), onConfirmed: () => ImageHelper.deleteImage(dispatch, { softwareProductId, componentId, @@ -71,13 +67,13 @@ const mapActionsToProps = (dispatch, {softwareProductId, componentId}) => { }) } }); - }), - onEditImageClick: (image, version, isReadOnlyMode) => { + }, + onEditImageClick: (image, isReadOnlyMode) => { SoftwareProductComponentsImagesActionHelper.openEditImageEditor(dispatch, { image, isReadOnlyMode, softwareProductId, componentId, version, modalClassName: 'image-modal-edit'} ); }, - onSubmit: (version, qdata) => { return SoftwareProductComponentsActionHelper.updateSoftwareProductComponentQuestionnaire(dispatch, + onSubmit: (qdata) => { return SoftwareProductComponentsActionHelper.updateSoftwareProductComponentQuestionnaire(dispatch, {softwareProductId, vspComponentId: componentId, version, diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/SoftwareProductComponentsImageListView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/SoftwareProductComponentsImageListView.jsx index 54def08fc1..004cbebe5d 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/SoftwareProductComponentsImageListView.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/SoftwareProductComponentsImageListView.jsx @@ -75,7 +75,7 @@ class SoftwareProductComponentsImageListView extends React.Component { renderImagesList() { const {localFilter} = this.state; - let {isReadOnlyMode, onAddImage, isManual, version} = this.props; + let {isReadOnlyMode, onAddImage, isManual} = this.props; return ( <ListEditorView @@ -84,7 +84,7 @@ class SoftwareProductComponentsImageListView extends React.Component { placeholder={i18n('Filter Images by Name')} isReadOnlyMode={isReadOnlyMode} onFilter={value => this.setState({localFilter: value})} - onAdd={isManual ? () => onAddImage(version, isReadOnlyMode) : null} + onAdd={isManual ? () => onAddImage(isReadOnlyMode) : null} plusButtonTitle={i18n('Add Image')} twoColumns> {this.filterList().map(image => this.renderImagesListItem(image, isReadOnlyMode))} @@ -95,13 +95,13 @@ class SoftwareProductComponentsImageListView extends React.Component { renderImagesListItem(image, isReadOnlyMode) { let {id, fileName} = image; - let {onEditImageClick, version, isManual, onDeleteImage} = this.props; + let {onEditImageClick, isManual, onDeleteImage} = this.props; return ( <ListEditorItemView key={id} isReadOnlyMode={isReadOnlyMode} - onSelect={() => onEditImageClick(image, version, isReadOnlyMode)} - onDelete={isManual ? () => onDeleteImage(image, version) : null}> + onSelect={() => onEditImageClick(image, isReadOnlyMode)} + onDelete={isManual ? () => onDeleteImage(image) : null}> <ListEditorItemViewField> <div className='image-filename-cell'><span className='image-filename'>{fileName}</span></div> @@ -125,8 +125,8 @@ class SoftwareProductComponentsImageListView extends React.Component { } save() { - let {onSubmit, qdata, version} = this.props; - return onSubmit(version, qdata); + let {onSubmit, qdata} = this.props; + return onSubmit(qdata); } } export default SoftwareProductComponentsImageListView; diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/imagesEditorComponents/FileDetails.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/imagesEditorComponents/FileDetails.jsx index 2e9ab417d8..64367c00f2 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/imagesEditorComponents/FileDetails.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/imagesEditorComponents/FileDetails.jsx @@ -26,8 +26,8 @@ import Version from './Version.jsx'; const FileDetails = ({editingMode, fileName, onDataChanged, isManual, dataMap, onQDataChanged, genericFieldInfo, qgenericFieldInfo}) => { let fileNameCols = (editingMode) ? 3 : 4; return( - <GridSection> - <GridItem colSpan={fileNameCols}> + <GridSection hasLastColSset> + <GridItem colSpan={fileNameCols} lastColInRow={!editingMode}> <Input disabled={!isManual} onChange={fileName => onDataChanged({fileName}, forms.IMAGE_EDIT_FORM)} diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/imagesEditorComponents/Version.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/imagesEditorComponents/Version.jsx index 7dd577b8c9..bd55c5ba91 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/imagesEditorComponents/Version.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/images/imagesEditorComponents/Version.jsx @@ -22,7 +22,7 @@ import {imageCustomValidations} from '../ImageValidations.js'; const Version = ({isManual, dataMap, qgenericFieldInfo, onQDataChanged}) => { return( - <GridItem colSpan={1}> + <GridItem colSpan={1} lastColInRow> <Input disabled={!isManual} data-test-id='image-version' 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 0634858219..350e80c0f8 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 @@ -17,29 +17,25 @@ 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, qgenericFieldInfo : genericFieldInfo, dataMap}} = softwareProductComponents; - let isReadOnlyMode = VersionControllerUtils.isReadOnly(currentVSP); +export const mapStateToProps = ({softwareProduct: {softwareProductComponents}}) => { + + let {componentEditor: {qdata, qgenericFieldInfo: genericFieldInfo, dataMap}} = softwareProductComponents; return { qdata, genericFieldInfo, - dataMap, - isReadOnlyMode + dataMap }; -}; +}; const mapActionsToProps = (dispatch, {softwareProductId, version, componentId}) => { return { onQDataChanged: (deltaData) => ValidationHelper.qDataChanged(dispatch, {deltaData, qName: COMPONENTS_QUESTIONNAIRE}), onSubmit: ({qdata}) =>{ return SoftwareProductComponentsActionHelper.updateSoftwareProductComponentQuestionnaire(dispatch, {softwareProductId, version, vspComponentId: componentId, qdata});} }; - }; export default connect(mapStateToProps, mapActionsToProps, null, {withRef: true})(SoftwareProductComponentLoadBalancingView); diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/loadBalancing/SoftwareProductComponentLoadBalancingRefView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/loadBalancing/SoftwareProductComponentLoadBalancingRefView.jsx index 8a82f54901..1cbb9afc5d 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/loadBalancing/SoftwareProductComponentLoadBalancingRefView.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/loadBalancing/SoftwareProductComponentLoadBalancingRefView.jsx @@ -14,6 +14,7 @@ * permissions and limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import SVGIcon from 'sdc-ui/lib/react/SVGIcon.js'; import i18n from 'nfvo-utils/i18n/i18n.js'; @@ -79,11 +80,11 @@ const TextAreaItem = ({item, toggle, expanded, genericFieldInfo, dataMap, onQDat class SoftwareProductComponentLoadBalancingView extends React.Component { static propTypes = { - componentId: React.PropTypes.string.isRequired, - softwareProductId: React.PropTypes.string.isRequired, - qdata: React.PropTypes.object, - qschema: React.PropTypes.object, - currentSoftwareProduct: React.PropTypes.object + componentId: PropTypes.string.isRequired, + softwareProductId: PropTypes.string.isRequired, + qdata: PropTypes.object, + qschema: PropTypes.object, + currentSoftwareProduct: PropTypes.object }; state = { diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoring.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoring.js index 730beba545..8871aabbb5 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoring.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoring.js @@ -14,7 +14,6 @@ * permissions and limitations under the License. */ import {connect} from 'react-redux'; -import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js'; import SoftwareProductComponentsMonitoringView from './SoftwareProductComponentsMonitoringView.jsx'; import SoftwareProductComponentsMonitoringAction from './SoftwareProductComponentsMonitoringActionHelper.js'; import {actionTypes as modalActionTypes} from 'nfvo-components/modal/GlobalModalConstants.js'; @@ -24,17 +23,15 @@ import i18n from 'nfvo-utils/i18n/i18n.js'; export const mapStateToProps = ({softwareProduct}) => { - let {softwareProductEditor: {data:currentVSP = {}}, softwareProductComponents: {monitoring}} = softwareProduct; - let filenames = monitoring; - let isReadOnlyMode = VersionControllerUtils.isReadOnly(currentVSP); - + let {softwareProductComponents: {monitoring}} = softwareProduct; return { - isReadOnlyMode, - filenames + filenames: monitoring }; + }; const mapActionsToProps = (dispatch, {softwareProductId, version, componentId}) => { + return { onDropMibFileToUpload: (formData, type) => SoftwareProductComponentsMonitoringAction.uploadFile(dispatch, { @@ -58,9 +55,9 @@ const mapActionsToProps = (dispatch, {softwareProductId, version, componentId}) title: i18n('Upload Failed'), msg: i18n('Expected "zip" file. Please check the provided file type.') } - }), - + }) }; + }; export default connect(mapStateToProps, mapActionsToProps, null, {withRef: true})(SoftwareProductComponentsMonitoringView); diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringView.jsx index 2d5a965c40..41acee43ca 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringView.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringView.jsx @@ -13,7 +13,8 @@ * or implied. See the License for the specific language governing * permissions and limitations under the License. */ -import React, {Component, PropTypes} from 'react'; +import React, {Component} from 'react'; +import PropTypes from 'prop-types'; import Dropzone from 'react-dropzone'; import Button from 'sdc-ui/lib/react/Button.js'; import DraggableUploadFileBox from 'nfvo-components/fileupload/DraggableUploadFileBox.jsx'; diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/NICCreation/NICCreation.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/NICCreation/NICCreation.js index 865367a734..d4aaf7cc7e 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/NICCreation/NICCreation.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/NICCreation/NICCreation.js @@ -36,13 +36,13 @@ export const mapStateToProps = ({softwareProduct}) => { }; }; -const mapActionsToProps = (dispatch) => { +const mapActionsToProps = (dispatch, {softwareProductId, version}) => { return { onDataChanged: deltaData => ValidationHelper.dataChanged(dispatch, {deltaData, formName: NIC_CREATION_FORM_NAME}), onCancel: () => NICCreationActionHelper.close(dispatch), - onSubmit: ({nic, softwareProductId, componentId, version}) => { - NICCreationActionHelper.close(dispatch); + onSubmit: ({nic, componentId}) => { SoftwareProductComponentsNetworkActionHelper.createNIC(dispatch, {nic, softwareProductId, componentId, version}); + NICCreationActionHelper.close(dispatch); }, onValidateForm: () => ValidationHelper.validateForm(dispatch, NIC_CREATION_FORM_NAME) }; diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/NICCreation/NICCreationActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/NICCreation/NICCreationActionHelper.js index ad28c86b81..a40b32d51a 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/NICCreation/NICCreationActionHelper.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/NICCreation/NICCreationActionHelper.js @@ -20,7 +20,7 @@ import {modalContentMapper} from 'sdc-app/common/modal/ModalContentMapper.js'; export default { - open(dispatch, {softwareProductId, componentId, modalClassName}) { + open(dispatch, {softwareProductId, componentId, modalClassName, version}) { dispatch({ type: actionTypes.NICCreation.OPEN }); @@ -31,7 +31,7 @@ export default { modalComponentName: modalContentMapper.NIC_CREATION, title: i18n('Create NEW NIC'), modalClassName, - modalComponentProps: {softwareProductId, componentId} + modalComponentProps: {softwareProductId, componentId, version} } }); }, diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/NICCreation/NICCreationView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/NICCreation/NICCreationView.jsx index 3cb731a421..258876844a 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/NICCreation/NICCreationView.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/NICCreation/NICCreationView.jsx @@ -14,26 +14,27 @@ * permissions and limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import i18n from 'nfvo-utils/i18n/i18n.js'; import Input from 'nfvo-components/input/validation/Input.jsx'; import Form from 'nfvo-components/input/validation/Form.jsx'; import GridSection from 'nfvo-components/grid/GridSection.jsx'; import GridItem from 'nfvo-components/grid/GridItem.jsx'; -const NICPropType = React.PropTypes.shape({ - id: React.PropTypes.string, - name: React.PropTypes.string, - description: React.PropTypes.string, - networkId: React.PropTypes.string +const NICPropType = PropTypes.shape({ + id: PropTypes.string, + name: PropTypes.string, + description: PropTypes.string, + networkId: PropTypes.string }); class NICCreationView extends React.Component { static propTypes = { data: NICPropType, - onDataChanged: React.PropTypes.func.isRequired, - onSubmit: React.PropTypes.func.isRequired, - onCancel: React.PropTypes.func.isRequired + onDataChanged: PropTypes.func.isRequired, + onSubmit: PropTypes.func.isRequired, + onCancel: PropTypes.func.isRequired }; render() { @@ -51,8 +52,8 @@ class NICCreationView extends React.Component { isValid={isFormValid} onValidateForm={() => onValidateForm()} formReady={formReady} > - <GridSection> - <GridItem colSpan={4}> + <GridSection hasLastColSet> + <GridItem colSpan={4} lastColInRow> <Input value={name} label={i18n('Name')} @@ -74,7 +75,7 @@ class NICCreationView extends React.Component { className='field-section'/> </GridItem> </GridSection> - <GridSection title={i18n('Network')}> + <GridSection title={i18n('Network')} hasLastColSet> <GridItem colSpan={2}> <div className='form-group'> <label className='control-label'>{i18n('Network Type')}</label> @@ -96,7 +97,7 @@ class NICCreationView extends React.Component { </div> </div> </GridItem> - <GridItem colSpan={2}> + <GridItem colSpan={2} lastColInRow> <Input value={networkDescription} label={i18n('Network Description')} @@ -115,8 +116,8 @@ class NICCreationView extends React.Component { submit() { - const {data: nic, softwareProductId, componentId, currentSoftwareProduct} = this.props; - this.props.onSubmit({nic, softwareProductId, componentId, version: currentSoftwareProduct.version}); + const {data: nic, componentId} = this.props; + this.props.onSubmit({nic, componentId}); } } 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 b47c7e0f99..93bd0bd67e 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 @@ -16,19 +16,17 @@ 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'; import {onboardingMethod as onboardingMethodTypes} from '../../SoftwareProductConstants.js'; -export const mapStateToProps = ({softwareProduct}) => { +export const mapStateToProps = ({softwareProduct, currentScreen}) => { let {softwareProductEditor: {data:currentSoftwareProduct = {}, isValidityData = true}, softwareProductComponents} = softwareProduct; - let {network: {nicEditor = {}}} = softwareProductComponents; let {data, qdata, genericFieldInfo, qgenericFieldInfo, dataMap, formReady} = nicEditor; - let isReadOnlyMode = VersionControllerUtils.isReadOnly(currentSoftwareProduct); + let {props: {isReadOnlyMode}} = currentScreen; let {onboardingMethod} = currentSoftwareProduct; let protocols = []; if(qdata && qdata.protocols && qdata.protocols.protocols && qdata.protocols.protocols.length){ @@ -55,11 +53,11 @@ export const mapStateToProps = ({softwareProduct}) => { }; -const mapActionsToProps = (dispatch, {softwareProductId, componentId}) => { +const mapActionsToProps = (dispatch, {softwareProductId, componentId, version}) => { return { onDataChanged: (deltaData) => ValidationHelper.dataChanged(dispatch, {deltaData, formName: forms.NIC_EDIT_FORM}), - onSubmit: ({data, qdata, version}) => SoftwareProductComponentsNetworkActionHelper.saveNICDataAndQuestionnaire(dispatch, {softwareProductId, version, componentId, data, qdata}), + onSubmit: ({data, qdata}) => SoftwareProductComponentsNetworkActionHelper.saveNICDataAndQuestionnaire(dispatch, {softwareProductId, version, componentId, data, qdata}), onCancel: () => SoftwareProductComponentsNetworkActionHelper.closeNICEditor(dispatch), onValidateForm: () => ValidationHelper.validateForm(dispatch, forms.NIC_EDIT_FORM), onQDataChanged: (deltaData) => ValidationHelper.qDataChanged(dispatch, {deltaData, diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNICEditorView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNICEditorView.jsx index 8a4c55a411..fbb3d53033 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNICEditorView.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNICEditorView.jsx @@ -65,8 +65,8 @@ class SoftwareProductComponentsNetworkEditorView extends React.Component { } submit() { - let {data, qdata, onSubmit, version} = this.props; - onSubmit({data, qdata, version}); + let {data, qdata, onSubmit} = this.props; + onSubmit({data, qdata}); } } diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkActionHelper.js index a3cfe65128..1ffbc5919f 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkActionHelper.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkActionHelper.js @@ -78,7 +78,7 @@ const SoftwareProductComponentNetworkActionHelper = { }); }, - openNICEditor(dispatch, {nic = {}, data = {}, softwareProductId, componentId, isReadOnlyMode, modalClassName}) { + openNICEditor(dispatch, {nic = {}, data = {}, softwareProductId, componentId, isReadOnlyMode, modalClassName, version}) { dispatch({ type: actionTypes.NICEditor.FILL_DATA, nic: {...data, id: nic.id} @@ -87,7 +87,7 @@ const SoftwareProductComponentNetworkActionHelper = { type: GlobalModalActions.GLOBAL_MODAL_SHOW, data: { modalClassName, - modalComponentProps: {softwareProductId, componentId, isReadOnlyMode}, + modalComponentProps: {softwareProductId, componentId, isReadOnlyMode, version}, modalComponentName: modalPagesMapper.NIC_EDITOR, title: i18n('Edit NIC') } diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkList.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkList.js index 0fa877e90f..bb256d5d41 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkList.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/SoftwareProductComponentsNetworkList.js @@ -15,7 +15,6 @@ */ import {connect} from 'react-redux'; import i18n from 'nfvo-utils/i18n/i18n.js'; -import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js'; import SoftwareProductComponentsActionHelper from 'sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsActionHelper.js'; import SoftwareProductComponentsNetworkListView from './SoftwareProductComponentsNetworkListView.jsx'; @@ -31,8 +30,8 @@ export const mapStateToProps = ({softwareProduct}) => { let {softwareProductEditor: {data: currentSoftwareProduct = {}, isValidityData = true}, softwareProductComponents} = softwareProduct; let {network: {nicList = []}, componentEditor: {data: componentData, qdata, dataMap, qgenericFieldInfo}} = softwareProductComponents; - let isReadOnlyMode = VersionControllerUtils.isReadOnly(currentSoftwareProduct); let {version, onboardingMethod} = currentSoftwareProduct; + let isManual = onboardingMethod === onboardingMethodTypes.MANUAL; return { version, @@ -42,26 +41,25 @@ export const mapStateToProps = ({softwareProduct}) => { qgenericFieldInfo, isValidityData, nicList, - isReadOnlyMode, - isManual: onboardingMethod === onboardingMethodTypes.MANUAL + isManual }; }; -const mapActionsToProps = (dispatch, {softwareProductId, componentId}) => { +const mapActionsToProps = (dispatch, {softwareProductId, componentId, version}) => { return { onQDataChanged: (deltaData) => ValidationHelper.qDataChanged(dispatch, {deltaData, qName: COMPONENTS_QUESTIONNAIRE}), - onAddNic: () => NICCreationActionHelper.open(dispatch, {softwareProductId, componentId, modalClassName: 'network-nic-modal-create'}), - onDeleteNic: (nic, version) => dispatch({ + onAddNic: () => NICCreationActionHelper.open(dispatch, {softwareProductId, componentId, modalClassName: 'network-nic-modal-create', version}), + onDeleteNic: (nic) => dispatch({ type: GlobalModalActions.GLOBAL_MODAL_WARNING, data:{ - msg: i18n(`Are you sure you want to delete "${nic.name}"?`), + msg: i18n('Are you sure you want to delete "{name}"?', {name: nic.name}), onConfirmed: () => SoftwareProductComponentsNetworkActionHelper.deleteNIC(dispatch, {softwareProductId, componentId, nicId: nic.id, version}) } }), - onEditNicClick: (nic, version, isReadOnlyMode) => { + onEditNicClick: (nic, isReadOnlyMode) => { Promise.all([ SoftwareProductComponentsNetworkActionHelper.loadNICData({ softwareProductId, @@ -77,10 +75,10 @@ const mapActionsToProps = (dispatch, {softwareProductId, componentId}) => { }) ]).then( ([{data}]) => SoftwareProductComponentsNetworkActionHelper.openNICEditor(dispatch, {nic, data, - isReadOnlyMode, softwareProductId, componentId, modalClassName: 'network-nic-modal-edit'}) + isReadOnlyMode, softwareProductId, componentId, modalClassName: 'network-nic-modal-edit', version}) ); }, - onSubmit: ({qdata, version}) => { return SoftwareProductComponentsActionHelper.updateSoftwareProductComponentQuestionnaire(dispatch, + onSubmit: ({qdata}) => { return SoftwareProductComponentsActionHelper.updateSoftwareProductComponentQuestionnaire(dispatch, {softwareProductId, version, vspComponentId: componentId, qdata}); diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/Acceptable.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/Acceptable.jsx index 524b95c3ad..0fc7404c56 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/Acceptable.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/Acceptable.jsx @@ -21,53 +21,53 @@ import GridItem from 'nfvo-components/grid/GridItem.jsx'; const Acceptable = ({qgenericFieldInfo, dataMap, onQDataChanged}) => { return( - <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 hasLastColSet> + <GridItem colSpan={3}> + <div className='part-title-small packets'>{i18n('Acceptable Jitter')}</div> + </GridItem> + <GridItem lastColInRow> + <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 lastColInRow> + <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> ); }; diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/NameAndPurpose.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/NameAndPurpose.jsx index bc692e753c..06a2bb445c 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/NameAndPurpose.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/NameAndPurpose.jsx @@ -14,6 +14,7 @@ * permissions and limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import i18n from 'nfvo-utils/i18n/i18n.js'; import Input from 'nfvo-components/input/validation/Input.jsx'; import GridSection from 'nfvo-components/grid/GridSection.jsx'; @@ -22,7 +23,7 @@ import GridItem from 'nfvo-components/grid/GridItem.jsx'; const NameAndPurpose = ({onDataChanged, genericFieldInfo, isReadOnlyMode, name, description, isManual}) => { return ( - <GridSection> + <GridSection hastLastColSet> <GridItem colSpan={2}> <Input label={i18n('Name')} @@ -35,24 +36,24 @@ const NameAndPurpose = ({onDataChanged, genericFieldInfo, isReadOnlyMode, name, errorText={genericFieldInfo['name'].errorText} type='text' /> </GridItem> - <GridItem colSpan={2}> + <GridItem colSpan={2} lastColInRow> <Input label={i18n('Purpose of NIC')} value={description} data-test-id='nic-description' onChange={description => onDataChanged({description})} disabled={isReadOnlyMode} - type='textarea'/> + type='textarea' /> </GridItem> </GridSection> ); }; NameAndPurpose.PropTypes = { - name: React.PropTypes.string, - description: React.PropTypes.array, - onDataChanged: React.PropTypes.func, - isReadOnlyMode: React.PropTypes.bool, + name: PropTypes.string, + description: PropTypes.array, + onDataChanged: PropTypes.func, + isReadOnlyMode: PropTypes.bool, }; export default NameAndPurpose; diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/Network.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/Network.jsx index 8d9b79e67f..7e6712cb5e 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/Network.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/Network.jsx @@ -14,6 +14,7 @@ * permissions and limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import i18n from 'nfvo-utils/i18n/i18n.js'; import Input from 'nfvo-components/input/validation/Input.jsx'; import GridSection from 'nfvo-components/grid/GridSection.jsx'; @@ -23,51 +24,53 @@ import { networkTypes } from '../SoftwareProductComponentsNetworkConstants.js'; const Network = ({networkValues, networkType, networkDescription, onDataChanged, isReadOnlyMode}) => { const isExternal = networkType === networkTypes.EXTERNAL; return ( - <GridSection title={i18n('Network')}> - <GridItem> - <Input - label={i18n('Internal')} - disabled - checked={!isExternal} - data-test-id='nic-internal' - className='network-radio disabled' - type='radio'/> - </GridItem> - <GridItem> - <Input - label={i18n('External')} - disabled - checked={isExternal} - data-test-id='nic-external' - className='network-radio disabled' - type='radio'/> - </GridItem> - <GridItem colSpan={2}> - {isExternal ? + <GridSection title={i18n('Network')} hasLastColSet> + <GridItem> + <Input + label={i18n('Internal')} + disabled + checked={!isExternal} + data-test-id='nic-internal' + className='network-radio disabled' + type='radio' /> + </GridItem> + <GridItem> + <Input + label={i18n('External')} + disabled + checked={isExternal} + data-test-id='nic-external' + className='network-radio disabled' + type='radio' /> + </GridItem> + <GridItem colSpan={2} lastColInRow> + { + isExternal ? <Input label={i18n('Network Description')} value={networkDescription} data-test-id='nic-network-description' onChange={networkDescription => onDataChanged({networkDescription})} disabled={isReadOnlyMode} - type='text'/> - : + type='text' /> + : <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> + disabled={true}> + {networkValues.map(val => <option key={val.enum} value={val.enum}>{val.title}</option>)} + </Input> + } + </GridItem> </GridSection> ); }; Network.PropTypes = { - networkValues: React.PropTypes.array + networkValues: PropTypes.array }; export default Network; diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/PacketsBytes.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/PacketsBytes.jsx index d7ee91bd15..f5f28aea59 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/PacketsBytes.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/PacketsBytes.jsx @@ -14,14 +14,15 @@ * permissions and limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import i18n from 'nfvo-utils/i18n/i18n.js'; import Input from 'nfvo-components/input/validation/Input.jsx'; import GridSection from 'nfvo-components/grid/GridSection.jsx'; import GridItem from 'nfvo-components/grid/GridItem.jsx'; -const PointerInput = ({label, value, onQDataChanged, qgenericFieldInfo, dataMap}) => { +const PointerInput = ({label, value, onQDataChanged, qgenericFieldInfo, dataMap, lastColInRow}) => { return ( - <GridItem> + <GridItem lastColInRow={lastColInRow}> <Input label={i18n(label)} type='number' @@ -35,31 +36,31 @@ const PointerInput = ({label, value, onQDataChanged, qgenericFieldInfo, dataMap} }; PointerInput.PropTypes = { - label: React.PropTypes.string, - value: React.PropTypes.string + label: PropTypes.string, + value: PropTypes.string }; const PacketsBytes = ({title, pointers = [], qgenericFieldInfo, dataMap, onQDataChanged}) => { return( - <GridSection title={title}> + <GridSection title={title} hasLastColSet> <GridItem colSpan={2}> <div className='part-title-small packets'>{i18n('Packets')}</div> </GridItem> - <GridItem colSpan={2}> + <GridItem colSpan={2} lastColInRow> <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} />);})} + {pointers.map((pointer, i) => {return (<PointerInput key={i} label={pointer.label} value={pointer.value} + qgenericFieldInfo={qgenericFieldInfo} onQDataChanged={onQDataChanged} dataMap={dataMap} lastColInRow={i === 3} />);})} </GridSection> ); }; PacketsBytes.PropTypes = { - title: React.PropTypes.string, - pointers: React.PropTypes.array, - onQDataChanged: React.PropTypes.function, - dataMap: React.PropTypes.object, - qgenericFieldInfo: React.PropTypes.object + title: PropTypes.string, + pointers: PropTypes.array, + onQDataChanged: PropTypes.function, + dataMap: PropTypes.object, + qgenericFieldInfo: PropTypes.object }; export default PacketsBytes; diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/Protocols.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/Protocols.jsx index 3e8a9f4e77..be4093da59 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/Protocols.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/Protocols.jsx @@ -14,6 +14,7 @@ * permissions and limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import i18n from 'nfvo-utils/i18n/i18n.js'; import Input from 'nfvo-components/input/validation/Input.jsx'; import InputOptions from 'nfvo-components/input/validation/InputOptions.jsx'; @@ -22,7 +23,7 @@ import GridItem from 'nfvo-components/grid/GridItem.jsx'; const Protocols = ({protocols, qgenericFieldInfo, dataMap, onQDataChanged}) => { return ( - <GridSection title={i18n('Protocols')}> + <GridSection title={i18n('Protocols')} hasLastColSet> <GridItem colSpan={2}> <InputOptions data-test-id='nic-protocols' @@ -39,7 +40,7 @@ const Protocols = ({protocols, qgenericFieldInfo, dataMap, onQDataChanged}) => { clearable={false} values={qgenericFieldInfo['protocols/protocols'].enum}/> </GridItem> - <GridItem colSpan={2}> + <GridItem colSpan={2} lastColInRow> <Input data-test-id='nic-protocolWithHighestTrafficProfile' label={i18n('Protocol with Highest Traffic Profile')} @@ -65,10 +66,10 @@ const Protocols = ({protocols, qgenericFieldInfo, dataMap, onQDataChanged}) => { }; Protocols.PropTypes = { - protocols: React.PropTypes.array, - onQDataChanged: React.PropTypes.function, - dataMap: React.PropTypes.object, - qgenericFieldInfo: React.PropTypes.object + protocols: PropTypes.array, + onQDataChanged: PropTypes.function, + dataMap: PropTypes.object, + qgenericFieldInfo: PropTypes.object }; export default Protocols; diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/Sizing.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/Sizing.jsx index 1dd0045f7b..202d458f25 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/Sizing.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/network/nicEditorComponents/Sizing.jsx @@ -21,8 +21,8 @@ import GridItem from 'nfvo-components/grid/GridItem.jsx'; const Sizing = ({qgenericFieldInfo, dataMap, onQDataChanged}) => { return( - <GridSection title={i18n('Sizing')}> - <GridItem colSpan={4}> + <GridSection title={i18n('Sizing')} hasLastColSet> + <GridItem colSpan={4} lastColInRow> <Input label={i18n('Describe Quality of Service')} type='textarea' 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 87abaf4978..9841ecbae7 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 @@ -14,168 +14,17 @@ * permissions and limitations under the License. */ import React from 'react'; -import i18n from 'nfvo-utils/i18n/i18n.js'; -import Dropzone from 'react-dropzone'; - -import DraggableUploadFileBox from 'nfvo-components/fileupload/DraggableUploadFileBox.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, - type: React.PropTypes.string -}); +import SoftwareProductProcessesEditorForm from 'sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesEditorForm.jsx'; class SoftwareProductProcessesEditorView extends React.Component { - state = { - dragging: false, - files: [] - }; - - static propTypes = { - data: SoftwareProductProcessEditorPropType, - previousData: SoftwareProductProcessEditorPropType, - isReadOnlyMode: React.PropTypes.bool, - onDataChanged: React.PropTypes.func, - onSubmit: React.PropTypes.func, - onCancel: React.PropTypes.func - }; - render() { - let {isReadOnlyMode, onCancel, onDataChanged, genericFieldInfo, data = {}} = this.props; - let {name, description, artifactName, type} = data; - return ( - <div> - { 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={(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}> - <DraggableUploadFileBox isReadOnlyMode={isReadOnlyMode} className='file-upload-box' 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> + <SoftwareProductProcessesEditorForm optionsInputValues={ComponentProcessesOptionsInputValues} {...this.props}/> ); } - - submit() { - const {data: process, previousData: previousProcess} = this.props; - let {files} = this.state; - let formData = new FormData(); - if (files.length) { - let file = files[0]; - formData.append('upload', file); - } - - let updatedProcess = { - ...process, - formData: files.length ? formData : false - }; - this.props.onSubmit({process: updatedProcess, previousProcess}); - } - - - handleImportSubmit(files, rejectedFiles) { - if (files.length > 0) { - let {onDataChanged} = this.props; - this.setState({ - dragging: false, - complete: '0', - files - }); - onDataChanged({artifactName: files[0].name}); - } - else if (rejectedFiles.length > 0) { - this.setState({ - dragging: false - }); - if (DEBUG) { - console.log('file was rejected ' + rejectedFiles[0].name); - } - } - - } } export default SoftwareProductProcessesEditorView; diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesList.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesList.js index 8c359db869..2a7152ef8b 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesList.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentProcessesList.js @@ -16,7 +16,6 @@ import {connect} from 'react-redux'; import i18n from 'nfvo-utils/i18n/i18n.js'; import {actionTypes as modalActionTypes} from 'nfvo-components/modal/GlobalModalConstants.js'; -import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js'; import SoftwareProductComponentProcessesActionHelper from './SoftwareProductComponentProcessesActionHelper.js'; import SoftwareProductComponentsProcessesListView from './SoftwareProductComponentsProcessesListView.jsx'; @@ -26,28 +25,26 @@ export const mapStateToProps = ({softwareProduct}) => { let {softwareProductEditor: {data:currentSoftwareProduct = {}, isValidityData = true}, softwareProductComponents: {componentProcesses = {}}} = softwareProduct; let{processesList = [], processesEditor = {}} = componentProcesses; let {data} = processesEditor; - let isReadOnlyMode = VersionControllerUtils.isReadOnly(currentSoftwareProduct); return { currentSoftwareProduct, isValidityData, processesList, isDisplayModal: Boolean(data), - isModalInEditMode: Boolean(data && data.id), - isReadOnlyMode + isModalInEditMode: Boolean(data && data.id) }; }; -const mapActionsToProps = (dispatch, {componentId, softwareProductId}) => { +const mapActionsToProps = (dispatch, {componentId, softwareProductId, version}) => { return { onAddProcess: () => SoftwareProductComponentProcessesActionHelper.openEditor(dispatch), - onEditProcessClick: (process) => SoftwareProductComponentProcessesActionHelper.openEditor(dispatch, process), - onDeleteProcessClick: (process, version) => dispatch({ + onEditProcess: (process) => SoftwareProductComponentProcessesActionHelper.openEditor(dispatch, process), + onDeleteProcess: (process) => dispatch({ type: modalActionTypes.GLOBAL_MODAL_WARNING, data:{ - msg: i18n(`Are you sure you want to delete "${process.name}"?`), + msg: i18n('Are you sure you want to delete "{name}"?', {name: process.name}), confirmationButtonText: i18n('Delete'), title: i18n('Delete'), onConfirmed: ()=> SoftwareProductComponentProcessesActionHelper.deleteProcess(dispatch, diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentsProcessesListView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentsProcessesListView.jsx index 93d5ce886a..27c4b9f429 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentsProcessesListView.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/processes/SoftwareProductComponentsProcessesListView.jsx @@ -14,13 +14,11 @@ * permissions and limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import i18n from 'nfvo-utils/i18n/i18n.js'; import Modal from 'nfvo-components/modal/Modal.jsx'; - -import ListEditorView from 'nfvo-components/listEditor/ListEditorView.jsx'; -import ListEditorItemView from 'nfvo-components/listEditor/ListEditorItemView.jsx'; - import SoftwareProductProcessesEditor from './SoftwareProductComponentProcessesEditor.js'; +import SoftwareProductProcessListView from 'sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessListView.jsx'; class SoftwareProductProcessesView extends React.Component { @@ -29,15 +27,15 @@ class SoftwareProductProcessesView extends React.Component { }; static propTypes = { - onAddProcess: React.PropTypes.func, - onEditProcessClick: React.PropTypes.func, - onDeleteProcessClick: React.PropTypes.func, - isDisplayModal: React.PropTypes.bool, - isModalInEditMode: React.PropTypes.bool, - onStorageSelect: React.PropTypes.func, - componentId: React.PropTypes.string, - softwareProductId: React.PropTypes.string, - currentSoftwareProduct: React.PropTypes.object + onAddProcess: PropTypes.func, + onEditProcess: PropTypes.func, + onDeleteProcess: PropTypes.func, + isDisplayModal: PropTypes.bool, + isModalInEditMode: PropTypes.bool, + onStorageSelect: PropTypes.func, + componentId: PropTypes.string, + softwareProductId: PropTypes.string, + currentSoftwareProduct: PropTypes.object }; render() { @@ -46,7 +44,7 @@ class SoftwareProductProcessesView extends React.Component { <div className='software-product-view'> <div className='software-product-landing-view-right-side vsp-components-processes-page flex-column'> {this.renderEditor()} - {this.renderProcessList()} + <SoftwareProductProcessListView addButtonTitle={i18n('Add Component Process Details')} {...this.props}/> </div> </div> </div> @@ -54,7 +52,7 @@ class SoftwareProductProcessesView extends React.Component { } renderEditor() { - let {softwareProductId, currentSoftwareProduct: {version}, componentId, isReadOnlyMode, isDisplayModal, isModalInEditMode} = this.props; + let {softwareProductId, version, componentId, isReadOnlyMode, isDisplayModal, isModalInEditMode} = this.props; return ( <Modal show={isDisplayModal} bsSize='large' animation={true} className='onborading-modal'> <Modal.Header> @@ -72,66 +70,6 @@ class SoftwareProductProcessesView extends React.Component { ); } - renderProcessList() { - const {localFilter} = this.state; - let {onAddProcess, isReadOnlyMode} = this.props; - return ( - <div className='processes-list'> - <ListEditorView - plusButtonTitle={i18n('Add Component Process Details')} - filterValue={localFilter} - placeholder={i18n('Filter Process')} - onAdd={onAddProcess} - isReadOnlyMode={isReadOnlyMode} - title={i18n('Process Details')} - onFilter={value => this.setState({localFilter: value})}> - {this.filterList().map(processes => this.renderProcessListItem(processes, isReadOnlyMode))} - </ListEditorView> - </div> - ); - } - - renderProcessListItem(process, isReadOnlyMode) { - let {id, name, description, artifactName = ''} = process; - let {currentSoftwareProduct: {version}, onEditProcessClick, onDeleteProcessClick} = this.props; - return ( - <ListEditorItemView - key={id} - className='list-editor-item-view' - isReadOnlyMode={isReadOnlyMode} - onSelect={() => onEditProcessClick(process)} - onDelete={() => onDeleteProcessClick(process, version)}> - - <div className='list-editor-item-view-field'> - <div className='title'>{i18n('Name')}</div> - <div className='name'>{name}</div> - </div> - <div className='list-editor-item-view-field'> - <div className='title'>{i18n('Artifact name')}</div> - <div className='artifact-name'>{artifactName}</div> - </div> - <div className='list-editor-item-view-field'> - <div className='title'>{i18n('Notes')}</div> - <div className='description'>{description}</div> - </div> - </ListEditorItemView> - ); - } - - - filterList() { - let {processesList} = this.props; - let {localFilter} = this.state; - if (localFilter.trim()) { - const filter = new RegExp(escape(localFilter), 'i'); - return processesList.filter(({name = '', description = ''}) => { - return escape(name).match(filter) || escape(description).match(filter); - }); - } - else { - return processesList; - } - } } export default SoftwareProductProcessesView; diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/storage/SoftwareProductComponentStorage.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/storage/SoftwareProductComponentStorage.js index 7149adbbfb..ca27a76a18 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/storage/SoftwareProductComponentStorage.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/storage/SoftwareProductComponentStorage.js @@ -15,7 +15,6 @@ */ import {connect} from 'react-redux'; -import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js'; import ValidationHelper from 'sdc-app/common/helpers/ValidationHelper.js'; import SoftwareProductComponentsActionHelper from 'sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsActionHelper.js'; @@ -23,26 +22,21 @@ import SoftwareProductComponentStorageView from './SoftwareProductComponentStora import {COMPONENTS_QUESTIONNAIRE} from '../SoftwareProductComponentsConstants.js'; -const mapStateToProps = ({softwareProduct}) => { - let {softwareProductEditor: {data: currentVSP}, softwareProductComponents} = softwareProduct; - let {componentEditor: {data: componentData , qdata, qgenericFieldInfo : qGenericFieldInfo, dataMap}} = softwareProductComponents; - let isReadOnlyMode = VersionControllerUtils.isReadOnly(currentVSP); +const mapStateToProps = ({softwareProduct: {softwareProductComponents}}) => { + let {componentEditor: {qdata, qgenericFieldInfo : qGenericFieldInfo, dataMap}} = softwareProductComponents; return { - componentData, qdata, - isReadOnlyMode, qGenericFieldInfo, - dataMap, - version: currentVSP.version + dataMap }; }; -const mapActionToProps = (dispatch, {softwareProductId, componentId}) => { +const mapActionToProps = (dispatch, {softwareProductId, version, componentId}) => { return { onQDataChanged: (deltaData) => ValidationHelper.qDataChanged(dispatch, {deltaData, qName: COMPONENTS_QUESTIONNAIRE}), - onSubmit: ({componentData, qdata, version}) => { return SoftwareProductComponentsActionHelper.updateSoftwareProductComponent(dispatch, - {softwareProductId, version, vspComponentId: componentId, componentData, qdata}); + onSubmit: ({qdata}) => { + return SoftwareProductComponentsActionHelper.updateSoftwareProductComponentQuestionnaire(dispatch, {softwareProductId, version, vspComponentId: componentId, qdata}); } }; }; diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/storage/SoftwareProductComponentStorageView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/storage/SoftwareProductComponentStorageView.jsx index 00df21bb59..8538dab6bc 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/storage/SoftwareProductComponentStorageView.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/components/storage/SoftwareProductComponentStorageView.jsx @@ -14,6 +14,7 @@ * permissions and limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import i18n from 'nfvo-utils/i18n/i18n.js'; import Input from 'nfvo-components/input/validation/Input.jsx'; import Form from 'nfvo-components/input/validation/Form.jsx'; @@ -155,14 +156,14 @@ const LogBackupSection = ({dataMap, onQDataChanged, qgenericFieldInfo}) => ( class SoftwareProductComponentStorageView extends React.Component { static propTypes = { - componentId: React.PropTypes.string, - onQDataChanged: React.PropTypes.func, - onSubmit: React.PropTypes.func, - isReadOnlyMode: React.PropTypes.bool + componentId: PropTypes.string, + onQDataChanged: PropTypes.func, + onSubmit: PropTypes.func, + isReadOnlyMode: PropTypes.bool }; render() { - let {onQDataChanged, dataMap, qGenericFieldInfo, isReadOnlyMode, onSubmit, qdata, version} = this.props; + let {onQDataChanged, dataMap, qGenericFieldInfo, isReadOnlyMode, onSubmit, qdata} = this.props; return( <div className='vsp-component-questionnaire-view'> @@ -170,7 +171,7 @@ class SoftwareProductComponentStorageView extends React.Component { ref={form => this.form = form } isValid={true} formReady={null} - onSubmit={() => onSubmit({qdata, version})} + onSubmit={() => onSubmit({qdata})} className='component-questionnaire-validation-form' isReadOnlyMode={isReadOnlyMode} hasButtons={false}> @@ -183,8 +184,8 @@ class SoftwareProductComponentStorageView extends React.Component { } save(){ - const {componentData, qdata, onSubmit, version} = this.props; - return onSubmit({componentData, qdata, version}); + const {qdata, onSubmit} = this.props; + return onSubmit({qdata}); } } diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreation.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreation.js index 3b973c65cd..0136048bf7 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreation.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreation.js @@ -15,13 +15,17 @@ */ import {connect} from 'react-redux'; -import OnboardingActionHelper from 'sdc-app/onboarding/OnboardingActionHelper.js'; import SoftwareProductCreationActionHelper from './SoftwareProductCreationActionHelper.js'; import SoftwareProductCreationView from './SoftwareProductCreationView.jsx'; import ValidationHelper from 'sdc-app/common/helpers/ValidationHelper.js'; import SoftwareProductActionHelper from '../SoftwareProductActionHelper.js'; +import VersionsPageActionHelper from 'sdc-app/onboarding/versionsPage/VersionsPageActionHelper.js'; +import {itemTypes as versionItemTypes} from 'sdc-app/onboarding/versionsPage/VersionsPageConstants.js'; +import ScreensHelper from 'sdc-app/common/helpers/ScreensHelper.js'; +import {enums, screenTypes} from 'sdc-app/onboarding/OnboardingConstants.js'; +import PermissionsActionHelper from 'sdc-app/onboarding/permissions/PermissionsActionHelper.js'; -export const mapStateToProps = ({finalizedLicenseModelList, softwareProductList, softwareProduct: {softwareProductCreation, softwareProductCategories} }) => { +export const mapStateToProps = ({finalizedLicenseModelList, users: {usersList}, softwareProductList, softwareProduct: {softwareProductCreation, softwareProductCategories} }) => { let {genericFieldInfo} = softwareProductCreation; let isFormValid = ValidationHelper.checkFormValid(genericFieldInfo); @@ -39,7 +43,8 @@ export const mapStateToProps = ({finalizedLicenseModelList, softwareProductList, isFormValid, formReady: softwareProductCreation.formReady, genericFieldInfo, - VSPNames + VSPNames, + usersList }; }; @@ -47,13 +52,18 @@ export const mapActionsToProps = (dispatch) => { return { onDataChanged: (deltaData, formName, customValidations) => ValidationHelper.dataChanged(dispatch, {deltaData, formName, customValidations}), onCancel: () => SoftwareProductCreationActionHelper.resetData(dispatch), - onSubmit: (softwareProduct) => { + onSubmit: (softwareProduct, usersList) => { SoftwareProductCreationActionHelper.resetData(dispatch); SoftwareProductCreationActionHelper.createSoftwareProduct(dispatch, {softwareProduct}).then(response => { - SoftwareProductActionHelper.fetchSoftwareProductList(dispatch).then(() => { - let {vendorId: licenseModelId, licensingVersion} = softwareProduct; - OnboardingActionHelper.navigateToSoftwareProductLandingPage(dispatch, {softwareProductId: response.vspId, licenseModelId, licensingVersion}); - }); + let {itemId, version} = response; + SoftwareProductActionHelper.fetchSoftwareProductList(dispatch).then(() => + PermissionsActionHelper.fetchItemUsers(dispatch, {itemId, allUsers: usersList}).then(() => + VersionsPageActionHelper.fetchVersions(dispatch, {itemType: versionItemTypes.SOFTWARE_PRODUCT, itemId}).then(() => + ScreensHelper.loadScreen(dispatch, {screen: enums.SCREEN.SOFTWARE_PRODUCT_LANDING_PAGE, screenType: screenTypes.SOFTWARE_PRODUCT, + props: {softwareProductId: itemId, version}}) + ) + ) + ); }); }, onValidateForm: (formName) => ValidationHelper.validateForm(dispatch, formName) diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreationActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreationActionHelper.js index a22b517fa0..b19e460497 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreationActionHelper.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreationActionHelper.js @@ -48,10 +48,10 @@ const SoftwareProductCreationActionHelper = { type: modalActionTypes.GLOBAL_MODAL_SHOW, data: { modalComponentName: modalContentMapper.SOFTWARE_PRODUCT_CREATION, - title: i18n('New Software Product'), + title: i18n('New Software Product'), modalComponentProps: { vendorId, - size: modalSizes.LARGE + size: modalSizes.LARGE } } }); @@ -70,7 +70,13 @@ const SoftwareProductCreationActionHelper = { }, createSoftwareProduct(dispatch, {softwareProduct}) { - return createSoftwareProduct(softwareProduct); + return createSoftwareProduct(softwareProduct).then(result => { + dispatch({ + type: actionTypes.SOFTWARE_PRODUCT_CREATED, + result + }); + return result; + }); } }; diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreationConstants.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreationConstants.js index 241d7985b1..b941c849cb 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreationConstants.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreationConstants.js @@ -17,7 +17,8 @@ import keyMirror from 'nfvo-utils/KeyMirror.js'; export const actionTypes = keyMirror({ OPEN: null, - RESET_DATA: null + RESET_DATA: null, + SOFTWARE_PRODUCT_CREATED: null }); export const SP_CREATION_FORM_NAME = 'SPCREATIONFORM'; diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreationView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreationView.jsx index c7ab3e644c..e491491f4d 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreationView.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreationView.jsx @@ -14,6 +14,7 @@ * permissions and limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import i18n from 'nfvo-utils/i18n/i18n.js'; import Validator from 'nfvo-utils/Validator.js'; import Input from 'nfvo-components/input/validation/Input.jsx'; @@ -27,25 +28,26 @@ import sortByStringProperty from 'nfvo-utils/sortByStringProperty.js'; import SoftwareProductCategoriesHelper from 'sdc-app/onboarding/softwareProduct/SoftwareProductCategoriesHelper.js'; import {onboardingMethod as onboardingMethodConst} from '../SoftwareProductConstants.js'; -const SoftwareProductPropType = React.PropTypes.shape({ - id: React.PropTypes.string, - name: React.PropTypes.string, - description: React.PropTypes.string, - category: React.PropTypes.string, - subCategory: React.PropTypes.string, - vendorId: React.PropTypes.string +const SoftwareProductPropType = PropTypes.shape({ + id: PropTypes.string, + name: PropTypes.string, + description: PropTypes.string, + category: PropTypes.string, + subCategory: PropTypes.string, + vendorId: PropTypes.string }); class SoftwareProductCreationView extends React.Component { static propTypes = { data: SoftwareProductPropType, - finalizedLicenseModelList: React.PropTypes.array, - softwareProductCategories: React.PropTypes.array, - VSPNames: React.PropTypes.object, - onDataChanged: React.PropTypes.func.isRequired, - onSubmit: React.PropTypes.func.isRequired, - onCancel: React.PropTypes.func.isRequired + finalizedLicenseModelList: PropTypes.array, + softwareProductCategories: PropTypes.array, + VSPNames: PropTypes.object, + usersList: PropTypes.array, + onDataChanged: PropTypes.func.isRequired, + onSubmit: PropTypes.func.isRequired, + onCancel: PropTypes.func.isRequired }; render() { @@ -65,7 +67,7 @@ class SoftwareProductCreationView extends React.Component { submitButtonText={i18n('Create')} formReady={this.props.formReady} onValidateForm={() => this.validate() }> - <GridSection> + <GridSection hasLastColSet> <GridItem colSpan='2'> <Input value={name} @@ -115,7 +117,7 @@ class SoftwareProductCreationView extends React.Component { } </Input> </GridItem> - <GridItem colSpan='2' stretch> + <GridItem colSpan='2' stretch lastColInRow> <Input value={description} label={i18n('Description')} @@ -139,10 +141,10 @@ class SoftwareProductCreationView extends React.Component { let {finalizedLicenseModelList} = this.props; return [{enum: '', title: i18n('please select...')}].concat( - sortByStringProperty(finalizedLicenseModelList, 'vendorName').map(vendor => { + sortByStringProperty(finalizedLicenseModelList, 'name').map(vendor => { return { enum: vendor.id, - title: vendor.vendorName + title: vendor.name }; }) ); @@ -163,9 +165,9 @@ class SoftwareProductCreationView extends React.Component { } submit() { - let {data:softwareProduct, finalizedLicenseModelList} = this.props; - softwareProduct.vendorName = finalizedLicenseModelList.find(vendor => vendor.id === softwareProduct.vendorId).vendorName; - this.props.onSubmit(softwareProduct); + let {data:softwareProduct, finalizedLicenseModelList, usersList} = this.props; + softwareProduct.vendorName = finalizedLicenseModelList.find(vendor => vendor.id === softwareProduct.vendorId).name; + this.props.onSubmit(softwareProduct, usersList); } validateName(value) { diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependencies.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependencies.js index 05a1fc7797..9888087800 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependencies.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependencies.js @@ -16,24 +16,21 @@ import {connect} from 'react-redux'; import SoftwareProductDependenciesView from './SoftwareProductDependenciesView.jsx'; -import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js'; import SoftwareProductDependenciesActionHelper from './SoftwareProductDependenciesActionHelper.js'; export const mapStateToProps = ({softwareProduct}) => { - let {softwareProductEditor: {data: currentSoftwareProduct = {}}, softwareProductDependencies, softwareProductComponents: {componentsList}} = softwareProduct; - let isReadOnlyMode = VersionControllerUtils.isReadOnly(currentSoftwareProduct); + let {softwareProductDependencies, softwareProductComponents: {componentsList}} = softwareProduct; return { - isReadOnlyMode, - softwareProductDependencies: softwareProductDependencies.length ? softwareProductDependencies : [{sourceId: '', targetId: '', relationType: 'dependsOn', id: 'fake'}], + softwareProductDependencies: softwareProductDependencies, componentsOptions: componentsList.map(component => ({value: component.id, label: component.displayName})) }; }; const mapActionsToProps = (dispatch, {softwareProductId, version}) => { return { - onDataChanged: dependenciesList => SoftwareProductDependenciesActionHelper.updateDependencyList(dispatch, {dependenciesList}), - onAddDependency: () => SoftwareProductDependenciesActionHelper.addDependency(dispatch), - onSubmit: (dependenciesList) => SoftwareProductDependenciesActionHelper.saveDependencies(dispatch, {softwareProductId, version, dependenciesList}) + onDataChanged: (item) => SoftwareProductDependenciesActionHelper.updateDependency(dispatch, {softwareProductId, version, item}), + onDeleteDependency: (item) => SoftwareProductDependenciesActionHelper.removeDependency(dispatch, {softwareProductId, version, item}), + onAddDependency: (item) => SoftwareProductDependenciesActionHelper.createDependency(dispatch, {softwareProductId, version, item}) }; }; diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependenciesActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependenciesActionHelper.js index e47b33a577..f04f8faf56 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependenciesActionHelper.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependenciesActionHelper.js @@ -15,44 +15,83 @@ */ import RestAPIUtil from 'nfvo-utils/RestAPIUtil.js'; import Configuration from 'sdc-app/config/Configuration.js'; -import {actionTypes} from './SoftwareProductDependenciesConstants.js'; -import uuid from 'uuid-js'; +import {actionTypes, NEW_RULE_TEMP_ID} from './SoftwareProductDependenciesConstants.js'; function baseUrl(softwareProductId, version) { const versionId = version.id; const restPrefix = Configuration.get('restPrefix'); - return `${restPrefix}/v1.0/vendor-software-products/${softwareProductId}/versions/${versionId}/component-dependency-model`; + return `${restPrefix}/v1.0/vendor-software-products/${softwareProductId}/versions/${versionId}/component-dependencies`; } -function fetchDependency(softwareProductId, version) { +function fetchDependencies(softwareProductId, version) { return RestAPIUtil.fetch(`${baseUrl(softwareProductId, version)}`); } -function postDependency(softwareProductId, version, dependenciesList) { - let modifedDependencyList = dependenciesList ? dependenciesList.filter(item => item.sourceId && item.targetId) - .map(item => ({sourceId: item.sourceId, targetId: item.targetId, relationType: item.relationType})) : []; - return RestAPIUtil.post(`${baseUrl(softwareProductId, version)}`, {componentDependencyModels:modifedDependencyList}); +function addDepencency(softwareProductId, version, item) { + return RestAPIUtil.post(`${baseUrl(softwareProductId, version)}`, { + sourceId: item.sourceId, + targetId: item.targetId, + relationType: item.relationType + }); } + +function updateDepencency(softwareProductId, version, item) { + return RestAPIUtil.put(`${baseUrl(softwareProductId, version)}/${item.id}`, + { + sourceId: item.sourceId, + targetId: item.targetId, + relationType: item.relationType + }); +} + +function removeDependency(softwareProductId, version, item) { + return RestAPIUtil.destroy(`${baseUrl(softwareProductId, version)}/${item.id}`); +} + + const SoftwareProductDependenciesActionHelper = { - updateDependencyList(dispatch, {dependenciesList}) { - dispatch({type: actionTypes.SOFTWARE_PRODUCT_DEPENDENCIES_LIST_UPDATE, dependenciesList}); + updateDependency(dispatch, {softwareProductId, version, item}) { + // if change was made on existing item - we will update the server and refresh the list + // if change was made on the 'new' row - we will only fire the event + if (item.id !== NEW_RULE_TEMP_ID) { + return updateDepencency(softwareProductId, version, item).then(() => { + return this.fetchDependencies(dispatch, {softwareProductId, version}); + }); + } else { + dispatch({ + type: actionTypes.UPDATE_NEW_SOFTWARE_PRODUCT_DEPENDENCY, + item: item + }); + } }, - addDependency(dispatch) { - dispatch({type: actionTypes.ADD_SOFTWARE_PRODUCT_DEPENDENCY}); + + createDependency(dispatch, {softwareProductId, version, item}) { + // removing the temp id + delete item.id; + // creating the new dependency + return addDepencency(softwareProductId, version, item).then(() => { + dispatch({ + type: actionTypes.ADD_SOFTWARE_PRODUCT_DEPENDENCY + }); + return this.fetchDependencies(dispatch, {softwareProductId, version}); + }); }, + + removeDependency(dispatch, {softwareProductId, version, item}) { + return removeDependency(softwareProductId, version, item).then( () => { + return this.fetchDependencies(dispatch, {softwareProductId, version}); + }); + }, + fetchDependencies(dispatch, {softwareProductId, version}) { - return fetchDependency(softwareProductId, version).then( response => { - const dependenciesList = response.results ? response.results.map(item => {return {...item, id: uuid.create().toString()};}) : []; + return fetchDependencies(softwareProductId, version).then( response => { dispatch({ type: actionTypes.SOFTWARE_PRODUCT_DEPENDENCIES_LIST_UPDATE, - dependenciesList + dependenciesList : response.results }); }); - }, - saveDependencies(dispatch, {softwareProductId, version, dependenciesList}) { - return postDependency(softwareProductId, version, dependenciesList); - } + } }; export default SoftwareProductDependenciesActionHelper; diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependenciesConstants.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependenciesConstants.js index 1f27ed8311..c25561da17 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependenciesConstants.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependenciesConstants.js @@ -17,7 +17,8 @@ import keyMirror from 'nfvo-utils/KeyMirror.js'; export const actionTypes = keyMirror({ SOFTWARE_PRODUCT_DEPENDENCIES_LIST_UPDATE: null, - ADD_SOFTWARE_PRODUCT_DEPENDENCY: null + ADD_SOFTWARE_PRODUCT_DEPENDENCY: null, + UPDATE_NEW_SOFTWARE_PRODUCT_DEPENDENCY: null }); export const relationTypes = { @@ -27,3 +28,5 @@ export const relationTypes = { export const relationTypesOptions = [ {value: relationTypes.DEPENDS_ON, label: 'Depends On'} ]; + +export const NEW_RULE_TEMP_ID = 'newRuleTempId';
\ No newline at end of file diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependenciesReducer.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependenciesReducer.js index 3fb479eedc..3edd3b899a 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependenciesReducer.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependenciesReducer.js @@ -15,21 +15,31 @@ * permissions and limitations under the License. */ -import {actionTypes, relationTypes} from './SoftwareProductDependenciesConstants.js'; +import {actionTypes, relationTypes, NEW_RULE_TEMP_ID} from './SoftwareProductDependenciesConstants.js'; import {checkCyclesAndMarkDependencies} from './SoftwareProductDependenciesUtils.js'; -import uuid from 'uuid-js'; -export default (state = [], action) => { +let newRowObject = {id: NEW_RULE_TEMP_ID, targetId: null, sourceId: null, relationType: relationTypes.DEPENDS_ON}; + +export default (state = [Object.assign({}, newRowObject) ], action) => { switch (action.type) { case actionTypes.SOFTWARE_PRODUCT_DEPENDENCIES_LIST_UPDATE: + // copying the entity with the data for the row that is in the 'add' mode + let newDependency = state.find(dependency => dependency.id === NEW_RULE_TEMP_ID); + action.dependenciesList.push(newDependency); + // returning list from the server with our 'new entity' row return checkCyclesAndMarkDependencies(action.dependenciesList); - case actionTypes.ADD_SOFTWARE_PRODUCT_DEPENDENCY: - return [...state, { - sourceId: null, - relationType: relationTypes.DEPENDS_ON, - targetId: null, - id: uuid.create() - }]; + case actionTypes.ADD_SOFTWARE_PRODUCT_DEPENDENCY : + // resetting the entity with the data for the 'add' mode for a new entity + let newArray = state.filter(dependency => dependency.id !== NEW_RULE_TEMP_ID); + newArray.push(Object.assign({}, newRowObject)); + return newArray; + case actionTypes.UPDATE_NEW_SOFTWARE_PRODUCT_DEPENDENCY : + // we really only need this for the 'new' row since we need to change the state to get + // everything updated + let updateArrayIndex = state.findIndex(dependency => dependency.id === NEW_RULE_TEMP_ID); + let updateArray = state.slice(); + updateArray.splice(updateArrayIndex, 1, action.item); + return checkCyclesAndMarkDependencies(updateArray); default: return state; } diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependenciesView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependenciesView.jsx index a427470a4f..ed92de7bb1 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependenciesView.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependenciesView.jsx @@ -20,7 +20,42 @@ import i18n from 'nfvo-utils/i18n/i18n.js'; import SelectActionTable from 'nfvo-components/table/SelectActionTable.jsx'; import SelectActionTableRow from 'nfvo-components/table/SelectActionTableRow.jsx'; import SelectActionTableCell from 'nfvo-components/table/SelectActionTableCell.jsx'; -import {relationTypesOptions} from './SoftwareProductDependenciesConstants.js'; +import {relationTypesOptions, NEW_RULE_TEMP_ID} from './SoftwareProductDependenciesConstants.js'; + + +const TableActionRow = ({onAction, actionIcon, showAction, dependency, sourceOptions, targetOptions, onDataChanged}) => { + return ( + <SelectActionTableRow + key={dependency.id} + onAction={onAction} + overlayMsg={i18n('There is a loop between selections')} + hasError={dependency.hasCycle} + hasErrorIndication + showAction={showAction} + actionIcon={actionIcon}> + <SelectActionTableCell + options={sourceOptions} + selected={dependency.sourceId} + placeholder={i18n('Select VFC...')} + clearable={false} + onChange={newVal => { + dependency.sourceId = newVal; + onDataChanged(dependency); + }} /> + <SelectActionTableCell options={relationTypesOptions} selected={dependency.relationType} clearable={false}/> + <SelectActionTableCell + placeholder={i18n('Select VFC...')} + options={targetOptions} + selected={dependency.targetId} + clearable={false} + onChange={newVal => { + dependency.targetId = newVal; + onDataChanged(dependency); + }} /> + </SelectActionTableRow> + ); +}; + export default class SoftwareProductDependenciesView extends React.Component { filterTargets({componentsOptions, sourceToTargetMapping, selectedSourceId, selectedTargetId}) { @@ -46,8 +81,7 @@ export default class SoftwareProductDependenciesView extends React.Component { } render() { - let {componentsOptions, softwareProductDependencies, onDataChanged, onAddDependency, isReadOnlyMode} = this.props; - let canAdd = softwareProductDependencies.length < componentsOptions.length * (componentsOptions.length - 1); + let {componentsOptions, softwareProductDependencies, onDataChanged, onAddDependency, onDeleteDependency, isReadOnlyMode} = this.props; let sourceToTargetMapping = {}; softwareProductDependencies.map(dependency => { let isInMap = sourceToTargetMapping.hasOwnProperty(dependency.sourceId); @@ -55,47 +89,42 @@ export default class SoftwareProductDependenciesView extends React.Component { sourceToTargetMapping[dependency.sourceId] = isInMap ? [...sourceToTargetMapping[dependency.sourceId], dependency.targetId] : [dependency.targetId]; } }); + let depList = softwareProductDependencies.filter(dependency => dependency.id !== NEW_RULE_TEMP_ID); + let newDependency = softwareProductDependencies.find(dependency => dependency.id === NEW_RULE_TEMP_ID); return ( <div className='software-product-dependencies'> - <div className='software-product-dependencies-title'>{i18n('Dependencies')}</div> + <div className='page-title'>{i18n('Dependencies')}</div> <SelectActionTable - columns={['Source', 'Relation Type', 'Target']} + columns={[i18n('Source'), i18n('Relation Type'), i18n('Target')]} numOfIcons={2} - isReadOnlyMode={isReadOnlyMode} - onAdd={canAdd ? onAddDependency : undefined} - onAddItem={i18n('Add Rule')}> - {softwareProductDependencies.map(dependency => ( - <SelectActionTableRow + isReadOnlyMode={isReadOnlyMode}> + {!isReadOnlyMode && <TableActionRow + key={newDependency.id} + actionIcon='plusCircle' + onAction={() => onAddDependency(newDependency)} + dependency={newDependency} + componentsOptions={componentsOptions} + sourceToTargetMapping={sourceToTargetMapping} + onDataChanged={onDataChanged} + sourceOptions={this.filterSources({componentsOptions, sourceToTargetMapping, selectedSourceId: newDependency.sourceId, selectedTargetId: newDependency.targetId})} + targetOptions={this.filterTargets({componentsOptions, sourceToTargetMapping, selectedSourceId: newDependency.sourceId, selectedTargetId: newDependency.targetId})} + showAction={newDependency.targetId !== null && newDependency.relationType !== null && newDependency.sourceId !== null}/> } + {depList.map(dependency => ( + <TableActionRow key={dependency.id} - onDelete={() => onDataChanged(softwareProductDependencies.filter(currentDependency => currentDependency.id !== dependency.id))} - overlayMsg={i18n('There is a loop between selections')} - hasError={dependency.hasCycle} - hasErrorIndication - showDelete={dependency.id !== 'fake' || dependency.hasCycle !== undefined}> - <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> + actionIcon='trashO' + onAction={() => onDeleteDependency(dependency)} + dependency={dependency} + componentsOptions={componentsOptions} + sourceToTargetMapping={sourceToTargetMapping} + sourceOptions={this.filterSources({componentsOptions, sourceToTargetMapping, selectedSourceId: dependency.sourceId, selectedTargetId: dependency.targetId})} + targetOptions={this.filterTargets({componentsOptions, sourceToTargetMapping, selectedSourceId: dependency.sourceId, selectedTargetId: dependency.targetId})} + onDataChanged={onDataChanged} + showAction={true}/> ))} </SelectActionTable> </div> ); } - save() { - let {onSubmit, softwareProductDependencies} = this.props; - return onSubmit(softwareProductDependencies); - } } diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment/SoftwareProductDeployment.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment/SoftwareProductDeployment.js index 98f773b465..a5c70068b0 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment/SoftwareProductDeployment.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment/SoftwareProductDeployment.js @@ -18,13 +18,10 @@ import SoftwareProductDeploymentView from './SoftwareProductDeploymentView.jsx'; import SoftwareProductDeploymentActionHelper from './SoftwareProductDeploymentActionHelper.js'; import i18n from 'nfvo-utils/i18n/i18n.js'; import {actionTypes as modalActionTypes} from 'nfvo-components/modal/GlobalModalConstants.js'; -import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js'; export function mapStateToProps({softwareProduct}) { - let {softwareProductEditor: {data: currentSoftwareProduct = {}},softwareProductComponents: {componentsList}, softwareProductDeployment: {deploymentFlavors}} = softwareProduct; - let isReadOnlyMode = VersionControllerUtils.isReadOnly(currentSoftwareProduct); + let {softwareProductComponents: {componentsList}, softwareProductDeployment: {deploymentFlavors}} = softwareProduct; return { - isReadOnlyMode, deploymentFlavors, componentsList }; @@ -37,7 +34,7 @@ function mapActionToProps(dispatch, {softwareProductId, version}) { onDeleteDeployment: ({id, model}) => dispatch({ type: modalActionTypes.GLOBAL_MODAL_WARNING, data:{ - msg: i18n(`Are you sure you want to delete "${model}"?`), + msg: i18n('Are you sure you want to delete "{model}"?', {model: model}), onConfirmed: () => SoftwareProductDeploymentActionHelper.deleteDeploymentFlavor(dispatch, {softwareProductId, deploymentFlavorId: id, version}) } }), diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment/SoftwareProductDeploymentView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment/SoftwareProductDeploymentView.jsx index 81477ecff7..860d02c343 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment/SoftwareProductDeploymentView.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment/SoftwareProductDeploymentView.jsx @@ -14,6 +14,7 @@ * permissions and limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import i18n from 'nfvo-utils/i18n/i18n.js'; import ListEditorView from 'nfvo-components/listEditor/ListEditorView.jsx'; @@ -26,10 +27,10 @@ export default class SoftwareProductDeployment extends React.Component { }; static propTypes = { - onAddDeployment: React.PropTypes.func.isRequired, - onDeleteDeployment: React.PropTypes.func.isRequired, - onEditDeployment: React.PropTypes.func.isRequired, - isReadOnlyMode: React.PropTypes.bool.isRequired + onAddDeployment: PropTypes.func.isRequired, + onDeleteDeployment: PropTypes.func.isRequired, + onEditDeployment: PropTypes.func.isRequired, + isReadOnlyMode: PropTypes.bool.isRequired }; render() { diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment/editor/SoftwareProductDeploymentEditor.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment/editor/SoftwareProductDeploymentEditor.js index ba00d4e56e..c24548b7b9 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment/editor/SoftwareProductDeploymentEditor.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment/editor/SoftwareProductDeploymentEditor.js @@ -16,12 +16,14 @@ import {connect} from 'react-redux'; import SoftwareProductDeploymentEditorView from './SoftwareProductDeploymentEditorView.jsx'; import SoftwareProdcutDeploymentActionHelper from '../SoftwareProductDeploymentActionHelper.js'; -import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js'; import ValidationHelper from 'sdc-app/common/helpers/ValidationHelper.js'; - import {DEPLOYMENT_FLAVORS_FORM_NAME} from '../SoftwareProductDeploymentConstants.js'; -export function mapStateToProps({licenseModel, softwareProduct}) { +export function mapStateToProps({ + licenseModel, + softwareProduct, + currentScreen: {props: {isReadOnlyMode}} +}) { let { softwareProductEditor: { data: currentSoftwareProduct = {} @@ -48,7 +50,6 @@ export function mapStateToProps({licenseModel, softwareProduct}) { } } = licenseModel; - let isReadOnlyMode = VersionControllerUtils.isReadOnly(currentSoftwareProduct); let isFormValid = ValidationHelper.checkFormValid(genericFieldInfo); let selectedFeatureGroupsIds = currentSoftwareProduct.licensingData ? currentSoftwareProduct.licensingData.featureGroups || [] : []; let selectedFeatureGroupsList = featureGroupsList diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment/editor/SoftwareProductDeploymentEditorView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment/editor/SoftwareProductDeploymentEditorView.jsx index 2d621cd2f5..7c9ae438d9 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment/editor/SoftwareProductDeploymentEditorView.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/deployment/editor/SoftwareProductDeploymentEditorView.jsx @@ -29,7 +29,7 @@ export default class SoftwareProductDeploymentEditorView extends React.Component isValid={this.props.isFormValid} formReady={this.props.formReady} className='vsp-deployment-editor'> - <GridSection> + <GridSection hasLastColSet> <GridItem colSpan={1}> <Input onChange={model => onDataChanged({model}, {model: model => this.validateName(model)})} @@ -41,7 +41,7 @@ export default class SoftwareProductDeploymentEditorView extends React.Component isRequired={true} type='text'/> </GridItem> - <GridItem colSpan={3}> + <GridItem colSpan={3} lastColInRow> <Input onChange={description => onDataChanged({description})} label={i18n('Description')} @@ -52,7 +52,7 @@ export default class SoftwareProductDeploymentEditorView extends React.Component type='text'/> </GridItem> </GridSection> - <GridSection className={`deployment-feature-groups-section${!featureGroupsExist ? ' no-feature-groups' : ''}`} title={i18n('License Details')}> + <GridSection className={`deployment-feature-groups-section${!featureGroupsExist ? ' no-feature-groups' : ''}`} title={i18n('License Details')} hasLastColSet> <GridItem colSpan={1}> <SelectInput data-test-id='deployment-feature-groups' @@ -71,8 +71,8 @@ export default class SoftwareProductDeploymentEditorView extends React.Component <span>{i18n('Please assign Feature Groups in VSP General')}</span> </GridItem> </GridSection>} - <GridSection title={i18n('Assign VFCs and Compute Flavors')} className='vfc-table'> - <GridItem colSpan={4}> + <GridSection title={i18n('Assign VFCs and Compute Flavors')} className='vfc-table' hasLastColSet> + <GridItem colSpan={4} lastColInRow> <SelectActionTable columns={['Virtual Function Components', 'Compute Flavors']} numOfIcons={0}> diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/details/SoftwareProductDetails.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/details/SoftwareProductDetails.js index ac0282e593..b7ddf134bb 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/details/SoftwareProductDetails.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/details/SoftwareProductDetails.js @@ -15,19 +15,24 @@ */ import {connect} from 'react-redux'; -import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js'; import SoftwareProductActionHelper from 'sdc-app/onboarding/softwareProduct/SoftwareProductActionHelper.js'; import SoftwareProductDetailsView from './SoftwareProductDetailsView.jsx'; import ValidationHelper from 'sdc-app/common/helpers/ValidationHelper.js'; import {PRODUCT_QUESTIONNAIRE} from 'sdc-app/onboarding/softwareProduct/SoftwareProductConstants.js'; -export const mapStateToProps = ({finalizedLicenseModelList, softwareProduct, licenseModel: {licenseAgreement, featureGroup}}) => { - let {softwareProductEditor: {data: currentSoftwareProduct, genericFieldInfo}, softwareProductCategories, softwareProductQuestionnaire} = softwareProduct; +export const mapStateToProps = ({ + finalizedLicenseModelList, + softwareProduct, + licenseModel: {licenseAgreement, featureGroup} +}) => { + + let {softwareProductEditor: {data: currentSoftwareProduct, licensingVersionsList = [], genericFieldInfo}, softwareProductCategories, softwareProductQuestionnaire} = softwareProduct; let {licensingData = {}, licensingVersion} = currentSoftwareProduct; let licenseAgreementList = [], filteredFeatureGroupsList = []; - licenseAgreementList = licenseAgreement.licenseAgreementList; - if(licensingVersion && licensingVersion !== '' && licensingData && licensingData.licenseAgreement) { + licenseAgreementList = licensingVersion ? + licenseAgreement.licenseAgreementList : []; + if(licensingVersion && licensingData && licensingData.licenseAgreement) { let selectedLicenseAgreement = licenseAgreementList.find(la => la.id === licensingData.licenseAgreement); if (selectedLicenseAgreement) { let featureGroupsList = featureGroup.featureGroupsList.filter(({referencingLicenseAgreements}) => referencingLicenseAgreements.includes(selectedLicenseAgreement.id)); @@ -37,7 +42,6 @@ export const mapStateToProps = ({finalizedLicenseModelList, softwareProduct, lic } } let {qdata, qgenericFieldInfo : qGenericFieldInfo, dataMap} = softwareProductQuestionnaire; - let isReadOnlyMode = VersionControllerUtils.isReadOnly(currentSoftwareProduct); let isFormValid = ValidationHelper.checkFormValid(genericFieldInfo); @@ -45,24 +49,25 @@ export const mapStateToProps = ({finalizedLicenseModelList, softwareProduct, lic currentSoftwareProduct, softwareProductCategories, licenseAgreementList, + licensingVersionsList, featureGroupsList: filteredFeatureGroupsList, finalizedLicenseModelList, qdata, - isReadOnlyMode, isFormValid, genericFieldInfo, qGenericFieldInfo, dataMap }; + }; -export const mapActionsToProps = (dispatch) => { +export const mapActionsToProps = (dispatch, {version}) => { return { onDataChanged: (deltaData, formName) => ValidationHelper.dataChanged(dispatch, {deltaData, formName}), onVendorParamChanged: (deltaData, formName) => SoftwareProductActionHelper.softwareProductEditorVendorChanged(dispatch, {deltaData, formName}), onQDataChanged: (deltaData) => ValidationHelper.qDataChanged(dispatch, {deltaData, qName: PRODUCT_QUESTIONNAIRE}), onValidityChanged: isValidityData => SoftwareProductActionHelper.setIsValidityData(dispatch, {isValidityData}), - onSubmit: (softwareProduct, qdata) =>{ return SoftwareProductActionHelper.updateSoftwareProduct(dispatch, {softwareProduct, qdata});} + onSubmit: (softwareProduct, qdata) => SoftwareProductActionHelper.updateSoftwareProduct(dispatch, {softwareProduct, qdata, version}) }; }; diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/details/SoftwareProductDetailsReducer.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/details/SoftwareProductDetailsReducer.js index d62207ff9f..54dc1a4d37 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/details/SoftwareProductDetailsReducer.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/details/SoftwareProductDetailsReducer.js @@ -45,6 +45,11 @@ export default (state = {}, action) => { ...state, mapOfExpandedIds: action.mapOfExpandedIds }; + case actionTypes.LOAD_LICENSING_VERSIONS_LIST: + return { + ...state, + licensingVersionsList: action.licensingVersionsList + }; default: return state; } diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/details/SoftwareProductDetailsView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/details/SoftwareProductDetailsView.jsx index e4caf92c21..f6199ec83e 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/details/SoftwareProductDetailsView.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/details/SoftwareProductDetailsView.jsx @@ -13,7 +13,8 @@ * or implied. See the License for the specific language governing * permissions and limitations under the License. */ -import React, {Component, PropTypes} from 'react'; +import React, {Component} from 'react'; +import PropTypes from 'prop-types'; import i18n from 'nfvo-utils/i18n/i18n.js'; import sortByStringProperty from 'nfvo-utils/sortByStringProperty.js'; @@ -55,7 +56,7 @@ class GeneralSection extends React.Component { let {genericFieldInfo} = this.props; return ( <div> - {genericFieldInfo && <GridSection title={i18n('General')}> + {genericFieldInfo && <GridSection title={i18n('General')} className='grid-section-general'> <GridItem> <Input data-test-id='vsp-name' @@ -74,8 +75,8 @@ class GeneralSection extends React.Component { onChange={e => this.onVendorParamChanged(e)}> {sortByStringProperty( this.props.finalizedLicenseModelList, - 'vendorName' - ).map(lm => <option key={lm.id} value={lm.id}>{lm.vendorName}</option>) + 'name' + ).map(lm => <option key={lm.id} value={lm.id}>{lm.name}</option>) } </Input> <Input @@ -117,7 +118,7 @@ class LicensesSection extends React.Component { static propTypes = { onVendorParamChanged: PropTypes.func.isRequired, vendorId: PropTypes.string, - licensingVersion: PropTypes.object, + licensingVersion: PropTypes.string, licensingVersionsList: PropTypes.array, licensingData: PropTypes.shape({ licenceAgreement: PropTypes.string, @@ -132,7 +133,7 @@ class LicensesSection extends React.Component { 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); + this.props.onVendorParamChanged({vendorId: this.props.vendorId, licensingVersion}, forms.VENDOR_SOFTWARE_PRODUCT_DETAILS); } onLicensingDataChanged(e) { @@ -148,7 +149,7 @@ class LicensesSection extends React.Component { <Input data-test-id='vsp-licensing-version' onChange={e => this.onVendorParamChanged(e)} - value={this.props.licensingVersion ? this.props.licensingVersion.id : ''} + value={this.props.licensingVersion || ''} label={i18n('Licensing Version')} type='select'> {this.props.licensingVersionsList.map(version => @@ -196,6 +197,7 @@ const AvailabilitySection = (props) => ( data-test-id='vsp-use-availability-zone' label={i18n('Use Availability Zones for High Availability')} type='checkbox' + checked={props.dataMap['general/availability/useAvailabilityZonesForHighAvailability']} value={props.dataMap['general/availability/useAvailabilityZonesForHighAvailability']} onChange={(aZone) => props.onQDataChanged({'general/availability/useAvailabilityZonesForHighAvailability' : aZone})} /> </GridItem> @@ -274,7 +276,7 @@ class SoftwareProductDetails extends Component { subCategory: PropTypes.string, vendorId: PropTypes.string, vendorName: PropTypes.string, - licensingVersion: PropTypes.object, + licensingVersion: PropTypes.string, licensingData: PropTypes.shape({ licenceAgreement: PropTypes.string, featureGroups: PropTypes.array @@ -292,10 +294,6 @@ class SoftwareProductDetails extends Component { onVendorParamChanged: PropTypes.func.isRequired }; - state = { - licensingVersionsList: [] - }; - prepareDataForGeneralSection(){ let {softwareProductCategories, finalizedLicenseModelList, onDataChanged, currentSoftwareProduct, genericFieldInfo} = this.props; let {name, description, vendorId, subCategory} = currentSoftwareProduct; @@ -317,12 +315,11 @@ class SoftwareProductDetails extends Component { prepareDataForLicensesSection(){ let { featureGroupsList, licenseAgreementList, currentSoftwareProduct } = this.props; let {vendorId, licensingVersion, licensingData = {}} = currentSoftwareProduct; - let licensingVersionsList = this.state.licensingVersionsList.length > 0 ? this.state.licensingVersionsList : this.refreshVendorVersionsList(vendorId); return { onVendorParamChanged: args => this.onVendorParamChanged(args), vendorId, licensingVersion, - licensingVersionsList, + licensingVersionsList: this.buildLicensingVersionsListItems(), licensingData, onFeatureGroupsChanged: args => this.onFeatureGroupsChanged(args), onLicensingDataChanged: args => this.onLicensingDataChanged(args), @@ -361,10 +358,10 @@ class SoftwareProductDetails extends Component { onVendorParamChanged({vendorId, licensingVersion}) { let {finalizedLicenseModelList, onVendorParamChanged} = this.props; if(!licensingVersion) { - const licensingVersionsList = this.refreshVendorVersionsList(vendorId); - licensingVersion = licensingVersionsList.length > 0 ? licensingVersionsList[0].enum : ''; + const licensingVersionsList = this.buildLicensingVersionsListItems(); + licensingVersion = licensingVersionsList[0].enum; } - let vendorName = finalizedLicenseModelList.find(licenseModelItem => licenseModelItem.id === vendorId).vendorName || ''; + let vendorName = finalizedLicenseModelList.find(licenseModelItem => licenseModelItem.id === vendorId).name || ''; let deltaData = { vendorId, vendorName, @@ -376,25 +373,15 @@ class SoftwareProductDetails extends Component { } - refreshVendorVersionsList(vendorId) { - if(!vendorId) { - return []; - } + buildLicensingVersionsListItems() { + let {licensingVersionsList} = this.props; - let {finalVersions} = this.props.finalizedLicenseModelList.find(vendor => vendor.id === vendorId); - - let licensingVersionsList = [{ + let licensingVersionsListItems = [{ enum: '', title: i18n('Select...') }]; - if(finalVersions) { - finalVersions.forEach(version => licensingVersionsList.push({ - enum: version.id, - title: version.label - })); - } - return licensingVersionsList; + return licensingVersionsListItems.concat(licensingVersionsList.map(version => ({enum: version.id, title: version.name}))); } onFeatureGroupsChanged({featureGroups}) { diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/landingPage/SoftwareProductLandingPage.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/landingPage/SoftwareProductLandingPage.js index a13e742006..90ea182dfa 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/landingPage/SoftwareProductLandingPage.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/landingPage/SoftwareProductLandingPage.js @@ -15,14 +15,18 @@ */ import {connect} from 'react-redux'; import i18n from 'nfvo-utils/i18n/i18n.js'; -import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js'; -import OnboardingActionHelper from 'sdc-app/onboarding/OnboardingActionHelper.js'; import SoftwareProductActionHelper from 'sdc-app/onboarding/softwareProduct/SoftwareProductActionHelper.js'; import LandingPageView from './SoftwareProductLandingPageView.jsx'; import {actionTypes as modalActionTypes} from 'nfvo-components/modal/GlobalModalConstants.js'; import {onboardingMethod} from '../SoftwareProductConstants.js'; +import ScreensHelper from 'sdc-app/common/helpers/ScreensHelper.js'; +import {enums, screenTypes} from 'sdc-app/onboarding/OnboardingConstants.js'; -export const mapStateToProps = ({softwareProduct, licenseModel: {licenseAgreement}}) => { + +export const mapStateToProps = ({ + softwareProduct, + licenseModel: {licenseAgreement}, +}) => { let {softwareProductEditor: {data:currentSoftwareProduct = {}}, softwareProductComponents, softwareProductCategories = []} = softwareProduct; let {licensingData = {}} = currentSoftwareProduct; let {licenseAgreementList} = licenseAgreement; @@ -44,7 +48,6 @@ export const mapStateToProps = ({softwareProduct, licenseModel: {licenseAgreemen } fullCategoryDisplayName = `${subCategoryName} (${categoryName})`; - const isReadOnlyMode = VersionControllerUtils.isReadOnly(currentSoftwareProduct); return { currentSoftwareProduct: { @@ -52,7 +55,6 @@ export const mapStateToProps = ({softwareProduct, licenseModel: {licenseAgreemen licenseAgreementName, fullCategoryDisplayName }, - isReadOnlyMode, componentsList, isManual: currentSoftwareProduct.onboardingMethod === onboardingMethod.MANUAL }; @@ -60,11 +62,12 @@ export const mapStateToProps = ({softwareProduct, licenseModel: {licenseAgreemen const mapActionsToProps = (dispatch, {version}) => { return { - onDetailsSelect: ({id: softwareProductId, vendorId: licenseModelId, version}) => OnboardingActionHelper.navigateToSoftwareProductDetails(dispatch, { - softwareProductId, - licenseModelId, - version - }), + onDetailsSelect: ({id: softwareProductId}) => + ScreensHelper.loadScreen(dispatch, { + screen: enums.SCREEN.SOFTWARE_PRODUCT_DETAILS, screenType: screenTypes.SOFTWARE_PRODUCT, + props: {softwareProductId, version} + }), + onUpload: (softwareProductId, formData) => SoftwareProductActionHelper.uploadFile(dispatch, { softwareProductId, @@ -100,9 +103,10 @@ const mapActionsToProps = (dispatch, {version}) => { msg: i18n('no zip or csar file was uploaded or expected file doesn\'t exist') } }), - onComponentSelect: ({id: softwareProductId, componentId}) => { - OnboardingActionHelper.navigateToSoftwareProductComponentGeneralAndUpdateLeftPanel(dispatch, {softwareProductId, componentId, version }); - }, + onComponentSelect: ({id: softwareProductId, componentId}) => ScreensHelper.loadScreen(dispatch, { + screen: screenTypes.SOFTWARE_PRODUCT_COMPONENT_DEFAULT_GENERAL, screenType: screenTypes.SOFTWARE_PRODUCT, + props: {softwareProductId, version, componentId} + }), /** for the next version */ onAddComponent: () => SoftwareProductActionHelper.addComponent(dispatch) }; diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/landingPage/SoftwareProductLandingPageView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/landingPage/SoftwareProductLandingPageView.jsx index 72a416473c..56402b4417 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/landingPage/SoftwareProductLandingPageView.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/landingPage/SoftwareProductLandingPageView.jsx @@ -14,6 +14,7 @@ * permissions and limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import classnames from 'classnames'; import Dropzone from 'react-dropzone'; @@ -22,25 +23,25 @@ import i18n from 'nfvo-utils/i18n/i18n.js'; import DraggableUploadFileBox from 'nfvo-components/fileupload/DraggableUploadFileBox.jsx'; import SVGIcon from 'sdc-ui/lib/react/SVGIcon.js'; -import SoftwareProductComponentsList from '../components/SoftwareProductComponentsList.js'; - -const SoftwareProductPropType = React.PropTypes.shape({ - name: React.PropTypes.string, - description: React.PropTypes.string, - version: React.PropTypes.object, - id: React.PropTypes.string, - categoryId: React.PropTypes.string, - vendorId: React.PropTypes.string, - status: React.PropTypes.string, - licensingData: React.PropTypes.object, - validationData: React.PropTypes.object +import SoftwareProductComponentsList from 'sdc-app/onboarding/softwareProduct/components/SoftwareProductComponents.js'; + +const SoftwareProductPropType = PropTypes.shape({ + name: PropTypes.string, + description: PropTypes.string, + version: PropTypes.object, + id: PropTypes.string, + categoryId: PropTypes.string, + vendorId: PropTypes.string, + status: PropTypes.string, + licensingData: PropTypes.object, + validationData: PropTypes.object }); -const ComponentPropType = React.PropTypes.shape({ - id: React.PropTypes.string, - name: React.PropTypes.string, - displayName: React.PropTypes.string, - description: React.PropTypes.string +const ComponentPropType = PropTypes.shape({ + id: PropTypes.string, + name: PropTypes.string, + displayName: PropTypes.string, + description: PropTypes.string }); class SoftwareProductLandingPageView extends React.Component { @@ -54,18 +55,19 @@ class SoftwareProductLandingPageView extends React.Component { static propTypes = { currentSoftwareProduct: SoftwareProductPropType, - isReadOnlyMode: React.PropTypes.bool, - componentsList: React.PropTypes.arrayOf(ComponentPropType), - onDetailsSelect: React.PropTypes.func, - onUpload: React.PropTypes.func, - onUploadConfirmation: React.PropTypes.func, - onInvalidFileSizeUpload: React.PropTypes.func, - onComponentSelect: React.PropTypes.func, - onAddComponent: React.PropTypes.func + isReadOnlyMode: PropTypes.bool, + componentsList: PropTypes.arrayOf(ComponentPropType), + version: PropTypes.object, + onDetailsSelect: PropTypes.func, + onUpload: PropTypes.func, + onUploadConfirmation: PropTypes.func, + onInvalidFileSizeUpload: PropTypes.func, + onComponentSelect: PropTypes.func, + onAddComponent: PropTypes.func }; render() { - let {currentSoftwareProduct, isReadOnlyMode, isManual, onDetailsSelect, componentsList} = this.props; + let {currentSoftwareProduct, isReadOnlyMode, isManual, onDetailsSelect} = this.props; return ( <div className='software-product-landing-wrapper'> <Dropzone @@ -88,11 +90,7 @@ class SoftwareProductLandingPageView extends React.Component { </div> </div> </Dropzone> - <SoftwareProductComponentsList - isReadOnlyMode={isReadOnlyMode} - componentsList={componentsList} - isManual={isManual} - currentSoftwareProduct={currentSoftwareProduct}/> + <SoftwareProductComponentsList/> </div> ); } diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/networks/SoftwareProductNetworksView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/networks/SoftwareProductNetworksView.jsx index 024c5cc44c..e8c365f124 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/networks/SoftwareProductNetworksView.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/networks/SoftwareProductNetworksView.jsx @@ -14,6 +14,7 @@ * permissions and limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import i18n from 'nfvo-utils/i18n/i18n.js'; import ListEditorView from 'nfvo-components/listEditor/ListEditorView.jsx'; @@ -23,11 +24,12 @@ import ListEditorItemViewField from 'nfvo-components/listEditor/ListEditorItemVi class SoftwareProductNetworksView extends React.Component { static propTypes = { - networksList: React.PropTypes.arrayOf(React.PropTypes.shape({ - id: React.PropTypes.string.isRequired, - name: React.PropTypes.string.isRequired, - dhcp: React.PropTypes.bool.isRequired - })).isRequired + networksList: PropTypes.arrayOf(PropTypes.shape({ + id: PropTypes.string.isRequired, + name: PropTypes.string.isRequired, + dhcp: PropTypes.bool.isRequired + })).isRequired, + isReadOnlyMode: PropTypes.bool.isRequired }; state = { @@ -36,6 +38,7 @@ class SoftwareProductNetworksView extends React.Component { render() { const {localFilter} = this.state; + const {isReadOnlyMode} = this.props; return ( <div className='vsp-networks-page'> @@ -45,19 +48,19 @@ class SoftwareProductNetworksView extends React.Component { placeholder={i18n('Filter Networks')} onFilter={value => this.setState({localFilter: value})} twoColumns> - {this.filterList().map(network => this.renderNetworksListItem(network))} + {this.filterList().map(network => this.renderNetworksListItem({network, isReadOnlyMode}))} </ListEditorView> </div> ); } - renderNetworksListItem(network) { + renderNetworksListItem({network, isReadOnlyMode}) { let {id, name, dhcp} = network; return ( <ListEditorItemView key={id} className='list-editor-item-view' - isReadOnlyMode={true}> + isReadOnlyMode={isReadOnlyMode}> <ListEditorItemViewField> <div className='name'>{name}</div> diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessListView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessListView.jsx new file mode 100644 index 0000000000..aa39c87dd0 --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessListView.jsx @@ -0,0 +1,99 @@ +/*! + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ +import React from 'react'; +import PropTypes from 'prop-types'; +import i18n from 'nfvo-utils/i18n/i18n.js'; + +import ListEditorView from 'nfvo-components/listEditor/ListEditorView.jsx'; +import ListEditorItemView from 'nfvo-components/listEditor/ListEditorItemView.jsx'; + + +class SoftwareProductProcessesListView extends React.Component { + + state = { + localFilter: '' + }; + + static propTypes = { + onAddProcess: PropTypes.func.isRequired, + onEditProcess: PropTypes.func.isRequired, + onDeleteProcess: PropTypes.func.isRequired, + isReadOnlyMode: PropTypes.bool.isRequired, + currentSoftwareProduct:PropTypes.object, + addButtonTitle: PropTypes.string + }; + + render() { + const {localFilter} = this.state; + let {onAddProcess, isReadOnlyMode, addButtonTitle} = this.props; + + return ( + <ListEditorView + plusButtonTitle={addButtonTitle} + filterValue={localFilter} + placeholder={i18n('Filter Process')} + onAdd={onAddProcess} + isReadOnlyMode={isReadOnlyMode} + title={i18n('Process Details')} + onFilter={value => this.setState({localFilter: value})}> + {this.filterList().map(processes => this.renderProcessListItem(processes, isReadOnlyMode))} + </ListEditorView>); + } + + renderProcessListItem(process, isReadOnlyMode) { + let {id, name, description, artifactName = ''} = process; + let {currentSoftwareProduct: {version}, onEditProcess, onDeleteProcess} = this.props; + return ( + <ListEditorItemView + key={id} + className='list-editor-item-view' + isReadOnlyMode={isReadOnlyMode} + onSelect={() => onEditProcess(process)} + onDelete={() => onDeleteProcess(process, version)}> + + <div className='list-editor-item-view-field'> + <div className='title'>{i18n('Name')}</div> + <div className='name'>{name}</div> + </div> + <div className='list-editor-item-view-field'> + <div className='title'>{i18n('Artifact name')}</div> + <div className='artifact-name'>{artifactName}</div> + </div> + <div className='list-editor-item-view-field'> + <div className='title'>{i18n('Notes')}</div> + <div className='description'>{description}</div> + </div> + </ListEditorItemView> + ); + } + + filterList() { + let {processesList} = this.props; + let {localFilter} = this.state; + + if (localFilter.trim()) { + const filter = new RegExp(escape(localFilter), 'i'); + return processesList.filter(({name = '', description = ''}) => { + return escape(name).match(filter) || escape(description).match(filter); + }); + } + else { + return processesList; + } + } +} + +export default SoftwareProductProcessesListView; diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcesses.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcesses.js index c70452919b..b0403abde5 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcesses.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcesses.js @@ -16,33 +16,30 @@ import {connect} from 'react-redux'; import i18n from 'nfvo-utils/i18n/i18n.js'; import {actionTypes as modalActionTypes} from 'nfvo-components/modal/GlobalModalConstants.js'; -import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js'; import SoftwareProductProcessesActionHelper from './SoftwareProductProcessesActionHelper.js'; import SoftwareProductProcessesView from './SoftwareProductProcessesView.jsx'; export const mapStateToProps = ({softwareProduct}) => { let {softwareProductEditor: {data: currentSoftwareProduct = {}}, softwareProductProcesses: {processesList, processesEditor}} = softwareProduct; - let isReadOnlyMode = VersionControllerUtils.isReadOnly(currentSoftwareProduct); let {data} = processesEditor; return { currentSoftwareProduct, processesList, isDisplayEditor: Boolean(data), - isModalInEditMode: Boolean(data && data.id), - isReadOnlyMode + isModalInEditMode: Boolean(data && data.id) }; }; -const mapActionsToProps = (dispatch, {softwareProductId}) => { +const mapActionsToProps = (dispatch, {softwareProductId, version}) => { return { onAddProcess: () => SoftwareProductProcessesActionHelper.openEditor(dispatch), onEditProcess: (process) => SoftwareProductProcessesActionHelper.openEditor(dispatch, process), - onDeleteProcess: (process, version) => dispatch({ + onDeleteProcess: (process) => dispatch({ type: modalActionTypes.GLOBAL_MODAL_WARNING, data:{ - msg: i18n(`Are you sure you want to delete "${process.name}"?`), + msg: i18n('Are you sure you want to delete "{name}"?', {name: process.name}), confirmationButtonText: i18n('Delete'), title: i18n('Delete'), onConfirmed: ()=> SoftwareProductProcessesActionHelper.deleteProcess(dispatch, diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesEditor.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesEditor.js index ff787c357e..fc194fac13 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesEditor.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesEditor.js @@ -45,7 +45,7 @@ const mapActionsToProps = (dispatch, {softwareProductId, version}) => { SoftwareProductProcessesActionHelper.closeEditor(dispatch); SoftwareProductProcessesActionHelper.saveProcess(dispatch, {softwareProductId, version, previousProcess, process}); }, - onClose: () => SoftwareProductProcessesActionHelper.closeEditor(dispatch), + onCancel: () => SoftwareProductProcessesActionHelper.closeEditor(dispatch), onValidateForm: () => ValidationHelper.validateForm(dispatch, VSP_PROCESS_FORM) }; }; diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesEditorForm.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesEditorForm.jsx new file mode 100644 index 0000000000..72b2f8cb38 --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesEditorForm.jsx @@ -0,0 +1,181 @@ +/*! + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ +import React from 'react'; +import PropTypes from 'prop-types'; +import Dropzone from 'react-dropzone'; + +import DraggableUploadFileBox from 'nfvo-components/fileupload/DraggableUploadFileBox.jsx'; +import i18n from 'nfvo-utils/i18n/i18n.js'; +import Form from 'nfvo-components/input/validation/Form.jsx'; +import Input from 'nfvo-components/input/validation/Input.jsx'; +import GridSection from 'nfvo-components/grid/GridSection.jsx'; +import GridItem from 'nfvo-components/grid/GridItem.jsx'; + +const SoftwareProductProcessEditorPropType = React.PropTypes.shape({ + id: PropTypes.string, + name: PropTypes.string, + description: PropTypes.string, + artifactName: PropTypes.string, + type: PropTypes.string +}); + + + +class SoftwareProductProcessesEditorForm extends React.Component { + + + static propTypes = { + data: SoftwareProductProcessEditorPropType, + previousData: SoftwareProductProcessEditorPropType, + isReadOnlyMode: React.PropTypes.bool, + onDataChanged: React.PropTypes.func, + onSubmit: React.PropTypes.func, + onCancel: React.PropTypes.func + }; + state = { + dragging: false, + files: [] + }; + + render() { + let {data = {}, isReadOnlyMode, onDataChanged, onCancel, genericFieldInfo, optionsInputValues} = this.props; + let {name, description, artifactName, type} = data; + + return ( + <div> + {genericFieldInfo && <Form + ref='validationForm' + hasButtons={true} + labledButtons={true} + isReadOnlyMode={isReadOnlyMode} + 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={(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 hasLastColSet={true}> + <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} lastColInRow={true}> + <label> </label> + <DraggableUploadFileBox className='process-editor-file-box' isReadOnlyMode={isReadOnlyMode} onClick={() => this.refs.processEditorFileInput.open()}/> + </GridItem> + </GridSection> + <GridSection hasLastColSet={true}> + <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} lastColInRow={true}> + <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')} + className='process-type' + data-test-id='process-type' + isValid={genericFieldInfo.type.isValid} + errorText={genericFieldInfo.type.errorText} + type='select'> + {optionsInputValues.PROCESS_TYPE.map(mtype => + <option key={mtype.enum} value={mtype.enum}>{`${mtype.title}`}</option>)} + </Input> + </GridItem> + </GridSection> + </Dropzone> + </div> + </Form>} + </div> + ); + } + + submit() { + const {data: process, previousData: previousProcess} = this.props; + let {files} = this.state; + let formData = false; + if (files.length) { + let file = files[0]; + formData = new FormData(); + formData.append('upload', file); + } + + let updatedProcess = { + ...process, + formData + }; + this.props.onSubmit({process: updatedProcess, previousProcess}); + } + + + handleImportSubmit(files, rejectedFiles) { + if (files.length > 0) { + let {onDataChanged} = this.props; + this.setState({ + dragging: false, + complete: '0', + files + }); + onDataChanged({artifactName: files[0].name}); + } + else if (rejectedFiles.length > 0) { + this.setState({ + dragging: false + }); + if (DEBUG) { + console.log('file was rejected.' + rejectedFiles[0].name); + } + } + } +} + +export default SoftwareProductProcessesEditorForm; diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesEditorView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesEditorView.jsx index 0df36cf65d..9ce690a1ca 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesEditorView.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesEditorView.jsx @@ -14,167 +14,17 @@ * permissions and limitations under the License. */ import React from 'react'; -import Dropzone from 'react-dropzone'; -import classnames from 'classnames'; -import DraggableUploadFileBox from 'nfvo-components/fileupload/DraggableUploadFileBox.jsx'; -import i18n from 'nfvo-utils/i18n/i18n.js'; import {optionsInputValues as ProcessesOptionsInputValues} from './SoftwareProductProcessesConstants.js'; -import Form from 'nfvo-components/input/validation/Form.jsx'; -import Input from 'nfvo-components/input/validation/Input.jsx'; -import GridSection from 'nfvo-components/grid/GridSection.jsx'; -import GridItem from 'nfvo-components/grid/GridItem.jsx'; - -const SoftwareProductProcessEditorPropType = React.PropTypes.shape({ - id: React.PropTypes.string, - name: React.PropTypes.string, - description: React.PropTypes.string, - artifactName: React.PropTypes.string, - type: React.PropTypes.string -}); - +import SoftwareProductProcessesEditorForm from './SoftwareProductProcessesEditorForm.jsx'; class SoftwareProductProcessesEditorView extends React.Component { - - state = { - dragging: false, - files: [] - }; - - static propTypes = { - data: SoftwareProductProcessEditorPropType, - previousData: SoftwareProductProcessEditorPropType, - isReadOnlyMode: React.PropTypes.bool, - onDataChanged: React.PropTypes.func, - onSubmit: React.PropTypes.func, - onClose: React.PropTypes.func - }; - render() { - let {data = {}, isReadOnlyMode, onDataChanged, onClose, genericFieldInfo} = this.props; - let {name, description, artifactName, type} = data; - return ( - <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}> - <DraggableUploadFileBox isReadOnlyMode={isReadOnlyMode} className='file-upload-box' 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> + <SoftwareProductProcessesEditorForm optionsInputValues={ProcessesOptionsInputValues} {...this.props}/> ); } - - submit() { - const {data: process, previousData: previousProcess} = this.props; - let {files} = this.state; - let formData = false; - if (files.length) { - let file = files[0]; - formData = new FormData(); - formData.append('upload', file); - } - - let updatedProcess = { - ...process, - formData - }; - this.props.onSubmit({process: updatedProcess, previousProcess}); - } - - - handleImportSubmit(files, rejectedFiles) { - if (files.length > 0) { - let {onDataChanged} = this.props; - this.setState({ - dragging: false, - complete: '0', - files - }); - onDataChanged({artifactName: files[0].name}); - } - else if (rejectedFiles.length > 0) { - this.setState({ - dragging: false - }); - if (DEBUG) { - console.log('file was rejected.' + rejectedFiles[0].name); - } - } - } } export default SoftwareProductProcessesEditorView; diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesView.jsx index 8f52434042..e2cb4edf74 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesView.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/processes/SoftwareProductProcessesView.jsx @@ -14,14 +14,12 @@ * permissions and limitations under the License. */ import React from 'react'; +import PropTypes from 'prop-types'; import i18n from 'nfvo-utils/i18n/i18n.js'; import Modal from 'nfvo-components/modal/Modal.jsx'; -import ListEditorView from 'nfvo-components/listEditor/ListEditorView.jsx'; -import ListEditorItemView from 'nfvo-components/listEditor/ListEditorItemView.jsx'; - import SoftwareProductProcessesEditor from './SoftwareProductProcessesEditor.js'; - +import SoftwareProductProcessListView from './SoftwareProductProcessListView.jsx'; class SoftwareProductProcessesView extends React.Component { @@ -31,25 +29,25 @@ class SoftwareProductProcessesView extends React.Component { }; static propTypes = { - onAddProcess: React.PropTypes.func.isRequired, - onEditProcess: React.PropTypes.func.isRequired, - onDeleteProcess: React.PropTypes.func.isRequired, - isDisplayEditor: React.PropTypes.bool.isRequired, - isReadOnlyMode: React.PropTypes.bool.isRequired, - currentSoftwareProduct:React.PropTypes.object + onAddProcess: PropTypes.func.isRequired, + onEditProcess: PropTypes.func.isRequired, + onDeleteProcess: PropTypes.func.isRequired, + isDisplayEditor: PropTypes.bool.isRequired, + isReadOnlyMode: PropTypes.bool.isRequired, + currentSoftwareProduct:PropTypes.object }; render() { return ( <div className='software-product-landing-view-right-side vsp-processes-page'> {this.renderEditor()} - {this.renderProcessList()} + <SoftwareProductProcessListView addButtonTitle={i18n('Add Process Details')} {...this.props}/> </div> ); } renderEditor() { - let {currentSoftwareProduct: {id, version}, isModalInEditMode, isReadOnlyMode, isDisplayEditor} = this.props; + let {currentSoftwareProduct: {id}, version, isModalInEditMode, isReadOnlyMode, isDisplayEditor} = this.props; return ( <Modal show={isDisplayEditor} bsSize='large' animation={true} className='onborading-modal'> @@ -62,66 +60,6 @@ class SoftwareProductProcessesView extends React.Component { </Modal> ); } - - renderProcessList() { - const {localFilter} = this.state; - let {onAddProcess, isReadOnlyMode} = this.props; - - return ( - <ListEditorView - plusButtonTitle={i18n('Add Process Details')} - filterValue={localFilter} - placeholder={i18n('Filter Process')} - onAdd={onAddProcess} - isReadOnlyMode={isReadOnlyMode} - title={i18n('Process Details')} - onFilter={value => this.setState({localFilter: value})}> - {this.filterList().map(processes => this.renderProcessListItem(processes, isReadOnlyMode))} - </ListEditorView> - ); - } - - renderProcessListItem(process, isReadOnlyMode) { - let {id, name, description, artifactName = ''} = process; - let {currentSoftwareProduct: {version}, onEditProcess, onDeleteProcess} = this.props; - return ( - <ListEditorItemView - key={id} - className='list-editor-item-view' - isReadOnlyMode={isReadOnlyMode} - onSelect={() => onEditProcess(process)} - onDelete={() => onDeleteProcess(process, version)}> - - <div className='list-editor-item-view-field'> - <div className='title'>{i18n('Name')}</div> - <div className='name'>{name}</div> - </div> - <div className='list-editor-item-view-field'> - <div className='title'>{i18n('Artifact name')}</div> - <div className='artifact-name'>{artifactName}</div> - </div> - <div className='list-editor-item-view-field'> - <div className='title'>{i18n('Notes')}</div> - <div className='description'>{description}</div> - </div> - </ListEditorItemView> - ); - } - - filterList() { - let {processesList} = this.props; - let {localFilter} = this.state; - - if (localFilter.trim()) { - const filter = new RegExp(escape(localFilter), 'i'); - return processesList.filter(({name = '', description = ''}) => { - return escape(name).match(filter) || escape(description).match(filter); - }); - } - else { - return processesList; - } - } } export default SoftwareProductProcessesView; diff --git a/openecomp-ui/src/sdc-app/onboarding/userNotifications/NotificationsReducer.js b/openecomp-ui/src/sdc-app/onboarding/userNotifications/NotificationsReducer.js new file mode 100644 index 0000000000..2c3442ee68 --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/userNotifications/NotificationsReducer.js @@ -0,0 +1,72 @@ +/*! + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +import {actionTypes} from './UserNotificationsConstants.js'; + +export default (state = {}, action) => { + switch (action.type) { + case actionTypes.NOTIFICATION: + let list = (state.notificationsList) ? state.notificationsList : []; + const {notifications, lastScanned} = action.data; + return { + ...state, + lastScanned, + notificationsList: [...notifications, ...list], + numOfNotSeenNotifications: state.numOfNotSeenNotifications + notifications.length + }; + case actionTypes.LOAD_NOTIFICATIONS: + return { + ...state, + ...action.result, + notificationsList: action.result.notifications, + notifications: undefined + }; + case actionTypes.LOAD_PREV_NOTIFICATIONS: + const {notifications: prevNotifications, endOfPage: newEndOfPage} = action.result; + return { + ...state, + notificationsList: [ + ...state.notificationsList, + ...prevNotifications + ], + endOfPage: newEndOfPage + }; + case actionTypes.UPDATE_READ_NOTIFICATION: + let {notificationForUpdate} = action; + notificationForUpdate = {...notificationForUpdate, read: true}; + const indexForEdit = state.notificationsList.findIndex(notification => notification.eventId === notificationForUpdate.eventId); + return { + ...state, + notificationsList: [ + ...state.notificationsList.slice(0, indexForEdit), + notificationForUpdate, + ...state.notificationsList.slice(indexForEdit + 1) + ] + }; + case actionTypes.RESET_NEW_NOTIFICATIONS: + return { + ...state, + numOfNotSeenNotifications: 0 + }; + case actionTypes.TOGGLE_OVERLAY: + return { + ...state, + showNotificationsOverlay: action.showNotificationsOverlay + }; + default: + return state; + } +}; diff --git a/openecomp-ui/src/sdc-app/onboarding/userNotifications/NotificationsView.jsx b/openecomp-ui/src/sdc-app/onboarding/userNotifications/NotificationsView.jsx new file mode 100644 index 0000000000..de105d23a7 --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/userNotifications/NotificationsView.jsx @@ -0,0 +1,106 @@ +/*! + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +import React from 'react'; +import PropTypes from 'prop-types'; +import enhanceWithClickOutside from 'react-click-outside'; +import classnames from 'classnames'; +import {connect} from 'react-redux'; +import SVGIcon from 'sdc-ui/lib/react/SVGIcon.js'; +import Overlay from 'nfvo-components/overlay/Overlay.jsx'; +import UserNotifications from 'sdc-app/onboarding/userNotifications/UserNotifications.jsx'; +import UserNotificationsActionHelper from 'sdc-app/onboarding/userNotifications/UserNotificationsActionHelper.js'; +import {actionTypes} from './UserNotificationsConstants.js'; +import OnboardingActionHelper from 'sdc-app/onboarding/OnboardingActionHelper.js'; + +const mapStateToProps = ({currentScreen, notifications, users: {usersList}}) => { + return {currentScreen, notifications, usersList}; +}; + +const mapActionToProps = (dispatch) => { + return { + resetNewNotifications: notificationId => UserNotificationsActionHelper.updateLastSeenNotification(dispatch, {notificationId}), + toggleOverlay: ({showNotificationsOverlay}) => dispatch({type: actionTypes.TOGGLE_OVERLAY, showNotificationsOverlay}), + onLoadPrevNotifications: (lastScanned, endOfPage) => UserNotificationsActionHelper.loadPreviousNotifications(dispatch, {lastScanned, endOfPage}), + onSync: ({itemId, itemName, versionId, versionName, currentScreen}) => UserNotificationsActionHelper.syncItem(dispatch, {itemId, itemName, versionId, versionName, currentScreen}), + updateNotification: notificationForUpdate => UserNotificationsActionHelper.updateNotification(dispatch, {notificationForUpdate}), + onLoadItemsLists: () => OnboardingActionHelper.loadItemsLists(dispatch) + }; +}; + + +class NotificationsView extends React.Component { + + static propTypes = { + currentScreen: PropTypes.object, + notifications: PropTypes.object, + resetNewNotifications: PropTypes.func, + toggleOverlay: PropTypes.func, + onLoadPrevNotifications: PropTypes.func, + onSync: PropTypes.func, + updateNotification: PropTypes.func, + onLoadItemsLists: PropTypes.func + }; + + render() { + const {usersList, notifications, onLoadPrevNotifications, onSync, updateNotification, onLoadItemsLists, currentScreen} = this.props; + const {notificationsList, numOfNotSeenNotifications, showNotificationsOverlay, lastScanned, endOfPage} = notifications; + + return ( + <div className='onboarding-notifications'> + <div className='notifications-icon' onClick={() => this.onNotificationIconClick()}> + <SVGIcon name={numOfNotSeenNotifications > 0 ? 'notificationFullBell' : 'notificationBell'} color={numOfNotSeenNotifications > 0 ? 'primary' : ''}/> + <div className={classnames('notifications-count', {'hidden-count': numOfNotSeenNotifications === 0})}> + {numOfNotSeenNotifications} + </div> + </div> + {showNotificationsOverlay && + <Overlay> + <UserNotifications notificationsList={notificationsList} usersList={usersList} lastScanned={lastScanned} endOfPage={endOfPage} + onLoadPrevNotifications={onLoadPrevNotifications} onSync={onSync} updateNotification={updateNotification} onLoadItemsLists={onLoadItemsLists} + currentScreen={currentScreen}/> + </Overlay> + } + </div> + ); + } + + handleClickOutside() { + const {notifications: {showNotificationsOverlay}} = this.props; + if(showNotificationsOverlay) { + this.onCloseOverlay(); + } + } + + onNotificationIconClick() { + const {notifications: {showNotificationsOverlay}, toggleOverlay} = this.props; + if (showNotificationsOverlay) { + this.onCloseOverlay(); + } else { + toggleOverlay({showNotificationsOverlay: true}); + } + } + + onCloseOverlay() { + const {notifications: {numOfNotSeenNotifications, lastScanned}, resetNewNotifications, toggleOverlay} = this.props; + if (numOfNotSeenNotifications) { + resetNewNotifications(lastScanned); + } + toggleOverlay({showNotificationsOverlay: false}); + } +} + +export default connect(mapStateToProps, mapActionToProps)(enhanceWithClickOutside(NotificationsView)); diff --git a/openecomp-ui/src/sdc-app/onboarding/userNotifications/UserNotifications.jsx b/openecomp-ui/src/sdc-app/onboarding/userNotifications/UserNotifications.jsx new file mode 100644 index 0000000000..c01424ee1b --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/userNotifications/UserNotifications.jsx @@ -0,0 +1,131 @@ +/*! + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +import React from 'react'; +import PropTypes from 'prop-types'; +import ReactDOM from 'react-dom'; +import classnames from 'classnames'; +import i18n from 'nfvo-utils/i18n/i18n.js'; +import {notificationType} from './UserNotificationsConstants.js'; +import ShowMore from 'react-show-more'; + +const Notification = ({notification, users, onActionClicked, getNotificationTypeDesc}) => { + const {eventType, read, eventAttributes, dateTime} = notification; + const {itemName, userId, description, versionName, permission, granted} = eventAttributes; + const {fullName: userName} = users.find(user => user.userId === userId); + return ( + <div className={classnames('notification', {'unread': !read})}> + <div className='notification-data'> + <div className='item-name'> + {itemName} + {versionName && <span> v{versionName}</span>} + {!read && <div className='unread-circle-icon'></div> } + </div> + <div className='flex-items'> + <div className='type'>{getNotificationTypeDesc(eventType, permission, granted)}</div> + <div className='separator'/> + <div className='user-name'>{`${i18n('By')} ${userName}`}</div> + </div> + {(description || versionName) && <div className='description'> + {description && <ShowMore anchorClass='more-less' lines={2} more={i18n('More')} less={i18n('Less')}> + {description} + </ShowMore>} + {eventType === notificationType.ITEM_CHANGED.SUBMIT && + <div> + <div>{i18n('Version {versionName} was submitted.', {versionName: versionName})}</div> + </div> + } + </div> + } + <div className='date'>{dateTime}</div> + </div> + <div className='notification-action'> + <div className={classnames('action-button', {'hidden': read})} onClick={() => onActionClicked(notification)}> + {eventType === notificationType.PERMISSION_CHANGED ? i18n('Accept') : i18n('Sync')} + </div> + </div> + </div> + ); +}; + +function getNotificationTypeDesc(eventType, permission, granted) { + switch (eventType) { + case notificationType.PERMISSION_CHANGED: + return i18n('Permission {granted}: {permission}', {granted: granted ? 'Granted' : 'Taken', permission: permission}); + case notificationType.ITEM_CHANGED.COMMIT: + return i18n('Your Copy Is Out Of Sync'); + case notificationType.ITEM_CHANGED.SUBMIT: + return i18n('Version Submitted'); + } +} + +class UserNotifications extends React.Component { + + static propTypes = { + currentScreen: PropTypes.object, + notificationsList: PropTypes.array, + usersList: PropTypes.array, + lastScanned: PropTypes.string, + endOfPage:PropTypes.string, + onLoadPrevNotifications: PropTypes.func, + onSync: PropTypes.func, + updateNotification: PropTypes.func, + onLoadItemsLists: PropTypes.func + }; + + render() { + const {notificationsList = [], usersList, lastScanned, endOfPage} = this.props; + + return ( + <div className='user-notifications'> + <div className='notifications-title'>{i18n('Notifications')}</div> + <div className='notifications-list' ref='notificationList' onScroll={() => this.loadPrevNotifications(lastScanned, endOfPage)}> + { + notificationsList.map(notification => ( + <Notification key={notification.eventId} notification={notification} users={usersList} + onActionClicked={notification => this.onActionClicked(notification)} + getNotificationTypeDesc={getNotificationTypeDesc}/>)) + } + </div> + </div> + ); + } + + onActionClicked(notification) { + const {onSync, updateNotification, currentScreen, onLoadItemsLists} = this.props; + const {eventType, eventAttributes: {itemId, itemName, versionId, versionName}} = notification; + if(eventType !== notificationType.PERMISSION_CHANGED) { + onSync({itemId, itemName, versionId, versionName, currentScreen}); + } + else { + onLoadItemsLists(); + } + updateNotification(notification); + } + + loadPrevNotifications(lastScanned, endOfPage) { + if(endOfPage && lastScanned) { + let element = ReactDOM.findDOMNode(this.refs['notificationList']); + const {onLoadPrevNotifications} = this.props; + + if (element && element.clientHeight + element.scrollTop === element.scrollHeight) { + onLoadPrevNotifications(lastScanned, endOfPage); + } + } + } +} + +export default UserNotifications; diff --git a/openecomp-ui/src/sdc-app/onboarding/userNotifications/UserNotificationsActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/userNotifications/UserNotificationsActionHelper.js new file mode 100644 index 0000000000..574aa0f3fc --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/userNotifications/UserNotificationsActionHelper.js @@ -0,0 +1,123 @@ +import {actionTypes} from './UserNotificationsConstants.js'; +import i18n from 'nfvo-utils/i18n/i18n.js'; +import Configuration from 'sdc-app/config/Configuration.js'; +import RestAPIUtil from 'nfvo-utils/RestAPIUtil.js'; +import WebSocketUtil, {websocketUrl} from 'nfvo-utils/WebSocketUtil.js'; +import {actionsEnum as VersionControllerActionsEnum} from 'nfvo-components/panel/versionController/VersionControllerConstants.js'; +import ItemsHelper from 'sdc-app/common/helpers/ItemsHelper.js'; +import ScreensHelper from 'sdc-app/common/helpers/ScreensHelper.js'; +import MergeEditorActionHelper from 'sdc-app/common/merge/MergeEditorActionHelper.js'; +import {actionTypes as modalActionTypes} from 'nfvo-components/modal/GlobalModalConstants.js'; +import {SyncStates} from 'sdc-app/common/merge/MergeEditorConstants.js'; + +function baseUrl() { + const restPrefix = Configuration.get('restPrefix'); + return `${restPrefix}/v1.0/notifications`; +} + +function fetch() { + return RestAPIUtil.fetch(baseUrl()); +} + +function updateNotification(notificationId) { + return RestAPIUtil.put(`${baseUrl()}/${notificationId}`); +} + +function updateLastSeenNotification(notificationId) { + return RestAPIUtil.put(`${baseUrl()}/last-seen/${notificationId}`); +} + +function loadPrevNotifications(lastScanned, endOfPage) { + return RestAPIUtil.fetch(`${baseUrl()}?LAST_DELIVERED_EVENT_ID=${lastScanned}&END_OF_PAGE_EVENT_ID=${endOfPage}`); +} + +const INITIAL_LAST_SCANNED = '00000000-0000-1000-8080-808080808080'; + +const UserNotificationsActionHelper = { + notificationsFirstHandling(dispatch) { + console.log('Websocket Url: ', websocketUrl); + UserNotificationsActionHelper.fetchUserNotificationsList(dispatch).then(({lastScanned}) => { + WebSocketUtil.open(websocketUrl, {lastScanned: lastScanned || INITIAL_LAST_SCANNED}); + }); + }, + + fetchUserNotificationsList(dispatch) { + return fetch().then(result => { + dispatch({ + type: actionTypes.LOAD_NOTIFICATIONS, + result + }); + return Promise.resolve({lastScanned: result.lastScanned}); + }); + }, + + loadPreviousNotifications(dispatch, {lastScanned, endOfPage}) { + loadPrevNotifications(lastScanned, endOfPage).then(result => dispatch({ + type: actionTypes.LOAD_PREV_NOTIFICATIONS, + result + })); + }, + + notifyAboutConflicts(dispatch, {itemId, itemName, version, currentScreen}) { + let {props} = currentScreen; + let currentItemId = props.softwareProductId || props.licenseModelId; + let currentVersion = props.version; + if(currentItemId === itemId && currentVersion.id === version.id) { + MergeEditorActionHelper.analyzeSyncResult(dispatch, {itemId, version}).then(() => ScreensHelper.loadScreen(dispatch, currentScreen)); + } + else { + dispatch({ + type: modalActionTypes.GLOBAL_MODAL_WARNING, + data: { + title: i18n('Conflicts'), + msg: i18n('There are conflicts in {itemName} version {versionName} that you have to resolve', {itemName: itemName.toUpperCase(), versionName: version.versionName}), + cancelButtonText: i18n('OK') + } + }); + } + }, + + syncItem(dispatch, {itemId, itemName, versionId, versionName, currentScreen}) { + let version = {id: versionId, versionName}; + ItemsHelper.fetchVersion({itemId, versionId}).then(response => { + let inMerge = response && response.state && response.state.synchronizationState === SyncStates.MERGE; + if (!inMerge) { + ItemsHelper.performVCAction({itemId, version, action: VersionControllerActionsEnum.SYNC}).then(() => { + return ItemsHelper.fetchVersion({itemId, versionId}).then(response => { + let inMerge = response && response.state && response.state.synchronizationState === SyncStates.MERGE; + if (!inMerge) { + return ScreensHelper.loadScreen(dispatch, currentScreen); + } + else { + return this.notifyAboutConflicts(dispatch, {itemId, itemName, version, currentScreen}); + } + }); + }); + } + else { + this.notifyAboutConflicts(dispatch, {itemId, itemName, version, currentScreen}); + } + }); + }, + + updateNotification(dispatch, {notificationForUpdate}) { + updateNotification(notificationForUpdate.eventId).then(response => { + if(response.status === 'Success' && Object.keys(response.errors).length === 0) { + dispatch({ + type: actionTypes.UPDATE_READ_NOTIFICATION, + notificationForUpdate + }); + } + }); + }, + + updateLastSeenNotification(dispatch, {notificationId}) { + updateLastSeenNotification(notificationId).then(response => { + if (response.status === 'Success' && Object.keys(response.errors).length === 0) { + dispatch({type: actionTypes.RESET_NEW_NOTIFICATIONS}); + } + }); + } +}; + +export default UserNotificationsActionHelper; diff --git a/openecomp-ui/src/sdc-app/onboarding/userNotifications/UserNotificationsConstants.js b/openecomp-ui/src/sdc-app/onboarding/userNotifications/UserNotificationsConstants.js new file mode 100644 index 0000000000..f006b5ae1b --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/userNotifications/UserNotificationsConstants.js @@ -0,0 +1,19 @@ + +import keyMirror from 'nfvo-utils/KeyMirror.js'; + +export const actionTypes = keyMirror({ + NOTIFICATION: null, + LOAD_NOTIFICATIONS: null, + LOAD_PREV_NOTIFICATIONS: null, + UPDATE_READ_NOTIFICATION: null, + RESET_NEW_NOTIFICATIONS: null, + TOGGLE_OVERLAY: null +}); + +export const notificationType = keyMirror({ + PERMISSION_CHANGED: 'PermissionChanged', + ITEM_CHANGED: { + COMMIT: 'commit', + SUBMIT: 'submit' + } +});
\ No newline at end of file diff --git a/openecomp-ui/src/sdc-app/onboarding/users/UsersActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/users/UsersActionHelper.js new file mode 100644 index 0000000000..8a9ff42238 --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/users/UsersActionHelper.js @@ -0,0 +1,61 @@ +/*! + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +import RestAPIUtil from 'nfvo-utils/RestAPIUtil.js'; +import Configuration from 'sdc-app/config/Configuration.js'; +import {actionTypes} from './UsersConstants.js'; + +function getUserId() { + let attApiHeaders = Configuration.get('ATTApiHeaders'); + let User = attApiHeaders && attApiHeaders.userId; + let userId = User && User.value ? User.value : ''; + return userId; +} + +function baseUrl() { + const restATTPrefix = Configuration.get('restATTPrefix'); + return `${restATTPrefix}`; +} + + +function fetchUsersList() { + const url = '/v1/user/users'; + return RestAPIUtil.fetch(`${baseUrl()}${url}`); +} + + + +const UsersActionHelper = { + fetchUsersList(dispatch) { + fetchUsersList().then(response => { + dispatch({ + type: actionTypes.USERS_LIST_LOADED, + usersList: response + }); + + let userId = getUserId(); + let userInfo = response.find(user => user.userId === userId); + dispatch({ + type: actionTypes.GOT_USER_INFO, + userInfo + }); + + }); + + } +}; + +export default UsersActionHelper; diff --git a/openecomp-ui/src/sdc-app/onboarding/users/UsersConstants.js b/openecomp-ui/src/sdc-app/onboarding/users/UsersConstants.js new file mode 100644 index 0000000000..fdcf4b179b --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/users/UsersConstants.js @@ -0,0 +1,22 @@ +/*! + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +import keyMirror from 'nfvo-utils/KeyMirror.js'; + +export const actionTypes = keyMirror({ + USERS_LIST_LOADED: null, + GOT_USER_INFO: null +}); diff --git a/openecomp-ui/src/sdc-app/onboarding/users/UsersReducers.js b/openecomp-ui/src/sdc-app/onboarding/users/UsersReducers.js new file mode 100644 index 0000000000..6bd72e3b3c --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/users/UsersReducers.js @@ -0,0 +1,42 @@ +/*! + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +import {actionTypes} from './UsersConstants.js'; +import {combineReducers} from 'redux'; + +function usersList (state = [], action) { + switch (action.type) { + case (actionTypes.USERS_LIST_LOADED): + return [...action.usersList]; + default: + return state; + } +}; + +function userInfo (state = {}, action) { + switch (action.type) { + case (actionTypes.GOT_USER_INFO): + return action.userInfo; + default: + return state; + } +} + + +export default combineReducers({ + usersList: usersList, + userInfo: userInfo +});
\ No newline at end of file diff --git a/openecomp-ui/src/sdc-app/onboarding/versionsPage/VersionsPage.js b/openecomp-ui/src/sdc-app/onboarding/versionsPage/VersionsPage.js new file mode 100644 index 0000000000..7b6f27307d --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/versionsPage/VersionsPage.js @@ -0,0 +1,87 @@ +/*! + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +import {connect} from 'react-redux'; +import VersionsPageActionHelper from './VersionsPageActionHelper.js'; +import VersionsPageCreationActionHelper from './creation/VersionsPageCreationActionHelper.js'; +import PermissionsActionHelper from '../permissions/PermissionsActionHelper.js'; +import {onboardingMethod as onboardingMethodType} from 'sdc-app/onboarding/softwareProduct/SoftwareProductConstants.js'; +import VersionsPageView from './VersionsPage.jsx'; + +export const mapStateToProps = ({ + users: {userInfo}, + versionsPage: {permissions, versionsList}, + currentScreen: {itemPermission: {isCollaborator}, props: {itemId}}, + softwareProductList = [] +}) => { + + let {versions, selectedVersion} = versionsList; + let {owner, contributors, viewers} = permissions; + + // sorting the version list + versions.sort((a,b) => { + let statusCompare = b.status.localeCompare(a.status); + if (statusCompare === 0) { + return b.modificationTime - a.modificationTime; + } else { + return statusCompare; + } + + }); + + const curentSoftwareProduct = softwareProductList.find(item => item.id === itemId); + return { + versions, + contributors, + viewers, + owner, + currentUser: userInfo, + selectedVersion, + isCollaborator, + isManual: curentSoftwareProduct && curentSoftwareProduct.onboardingMethod === onboardingMethodType.MANUAL + }; + +}; + +export const mapActionsToProps = (dispatch, {itemType, itemId, additionalProps}) => { + return { + onNavigateToVersion({version}) { + VersionsPageActionHelper.onNavigateToVersion(dispatch, {version, itemId, itemType, additionalProps}); + }, + + onSelectVersion({version}) { + VersionsPageActionHelper.selectVersion(dispatch, {version}); + }, + + onCreateVersion({version}) { + VersionsPageCreationActionHelper.open(dispatch, {baseVersion: version, itemId, itemType, additionalProps}); + }, + + onManagePermissions() { + PermissionsActionHelper.openPermissonsManager(dispatch, {itemId, askForRights: false}); + }, + + onTreeFullScreen(treeProps) { + VersionsPageActionHelper.openTree(dispatch, treeProps); + }, + + onModalNodeClick({version}) { + VersionsPageActionHelper.selectVersionFromModal(dispatch, {version}); + } + }; +}; + +export default connect(mapStateToProps, mapActionsToProps)(VersionsPageView); diff --git a/openecomp-ui/src/sdc-app/onboarding/versionsPage/VersionsPage.jsx b/openecomp-ui/src/sdc-app/onboarding/versionsPage/VersionsPage.jsx new file mode 100644 index 0000000000..69a34e0a1c --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/versionsPage/VersionsPage.jsx @@ -0,0 +1,77 @@ +/*! + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ +import React from 'react'; +import VersionList from './components/VersionList.jsx'; +import PermissionsView from './components/PermissionsView.jsx'; +import Tree from 'nfvo-components/tree/Tree.jsx'; +import SVGIcon from 'sdc-ui/lib/react/SVGIcon.js'; +import i18n from 'nfvo-utils/i18n/i18n.js'; + +class VersionsPage extends React.Component { + state = { + showExpanded : false + } + render() { + let { versions, owner, contributors, currentUser, isCollaborator, itemName = '', viewers, onSelectVersion, onNavigateToVersion, + onTreeFullScreen, onManagePermissions, onCreateVersion, selectedVersion, onModalNodeClick, isManual} = this.props; + return ( + <div className='versions-page-view'> + <div className='versions-page-title'>{i18n('Available Versions - {itemName}', {itemName: itemName})}</div> + <PermissionsView + owner={owner} + contributors={contributors} + viewers={viewers} + currentUser={currentUser} + isManual={isManual} + onManagePermissions={onManagePermissions}/> + <div className='versions-page-list-and-tree'> + <div className='version-tree-wrapper'> + <div className='version-tree-title-container'> + <div className='version-tree-title'>{i18n('Version Tree')}</div> + {this.state.showExpanded && <SVGIcon name='expand' className='version-tree-full-screen' onClick={() => onTreeFullScreen({ + name: 'versions-tree-popup', + width: 798, + height: 500, + nodes: versions.map(version => ({id: version.id, name: version.name, parent: version.baseId || ''})), + onNodeClick: (version) => onModalNodeClick({version}), + selectedNodeId: selectedVersion, + scrollable: true, + toWiden: true + })} />} + </div> + <Tree + name={'versions-tree'} + width={200} + allowScaleWidth={false} + nodes={versions.map(version => ({id: version.id, name: version.name, parent: version.baseId || ''}))} + onNodeClick={version => onSelectVersion({version})} + onRenderedBeyondWidth={() => {this.setState({showExpanded : true});}} + selectedNodeId={selectedVersion}/> + </div> + <VersionList + versions={versions} + onSelectVersion={onSelectVersion} + onNavigateToVersion={onNavigateToVersion} + onCreateVersion={onCreateVersion} + selectedVersion={selectedVersion} + isCollaborator={isCollaborator} /> + </div> + </div> + ); + } +} + +export default VersionsPage; diff --git a/openecomp-ui/src/sdc-app/onboarding/versionsPage/VersionsPageActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/versionsPage/VersionsPageActionHelper.js new file mode 100644 index 0000000000..52868293e2 --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/versionsPage/VersionsPageActionHelper.js @@ -0,0 +1,90 @@ +/*! + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ +import ItemsHelper from '../../common/helpers/ItemsHelper.js'; +import {actionTypes} from './VersionsPageConstants.js'; +import {itemTypes} from './VersionsPageConstants.js'; +import {modalContentMapper} from 'sdc-app/common/modal/ModalContentMapper.js'; +import {actionTypes as modalActionTypes} from 'nfvo-components/modal/GlobalModalConstants.js'; +import i18n from 'nfvo-utils/i18n/i18n.js'; +import ScreensHelper from 'sdc-app/common/helpers/ScreensHelper.js'; +import {enums, screenTypes} from 'sdc-app/onboarding/OnboardingConstants.js'; + + +const VersionsPageActionHelper = { + fetchVersions(dispatch, {itemType, itemId}) { + return ItemsHelper.fetchVersions({itemId}).then(response => { + dispatch({ + type: actionTypes.VERSIONS_LOADED, + versions: response.results, + itemType, + itemId + }); + }); + }, + + selectVersion(dispatch, {version}) { + dispatch({ + type: actionTypes.SELECT_VERSION, + versionId: version.id + }); + }, + + selectNone(dispatch) { + dispatch({ type: actionTypes.SELECT_NONE }); + }, + + onNavigateToVersion(dispatch, {version, itemId, itemType}) { + switch (itemType) { + case itemTypes.LICENSE_MODEL: + ScreensHelper.loadScreen(dispatch, { + screen: enums.SCREEN.LICENSE_MODEL_OVERVIEW, screenType: screenTypes.LICENSE_MODEL, + props: {licenseModelId: itemId, version} + }); + break; + case itemTypes.SOFTWARE_PRODUCT: + ScreensHelper.loadScreen(dispatch, { + screen: enums.SCREEN.SOFTWARE_PRODUCT_LANDING_PAGE, screenType: screenTypes.SOFTWARE_PRODUCT, + props: {softwareProductId: itemId, version} + }); + break; + } + }, + + openTree(dispatch, treeProps) { + dispatch({ + type: modalActionTypes.GLOBAL_MODAL_SHOW, + data: { + modalComponentName: modalContentMapper.VERSION_TREE, + modalComponentProps: treeProps, + onDeclined: () => dispatch({ + type: modalActionTypes.GLOBAL_MODAL_CLOSE + }), + modalClassName: 'versions-tree-modal', + cancelButtonText: i18n('Close'), + title: i18n('Version Tree') + } + }); + }, + + selectVersionFromModal(dispatch, {version}) { + dispatch({ + type: modalActionTypes.GLOBAL_MODAL_CLOSE + }); + this.selectVersion(dispatch, {version}); + } +}; + +export default VersionsPageActionHelper; diff --git a/openecomp-ui/src/sdc-app/onboarding/versionsPage/VersionsPageConstants.js b/openecomp-ui/src/sdc-app/onboarding/versionsPage/VersionsPageConstants.js new file mode 100644 index 0000000000..983ab79a14 --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/versionsPage/VersionsPageConstants.js @@ -0,0 +1,27 @@ +/*! + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ +import keyMirror from 'nfvo-utils/KeyMirror.js'; + +export const actionTypes = keyMirror({ + VERSIONS_LOADED: null, + SELECT_VERSION: null, + SELECT_NONE: null +}); + +export const itemTypes = { + LICENSE_MODEL: 'vendor-license-models', + SOFTWARE_PRODUCT: 'vendor-software-products' +}; diff --git a/openecomp-ui/src/sdc-app/onboarding/versionsPage/VersionsPageReducer.js b/openecomp-ui/src/sdc-app/onboarding/versionsPage/VersionsPageReducer.js new file mode 100644 index 0000000000..9b6fa9f803 --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/versionsPage/VersionsPageReducer.js @@ -0,0 +1,42 @@ +/*! + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ +import {actionTypes} from './VersionsPageConstants.js'; +import {combineReducers} from 'redux'; +import VersionsPageCreationReducer from './creation/VersionsPageCreationReducer.js'; +import PermissionsReducer from '../permissions/PermissionsReducer.js'; +import {createPlainDataReducer} from 'sdc-app/common/reducers/PlainDataReducer.js'; + +function VersionsListReducer(state = {}, action) { + switch (action.type) { + case actionTypes.VERSIONS_LOADED: + let {versions, itemType = state.itemType, itemId} = action; + return {...state, versions, itemType, itemId}; + case actionTypes.SELECT_VERSION: + return {...state, selectedVersion: action.versionId === state.selectedVersion ? null : action.versionId}; + case actionTypes.SELECT_NONE: + return {...state, selectedVersion: null}; + default: + return state; + } +}; + + + +export default combineReducers({ + versionCreation: createPlainDataReducer(VersionsPageCreationReducer), + versionsList: VersionsListReducer, + permissions: PermissionsReducer +}); diff --git a/openecomp-ui/src/sdc-app/onboarding/versionsPage/components/PermissionsView.jsx b/openecomp-ui/src/sdc-app/onboarding/versionsPage/components/PermissionsView.jsx new file mode 100644 index 0000000000..26f8450f4c --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/versionsPage/components/PermissionsView.jsx @@ -0,0 +1,82 @@ +/*! + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +import React from 'react'; +import i18n from 'nfvo-utils/i18n/i18n.js'; +import SVGIcon from 'sdc-ui/lib/react/SVGIcon.js'; +import OverlayTrigger from 'react-bootstrap/lib/OverlayTrigger.js'; +import Tooltip from 'react-bootstrap/lib/Tooltip.js'; + +const maxContributors = 6; + +function extraUsersTooltip (extraUsers) { + return ( + <Tooltip className='extra-users-tooltip' id='extra-users-tooltip-id'> + {extraUsers.map(extraUser => <div key={extraUser.userId} className='extra-user'>{extraUser.fullName}</div>)} + </Tooltip> + ); +} + +const User = ({user, isCurrentUser, dataTestId}) => ( + <SVGIcon className={`user-view ${isCurrentUser ? 'current-user' : ''}`} name='user' label={user.fullName} labelPosition='right' color='primary' + data-test-id={dataTestId}/> +); + +const Owner = ({owner, isCurrentUser}) => ( + <div className='owner-view'> + <div className='permissions-view-title'>{i18n('Owner')}</div> + <User user={owner} isCurrentUser={isCurrentUser} dataTestId='owner'/> + </div> +); + +const Contributors = ({contributors, owner, currentUser, onManagePermissions, isManual}) => { + let extraUsers = contributors.length - maxContributors; + return ( + <div className='contributors-view'> + <div className='permissions-view-title'>{i18n('Contributors')}</div> + {contributors.slice(0, maxContributors).map(contributor => + <User key={contributor.userId} user={contributor} isCurrentUser={contributor.userId === currentUser.userId} dataTestId='contributor'/> + )} + {extraUsers > 0 && + <OverlayTrigger placement='bottom' overlay={extraUsersTooltip(contributors.slice(maxContributors))}> + <div className='extra-contributors'>{`+${extraUsers}`}</div> + </OverlayTrigger> + } + {currentUser.userId === owner.userId && !isManual && + <span + className='manage-permissions' + onClick={onManagePermissions} + data-test-id='versions-page-manage-permissions'> + {i18n('Manage Permissions')} + </span> + } + </div> + ); +}; + +const PermissionsView = ({owner, contributors, currentUser = {}, onManagePermissions, isManual}) => ( + <div className='versions-page-permissions-view-wrapper'> + <div className='permissions-view-wrapper-title'>{i18n('Permissions')}</div> + <div className='permissions-view-content'> + <div className='permissions-view'> + <Owner owner={owner} isCurrentUser={owner.userId === currentUser.userId} /> + <Contributors owner={owner} contributors={contributors} currentUser={currentUser} onManagePermissions={onManagePermissions} isManual={isManual}/> + </div> + </div> + </div> +); + +export default PermissionsView; diff --git a/openecomp-ui/src/sdc-app/onboarding/versionsPage/components/VersionList.jsx b/openecomp-ui/src/sdc-app/onboarding/versionsPage/components/VersionList.jsx new file mode 100644 index 0000000000..f209d80125 --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/versionsPage/components/VersionList.jsx @@ -0,0 +1,129 @@ +/*! + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +import React from 'react'; +import OverlayTrigger from 'react-bootstrap/lib/OverlayTrigger.js'; +import Tooltip from 'react-bootstrap/lib/Tooltip.js'; +import i18n from 'nfvo-utils/i18n/i18n.js'; +import SVGIcon from 'sdc-ui/lib/react/SVGIcon.js'; + +const formatTime = (time) => { + if (!time) { return ''; } + + const date = new Date(time); + const options = { + year: 'numeric', + month: 'short', + day: 'numeric', + hour: '2-digit', + minute: '2-digit' + }; + const newDate = date.toLocaleTimeString('en-US', options); + + return newDate; +}; + +const DescriptionField = ({ className, text, useTooltip }) => { + if (useTooltip) { + return ( + <div className={className}> + <OverlayTrigger + placement='bottom' + overlay={<Tooltip className='version-description-tooltip' id='version-description-tooltip'>{text}</Tooltip>}> + <div className='description-text'>{text}</div> + </OverlayTrigger> + </div> + ); + } + return <div className={className}>{text}</div>; +}; + +const VersionListItem = ({ data, onSelectVersion, onNavigateToVersion, onCreateVersion, isHeader, isSelected, isCollaborator }) => { + + let {modificationTime, name, status, description, additionalInfo} = data; + const modificationText = !isHeader ? formatTime(modificationTime) : i18n('Last Edited On'); + + return ( + <div + data-test-id='version-item-row' + className={`version-item-row ${isHeader ? 'header-row' : 'clickable'} ${isSelected ? 'selected' : ''}`} + onClick={e => { + e.stopPropagation(); + onSelectVersion(); + onNavigateToVersion(); + }}> + <div className={`version-item-field ${isHeader ? 'header-field item-version' : 'item-version'}`}>{name}</div> + <div className={`version-item-field ${isHeader ? 'header-field item-status' : 'item-status'}`}>{status}</div> + <div className={`version-item-field ${isHeader ? 'header-field' : 'item-last-edited'}`}>{modificationText}</div> + <DescriptionField + className={`version-item-field ${isHeader ? 'header-field header-description' : 'item-description'}`} + useTooltip={!isHeader && description} + text={description} /> + + { + isHeader ? + <div className='version-item-field header-field actions'>{i18n('Actions')}</div> + : + <div className='version-item-field item-actions'> + <div className='version-item-field item-select'> + <SVGIcon + name='check-circle' + data-test-id='versions-page-select-version' + onClick={e => {e.stopPropagation(); onNavigateToVersion();}} + label={i18n('Go to this Version')} + labelPosition='right' /> + </div> + <div className='version-item-field item-create'> + {!isHeader && isCollaborator && additionalInfo.OptionalCreationMethods.length > 0 && + <SVGIcon + name='plus-circle' + data-test-id='versions-page-create-version' + onClick={e => { e.stopPropagation(); onCreateVersion(); }} + label={i18n('Create New Version')} + labelPosition='right' + disabled={!isCollaborator} /> + } + </div> + </div> + } + + + </div> + ); + +}; + +const VersionList = ({ versions, onSelectVersion, onNavigateToVersion, onCreateVersion, selectedVersion, isCollaborator }) => ( + <div className='version-list'> + <VersionListItem + data={{ name: i18n('Version'), status: i18n('Status'), description: i18n('Description') }} + isHeader /> + <div className='version-list-items'> + {versions.map(version => + <VersionListItem + key={version.id} + data={version} + onSelectVersion={() => onSelectVersion({version})} + onNavigateToVersion={() => onNavigateToVersion({version})} + onCreateVersion={() => onCreateVersion({version})} + isSelected={selectedVersion === version.id} + isCollaborator={isCollaborator} /> + )} + </div> + </div> +); + +export default VersionList; diff --git a/openecomp-ui/src/sdc-app/onboarding/versionsPage/creation/VersionsPageCreation.js b/openecomp-ui/src/sdc-app/onboarding/versionsPage/creation/VersionsPageCreation.js new file mode 100644 index 0000000000..66c1c79be5 --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/versionsPage/creation/VersionsPageCreation.js @@ -0,0 +1,44 @@ +/*! + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ +import {connect} from 'react-redux'; +import VersionsPageCreationActionHelper from './VersionsPageCreationActionHelper.js'; +import VersionsPageActionHelper from '../VersionsPageActionHelper.js'; +import VersionsPageCreationView from './VersionsPageCreationView.jsx'; +import ValidationHelper from 'sdc-app/common/helpers/ValidationHelper.js'; +import {VERSION_CREATION_FORM_NAME} from './VersionsPageCreationConstants.js'; + +export const mapStateToProps = ({versionsPage: {versionCreation}}) => { + let {genericFieldInfo} = versionCreation; + let isFormValid = ValidationHelper.checkFormValid(genericFieldInfo); + + return {...versionCreation, isFormValid}; +}; + +export const mapActionsToProps = (dispatch, {itemId, itemType, additionalProps}) => { + return { + onDataChanged: (deltaData, customValidations) => ValidationHelper.dataChanged(dispatch, {deltaData, formName: VERSION_CREATION_FORM_NAME, customValidations}), + onCancel: () => VersionsPageCreationActionHelper.close(dispatch), + onSubmit: ({baseVersion, payload}) => { + VersionsPageCreationActionHelper.close(dispatch); + VersionsPageCreationActionHelper.createVersion(dispatch, {baseVersion, itemId, payload}).then(response => { + VersionsPageActionHelper.onNavigateToVersion(dispatch, {version: response, itemId, itemType, additionalProps}); + }); + }, + onValidateForm: () => ValidationHelper.validateForm(dispatch, VERSION_CREATION_FORM_NAME) + }; +}; + +export default connect(mapStateToProps, mapActionsToProps)(VersionsPageCreationView); diff --git a/openecomp-ui/src/sdc-app/onboarding/versionsPage/creation/VersionsPageCreationActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/versionsPage/creation/VersionsPageCreationActionHelper.js new file mode 100644 index 0000000000..bc038689a4 --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/versionsPage/creation/VersionsPageCreationActionHelper.js @@ -0,0 +1,79 @@ +/*! + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ +import RestAPIUtil from 'nfvo-utils/RestAPIUtil.js'; +import Configuration from 'sdc-app/config/Configuration.js'; +import {actionTypes} from './VersionsPageCreationConstants.js'; +import {modalContentMapper} from 'sdc-app/common/modal/ModalContentMapper.js'; +import {actionTypes as modalActionTypes} from 'nfvo-components/modal/GlobalModalConstants.js'; +import i18n from 'nfvo-utils/i18n/i18n.js'; +import ItemsHelper from 'sdc-app/common/helpers/ItemsHelper.js'; +import {actionTypes as VersionsPageActionTypes} from '../VersionsPageConstants.js'; + +function baseUrl({itemId, baseVersion}) { + const restPrefix = Configuration.get('restPrefix'); + return `${restPrefix}/v1.0/items/${itemId}/versions/${baseVersion.id}/`; +} + +function createVersion({itemId, baseVersion, payload: {description, creationMethod} }) { + return RestAPIUtil.post(baseUrl({itemId, baseVersion}), {description, creationMethod}); +} + + +export default { + + open(dispatch, {itemType, itemId, additionalProps, baseVersion}) { + dispatch({ + type: actionTypes.OPEN + }); + + dispatch({ + type: modalActionTypes.GLOBAL_MODAL_SHOW, + data: { + modalComponentName: modalContentMapper.VERSION_CREATION, + modalComponentProps: {itemType, itemId, additionalProps, baseVersion}, + title: i18n('New Version - From {name}', {name: baseVersion.name}) + } + }); + }, + + close(dispatch){ + dispatch({ + type: actionTypes.CLOSE + }); + + dispatch({ + type: modalActionTypes.GLOBAL_MODAL_CLOSE + }); + }, + + createVersion(dispatch, {itemId, baseVersion, payload}){ + return createVersion({itemId, baseVersion, payload}).then(result => { + return ItemsHelper.fetchVersions({itemId}).then(response => { + dispatch({ + type: VersionsPageActionTypes.VERSIONS_LOADED, + versions: response.results, + itemId + }); + dispatch({ + type: actionTypes.VERSION_CREATED, + result + }); + return result; + }); + }); + } + +}; diff --git a/openecomp-ui/src/sdc-app/onboarding/versionsPage/creation/VersionsPageCreationConstants.js b/openecomp-ui/src/sdc-app/onboarding/versionsPage/creation/VersionsPageCreationConstants.js new file mode 100644 index 0000000000..4ce381d4de --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/versionsPage/creation/VersionsPageCreationConstants.js @@ -0,0 +1,28 @@ +/*! + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ +import keyMirror from 'nfvo-utils/KeyMirror.js'; + +export const actionTypes = keyMirror({ + OPEN: null, + CLOSE: null, + VERSION_CREATED: null +}); + +export const VERSION_CREATION_FORM_NAME = 'VCREATIONFORM'; + +export const defaultState = { + creationMethod: 'major' +};
\ No newline at end of file diff --git a/openecomp-ui/src/sdc-app/onboarding/versionsPage/creation/VersionsPageCreationReducer.js b/openecomp-ui/src/sdc-app/onboarding/versionsPage/creation/VersionsPageCreationReducer.js new file mode 100644 index 0000000000..620cf4717f --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/versionsPage/creation/VersionsPageCreationReducer.js @@ -0,0 +1,44 @@ +/*! + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ +import {actionTypes, VERSION_CREATION_FORM_NAME, defaultState} from './VersionsPageCreationConstants.js'; + +export default (state = {}, action) => { + switch (action.type) { + case actionTypes.OPEN: + return { + ...state, + formReady: null, + formName: VERSION_CREATION_FORM_NAME, + data: {...defaultState}, + genericFieldInfo: { + description: { + isValid: true, + errorText: '', + validations: [{type: 'required', data: true}, {type: 'maxLength', data: 120}] + }, + creationMethod: { + isValid: true, + errorText: '', + validations: [{type: 'required', data: true}] + } + } + }; + case actionTypes.CLOSE: + return {}; + default: + return state; + } +}; diff --git a/openecomp-ui/src/sdc-app/onboarding/versionsPage/creation/VersionsPageCreationView.jsx b/openecomp-ui/src/sdc-app/onboarding/versionsPage/creation/VersionsPageCreationView.jsx new file mode 100644 index 0000000000..caa85fe107 --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/versionsPage/creation/VersionsPageCreationView.jsx @@ -0,0 +1,249 @@ +/*! + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ +import React from 'react'; +import PropTypes from 'prop-types'; +import i18n from 'nfvo-utils/i18n/i18n.js'; +import Input from 'nfvo-components/input/validation/Input.jsx'; +import Form from 'nfvo-components/input/validation/Form.jsx'; + +const VersionPropType = PropTypes.shape({ + name: PropTypes.string, + description: PropTypes.string, + creationMethod: PropTypes.string +}); + +class VersionsPageCreationView extends React.Component { + + static propTypes = { + data: VersionPropType, + availableMethods: PropTypes.array, + onDataChanged: PropTypes.func.isRequired, + onSubmit: PropTypes.func.isRequired, + onCancel: PropTypes.func.isRequired + }; + + render() { + let {data = {}, genericFieldInfo, baseVersion, onDataChanged, onCancel} = this.props; + let {additionalInfo: {OptionalCreationMethods}} = baseVersion; + let {description, creationMethod} = data; + + return ( + <div className='version-creation-page'> + { genericFieldInfo && <Form + ref={(validationForm) => this.validationForm = validationForm} + hasButtons={true} + onSubmit={() => this.submit()} + submitButtonText={i18n('Create')} + onReset={() => onCancel()} + labledButtons={true} + isValid={this.props.isFormValid} + formReady={this.props.formReady} + onValidateForm={() => this.validate()}> + + <div className='version-form-row'> + <Input + label={i18n('Version Category')} + value={creationMethod} + onChange={e => this.onSelectMethod(e)} + type='select' + overlayPos='bottom' + data-test-id='new-version-category' + isValid={genericFieldInfo.creationMethod.isValid} + errorText={genericFieldInfo.creationMethod.errorText} + isRequired> + <option key='' value=''>{i18n('Please select…')}</option> + {OptionalCreationMethods.map(method => <option key={method} value={method}>{i18n(method)}</option>)} + </Input> + </div> + + <div className='version-form-row'> + <Input + label={i18n('Description')} + value={description} + type='text' + overlayPos='bottom' + data-test-id='new-version-description' + isValid={genericFieldInfo.description.isValid} + errorText={genericFieldInfo.description.errorText} + onChange={description => onDataChanged({description})} + isRequired /> + </div> + + </Form> } + </div> + ); + } + + onSelectMethod(e) { + const selectedIndex = e.target.selectedIndex; + const creationMethod = e.target.options[selectedIndex].value; + this.props.onDataChanged({creationMethod}); + } + + submit() { + let {baseVersion, data: {description, creationMethod}} = this.props; + this.props.onSubmit({baseVersion, payload: {description, creationMethod}}); + } + + validate() { + this.props.onValidateForm(); + } + +} + +export default VersionsPageCreationView; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +/* + <div className='software-product-inline-section'> + <Input + value={name} + label={i18n('Name')} + isRequired={true} + onChange={name => onDataChanged({name},V_CREATION_FORM_NAME, {name: name => this.validateName(name)})} + isValid={genericFieldInfo.name.isValid} + errorText={genericFieldInfo.name.errorText} + type='text' + className='field-section' + data-test-id='new-vsp-name' /> + <Input + label={i18n('Vendor')} + type='select' + 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} + 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 && + <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> + </div> + <div className='software-product-inline-section'> + <Input + value={description} + label={i18n('Description')} + isRequired={true} + overlayPos='bottom' + onChange={description => onDataChanged({description},V_CREATION_FORM_NAME)} + isValid={genericFieldInfo.description.isValid} + errorText={genericFieldInfo.description.errorText} + type='textarea' + className='field-section' + data-test-id='new-vsp-description' /> + </div> + </div> + </Form>} + </div> + ); + } + + getAvailableMethodsList() { + let {availableMethods} = this.props; + return [...availableMethods]; + } + + onSelectVendor(e) { + const selectedIndex = e.target.selectedIndex; + const vendorId = e.target.options[selectedIndex].value; + this.props.onDataChanged({vendorId},V_CREATION_FORM_NAME); + } + + onSelectSubCategory(e) { + const selectedIndex = e.target.selectedIndex; + const subCategory = e.target.options[selectedIndex].value; + let {softwareProductCategories, onDataChanged} = this.props; + let category = SoftwareProductCategoriesHelper.getCurrentCategoryOfSubCategory(subCategory, softwareProductCategories); + onDataChanged({category, subCategory},V_CREATION_FORM_NAME); + } + + submit() { + let {data:softwareProduct, finalizedLicenseModelList} = this.props; + softwareProduct.vendorName = finalizedLicenseModelList.find(vendor => vendor.id === softwareProduct.vendorId).name; + this.props.onSubmit(softwareProduct); + } + + validateName(value) { + const {data: {id}, VSPNames} = this.props; + const isExists = Validator.isItemNameAlreadyExistsInList({itemId: id, itemName: value, list: VSPNames}); + + return !isExists ? {isValid: true, errorText: ''} : + {isValid: false, errorText: i18n('Software product by the name \'' + value + '\' already exists. Software product name must be unique')}; + } + + validate() { + this.props.onValidateForm(SP_CREATION_FORM_NAME); + } +} + +export default SoftwareProductCreationView; +*/ diff --git a/openecomp-ui/test-utils/MockRest.js b/openecomp-ui/test-utils/MockRest.js index c49d53d984..6cc676a2bb 100644 --- a/openecomp-ui/test-utils/MockRest.js +++ b/openecomp-ui/test-utils/MockRest.js @@ -76,5 +76,19 @@ export default { resetQueue() { initQueue(); + }, + + checkEmptyQueue() { + let isEmpty = true; + let message = 'Check following calls: '; + for (let operationType in queue) { + if (queue[operationType].length > 0) { + isEmpty = false; + message += operationType; + } + } + if (!isEmpty) { + throw new Error('Queue is not empty, ' + message); + } } }; diff --git a/openecomp-ui/test-utils/ShowMore.js b/openecomp-ui/test-utils/ShowMore.js new file mode 100644 index 0000000000..a01ae6a5c9 --- /dev/null +++ b/openecomp-ui/test-utils/ShowMore.js @@ -0,0 +1,10 @@ +import React from 'react'; + +const ShowMore = ({children}) => { + if (children.length > 50) { + return (<div>Show Message With More Mock</div>); + } else { + return (<div>Show Message Mock</div>); + } +}; +export default ShowMore;
\ No newline at end of file diff --git a/openecomp-ui/test-utils/factories/common/CurrentScreenFactory.js b/openecomp-ui/test-utils/factories/common/CurrentScreenFactory.js new file mode 100644 index 0000000000..8301a277cf --- /dev/null +++ b/openecomp-ui/test-utils/factories/common/CurrentScreenFactory.js @@ -0,0 +1,100 @@ +/*! + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ +import {Factory} from 'rosie'; +import randomstring from 'randomstring'; +import VersionFactory from './VersionFactory.js'; + +export const InitializedItemPermissionFactory = new Factory() + .attrs({ + 'isCertified': false, + 'inMerge': false, + 'isCollaborator': true + }); + +export const ItemPermissionFactory = new Factory() + .extend(InitializedItemPermissionFactory) + .attrs({ + 'isDirty': false, + 'isOutOfSync': false, + 'isUpToDate': true + }); + + +export const CurrentScreenPropsFactory = new Factory() + .option('versionId', () => randomstring.generate()) + .option('versionBaseId', () => randomstring.generate()) + .attrs({ + softwareProductId: () => randomstring.generate(), + licenseModelId: () => randomstring.generate(), + isReadOnlyMode: false + }) + .attr('version', [ + 'versionId', 'versionBaseId' + ], (id, baseId) => + VersionFactory.build({id, baseId}) + ); + + +Factory.define('InitializedCurrentScreenFactory') + .option('isCertified', false) + .option('inMerge', false) + .option('isCollaborator', true) + .option('isReadOnlyMode', ['isCertified', 'inMerge', 'isCollaborator'], (isCertified, inMerge, isCollaborator) => + isCertified || inMerge || !isCollaborator + ) + .attr('itemPermission', ['isCertified', 'inMerge', 'isCollaborator'], (isCertified, inMerge, isCollaborator) => + InitializedItemPermissionFactory.build({isCollaborator, isCertified, inMerge}) + ) + .attr('props', ['isReadOnlyMode'], (isReadOnlyMode) => { + return {isReadOnlyMode}; + }); +export const InitializedCurrentScreenFactory = new Factory().extend('InitializedCurrentScreenFactory'); + + +Factory.define('CurrentScreenFactory') + .extend('InitializedCurrentScreenFactory') + .option('isDirty', false) + .option('isOutOfSync', false) + .option('isUpToDate', true) + .option('version', ['isCertified'], (isCertified) => VersionFactory.build({isCertified})) + .attr('itemPermission', [ + 'isCertified', 'inMerge', 'isCollaborator', 'isDirty', 'isOutOfSync', 'isUpToDate' + ], (isCertified, inMerge, isCollaborator, isDirty, isOutOfSync, isUpToDate) => + ItemPermissionFactory.build({isCollaborator, isCertified, inMerge, isDirty, isOutOfSync, isUpToDate}) + ) + .attr('props', ['isReadOnlyMode', 'version'], (isReadOnlyMode, version) => { + return {isReadOnlyMode, version}; + }); +export default new Factory().extend('CurrentScreenFactory'); + + +export const CurrentScreenFactoryWithProps = new Factory() + .extend('CurrentScreenFactory') + .option('versionId') + .option('versionBaseId') + .option('version') + .attr('props', [ + 'isReadOnlyMode', 'versionId', 'versionBaseId', 'version' + ], (isReadOnlyMode, id, baseId, version) => { + let attrs = {isReadOnlyMode}; + let options = {}; + + if (version !== undefined) { attrs['version'] = version; } + if (id !== undefined) { options['versionId'] = id; } + if (baseId !== undefined) { options['versionBaseId'] = baseId; } + + return CurrentScreenPropsFactory.build(attrs, options); + }); diff --git a/openecomp-ui/test-utils/factories/common/VersionFactory.js b/openecomp-ui/test-utils/factories/common/VersionFactory.js new file mode 100644 index 0000000000..66db6d6075 --- /dev/null +++ b/openecomp-ui/test-utils/factories/common/VersionFactory.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 {Factory} from 'rosie'; +import randomstring from 'randomstring'; +import IdMixin from '../mixins/IdMixin.js'; + +export default new Factory() + .extend(IdMixin) + .option('isCertified', false) + .attrs({ + baseId: () => randomstring.generate(), + description: () => randomstring.generate(), + name: () => randomstring.generate(), + creationTime: () => new Date().getTime(), + modificationTime: () => new Date().getTime(), + additionalInfo: () => { return {OptionalCreationMethods: ['major', 'minor']}; } + }) + .attr('status', ['isCertified'], (isCertified) => {return isCertified ? 'Certified' : 'Draft'; }); diff --git a/openecomp-ui/test-utils/factories/licenseModel/LicenseModelFactories.js b/openecomp-ui/test-utils/factories/licenseModel/LicenseModelFactories.js index 716eb15559..7cda105ff7 100644 --- a/openecomp-ui/test-utils/factories/licenseModel/LicenseModelFactories.js +++ b/openecomp-ui/test-utils/factories/licenseModel/LicenseModelFactories.js @@ -17,7 +17,6 @@ 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({ @@ -29,7 +28,7 @@ Factory.define('LicenseModelBaseFactory') export const LicenseModelCreationFactory = new Factory() .attrs({ data: { - vendorName: () => randomstring.generate(), + name: () => randomstring.generate(), description: () => randomstring.generate() } }); @@ -48,13 +47,8 @@ export const LicenseModelStoreFactory = new Factory() 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'}] + name: randomstring.generate(), + description: randomstring.generate() }); export const LicenseModelOverviewFactory = new Factory() @@ -62,8 +56,10 @@ export const LicenseModelOverviewFactory = new Factory() licenseModelEditor: { data: { ...Factory.attributes('LicenseModelBaseFactory'), - id: () => Math.floor(Math.random() * (1000 - 1) + 1), - ...VersionControllerUtilsFactory.build() + id: () => Math.floor(Math.random() * 1000 + 1), + version: { + id: Math.floor(Math.random() * 1000 + 1) + } } }, entitlementPool: {}, diff --git a/openecomp-ui/test-utils/factories/revisions/RevisionsFactories.js b/openecomp-ui/test-utils/factories/revisions/RevisionsFactories.js new file mode 100644 index 0000000000..57c5e70e68 --- /dev/null +++ b/openecomp-ui/test-utils/factories/revisions/RevisionsFactories.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 randomstring from 'randomstring'; +import IdMixin from 'test-utils/factories/mixins/IdMixin.js'; + + +export const RevisionsPagePropsFactory = new Factory() + .sequence('user') + .attr('message', 'message') + .attr('date', new Date().getTime()) + .extend(IdMixin).after(function(revisions) { + let longMessage = revisions.user % 2; + revisions.user = 'Carlos Santana'; + revisions.message = (longMessage) ? randomstring.generate(60) : randomstring.generate(10); + }); diff --git a/openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductComponentsMonitoringFactories.js b/openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductComponentsMonitoringFactories.js index 550e1a6d6c..8cb2221bea 100644 --- a/openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductComponentsMonitoringFactories.js +++ b/openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductComponentsMonitoringFactories.js @@ -26,13 +26,10 @@ export const VSPComponentsMonitoringRestFactory = new Factory() .option('createPoll', false) .option('createVes', false) - .attr(trap, ['createTrap'], (createTrap) => {return (createTrap) ? randomstring.generate() : undefined}) - .attr(poll, ['createPoll'], (createPoll) => {return (createPoll) ? randomstring.generate() : undefined}) - .attr(ves, ['createVes'], (createVes) => {return (createVes) ? randomstring.generate() : undefined}); + .attr(trap, ['createTrap'], (createTrap) => createTrap ? randomstring.generate() : undefined) + .attr(poll, ['createPoll'], (createPoll) => createPoll ? randomstring.generate() : undefined) + .attr(ves, ['createVes'], (createVes) => createVes ? randomstring.generate() : undefined); export const VSPComponentsMonitoringViewFactory = new Factory() .extend(VSPComponentsMonitoringRestFactory); -// .after(monitoring => { - -// }); diff --git a/openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductDependenciesFactories.js b/openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductDependenciesFactories.js index 6521c58a35..fab3f5f79e 100644 --- a/openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductDependenciesFactories.js +++ b/openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductDependenciesFactories.js @@ -23,10 +23,10 @@ const SoftwareProductDependenciesBaseFactory = new Factory() .attrs({ sourceId: () => randomstring.generate(), targetId: () => randomstring.generate(), relationType: relationTypes.DEPENDS_ON - }); + }).extend(IdMixin); export const SoftwareProductDependenciesResponseFactory = new Factory() - .extend(SoftwareProductDependenciesBaseFactory); + .extend(SoftwareProductDependenciesBaseFactory).extend(IdMixin); export const SoftwareProductDependenciesStoreFactory = new Factory() .extend(SoftwareProductDependenciesBaseFactory) diff --git a/openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductEditorFactories.js b/openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductEditorFactories.js index 5c5936155e..a820b70600 100644 --- a/openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductEditorFactories.js +++ b/openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductEditorFactories.js @@ -16,7 +16,6 @@ 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( @@ -30,7 +29,7 @@ Factory.define('VSPBaseFactory') licensingVersion: {id: '1', label: '1'}, licensingData: {}, icon: 'icon', - version: {id: '1', label: '1'} + version: {id: '123'} } ); @@ -46,7 +45,6 @@ Factory.define('LicensingDataMixin') export const VSPEditorFactory = new Factory() .extend('VSPBaseFactory') - .extend(VersionControllerUtilsFactory) .extend(IdMixin); export const VSPEditorPostFactory = new Factory() @@ -54,7 +52,6 @@ export const VSPEditorPostFactory = new Factory() export const VSPEditorFactoryWithLicensingData = new Factory() .extend('VSPBaseFactory') - .extend(VersionControllerUtilsFactory) .extend('LicensingDataMixin') .extend(IdMixin); diff --git a/openecomp-ui/test-utils/factories/softwareProduct/VersionControllerUtilsFactory.js b/openecomp-ui/test-utils/factories/softwareProduct/VersionControllerUtilsFactory.js index 8c9640714d..ba3946be48 100644 --- a/openecomp-ui/test-utils/factories/softwareProduct/VersionControllerUtilsFactory.js +++ b/openecomp-ui/test-utils/factories/softwareProduct/VersionControllerUtilsFactory.js @@ -14,17 +14,9 @@ * 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; - } + viewableVersions: [{id: '1.0', label: '1.0'}, {id: '1.1', label: '1.1'}, {id: '1.2', label: '1.2'}] }); - diff --git a/openecomp-ui/test-utils/factories/users/UsersFactories.js b/openecomp-ui/test-utils/factories/users/UsersFactories.js new file mode 100644 index 0000000000..cbafbe0747 --- /dev/null +++ b/openecomp-ui/test-utils/factories/users/UsersFactories.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'; +import randomstring from 'randomstring'; + +Factory.define('UserFactory') + .attrs( + { + firstName: () => randomstring.generate(5), + lastName: () => randomstring.generate(6), + userId: () => randomstring.generate(11), + email: randomstring.generate(5) + '@' + randomstring.generate(6) + '.com', + role: 'OPS', + lastLoginTime: 0, + status: 'ACTIVE', + fullName: () => randomstring.generate(5) + ' ' + randomstring.generate(6), + } +); + + +export const UserFactory = new Factory() + .extend('UserFactory');
\ No newline at end of file diff --git a/openecomp-ui/test-utils/factories/versionsPage/VersionsPageCreationFactories.js b/openecomp-ui/test-utils/factories/versionsPage/VersionsPageCreationFactories.js new file mode 100644 index 0000000000..c57ac87431 --- /dev/null +++ b/openecomp-ui/test-utils/factories/versionsPage/VersionsPageCreationFactories.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 {Factory} from 'rosie'; +import randomstring from 'randomstring'; + +export const VersionsPageCreationFactory = new Factory() + .attrs({ + name: () => randomstring.generate(), + description: () => randomstring.generate(), + creationMethod: () => ['major', 'minor'][Math.round(Math.random())] + }); + +export const VersionsPageCreationFieldInfoFactory = new Factory() + .attrs({ + description: () => ({ + isValid: true, + errorText: '', + validations: [{type: 'required', data: true}, {type: 'maxLength', data: 1000}] + }), + creationMethod: () => ({ + isValid: true, + errorText: '', + validations: [{type: 'required', data: true}] + }) + }); diff --git a/openecomp-ui/test-utils/factories/versionsPage/VersionsPageFactories.js b/openecomp-ui/test-utils/factories/versionsPage/VersionsPageFactories.js new file mode 100644 index 0000000000..49ceddc2bf --- /dev/null +++ b/openecomp-ui/test-utils/factories/versionsPage/VersionsPageFactories.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 {Factory} from 'rosie'; +import randomstring from 'randomstring'; +import VersionFactory from 'test-utils/factories/common/VersionFactory.js'; + +export const VersionsPageAdditionalPropsFactory = new Factory() + .attrs({ + itemId: () => randomstring.generate(), + itemType: () => 'vendor-license-models', + additionalProps: () => {}, + baseVersion: () => VersionFactory.build() + }); diff --git a/openecomp-ui/test-utils/failedTestReport.js b/openecomp-ui/test-utils/failedTestReport.js index 9520cc9c99..ed88ccde4f 100644 --- a/openecomp-ui/test-utils/failedTestReport.js +++ b/openecomp-ui/test-utils/failedTestReport.js @@ -22,7 +22,7 @@ stdin.on('end', function () { console.log('Failure Summary: \n'); } report.testResults.forEach((suite) => { - if(suite.status == 'failed') { + if(suite.status === 'failed') { console.log('Suite: ' + suite.name); suite.assertionResults.forEach((test) => { if (test.status === 'failed') { diff --git a/openecomp-ui/test/activity-log/ActivityLog.test.js b/openecomp-ui/test/activity-log/ActivityLog.test.js index 00aff49b26..d2c135eb79 100644 --- a/openecomp-ui/test/activity-log/ActivityLog.test.js +++ b/openecomp-ui/test/activity-log/ActivityLog.test.js @@ -24,11 +24,15 @@ import {mapStateToProps} from 'sdc-app/common/activity-log/ActivityLog.js'; import {storeCreator} from 'sdc-app/AppStore.js'; import mockRest from 'test-utils/MockRest.js'; import {ActivityLogStoreFactory} from 'test-utils/factories/activity-log/ActivityLogFactories.js'; -import VersionControllerUtilsFactory from 'test-utils/factories/softwareProduct/VersionControllerUtilsFactory.js'; +import VersionFactory from 'test-utils/factories/common/VersionFactory.js'; +import {UserFactory} from 'test-utils/factories/users/UsersFactories.js'; + +import {actionTypes as userActionTypes} from 'sdc-app/onboarding/users/UsersConstants.js'; describe('Activity Log Module Tests', function () { const LICENSE_MODEL_ID = '555'; - const version = VersionControllerUtilsFactory.build().version; + const version = VersionFactory.build(); + const usersList = UserFactory.buildList(3); it('mapStateToProps mapper exists', () => { expect(mapStateToProps).toBeTruthy(); @@ -37,11 +41,15 @@ describe('Activity Log Module Tests', function () { it('Loads Activity Log and renders into jsx', () => { const store = storeCreator(); const dispatch = store.dispatch; - let ActivityLogList = ActivityLogStoreFactory.buildList(1); + dispatch({ + type: userActionTypes.USERS_LIST_LOADED, + usersList + }); + let ActivityLogList = ActivityLogStoreFactory.buildList(1, {user: usersList[0].userId}); 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(baseUrl).toEqual(`/onboarding-api/v1.0/items/${LICENSE_MODEL_ID}/versions/${version.id}/activity-logs`); expect(data).toEqual(undefined); expect(options).toEqual(undefined); return {results: ActivityLogList}; @@ -51,7 +59,9 @@ describe('Activity Log Module Tests', function () { const state = store.getState(); expect(state).toEqual(expectedStore); const props = mapStateToProps(state); - expect(props.activities).toEqual(ActivityLogList); + expect(props.activities).toEqual(ActivityLogList.map(activity => + ({...activity, user: {id: activity.user, name: usersList.find(userObject => userObject.userId === activity.user).fullName}}) + )); const wrapper = mount(<ActivityLogView {...props}/>); expect(wrapper).toBeTruthy(); }); @@ -65,9 +75,9 @@ describe('Activity Log Module Tests', function () { 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]}}); + let firstActivity = ActivityLogStoreFactory.build({user: usersList[0].userId, timestamp: firstTimestamp}); + let secondActivity = ActivityLogStoreFactory.build({user: usersList[1].userId, timestamp: secondTimestamp, status: {success: false, message: 'error'}}); + let props = mapStateToProps({users: {usersList}, licenseModel: {activityLog: [firstActivity, secondActivity]}}); const wrapper = mount(<ActivityLogView {...props}/>); expect(wrapper.find(ActivityListItem).length).toEqual(3); // Includes Header component @@ -82,8 +92,8 @@ describe('Activity Log Module Tests', function () { expect(newFirstInstanceProps.activity.timestamp).toEqual(firstTimestamp); const listEditor = wrapper.find(ListEditorView); - listEditor.props().onFilter('second'); + listEditor.props().onFilter(usersList[1].fullName); expect(wrapper.find(ActivityListItem).length).toEqual(2); - expect(wrapper.find(ActivityListItem).at(1).props().activity.user).toEqual('second'); + expect(wrapper.find(ActivityListItem).at(1).props().activity.user.name).toEqual(usersList[1].fullName); }); }); diff --git a/openecomp-ui/test/licenseModel/creation/LicenseModelCreation.test.js b/openecomp-ui/test/licenseModel/creation/LicenseModelCreation.test.js index 0d8ce945c8..935360b04b 100644 --- a/openecomp-ui/test/licenseModel/creation/LicenseModelCreation.test.js +++ b/openecomp-ui/test/licenseModel/creation/LicenseModelCreation.test.js @@ -32,6 +32,9 @@ describe('License Model Creation Module Tests', function() { licenseModelCreation: { data: {} } + }, + users: { + usersList: [] } }; let props = mapStateToProps(state); @@ -41,16 +44,19 @@ describe('License Model Creation Module Tests', function() { it ('should return vlm names list', () => { let state = { licenseModelList: [{ - vendorName: 'vlm1', + name: 'vlm1', id: 'vlm1_id' }, { - vendorName: 'vlm2', + name: 'vlm2', id: 'vlm2_id' }], licenseModel: { licenseModelCreation: { data: {} } + }, + users: { + usersList: [] } }; let props = mapStateToProps(state); diff --git a/openecomp-ui/test/licenseModel/entitlementPools/test.js b/openecomp-ui/test/licenseModel/entitlementPools/test.js index f5415239ad..173384dc02 100644 --- a/openecomp-ui/test/licenseModel/entitlementPools/test.js +++ b/openecomp-ui/test/licenseModel/entitlementPools/test.js @@ -19,14 +19,18 @@ 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'; +import VersionFactory from 'test-utils/factories/common/VersionFactory.js'; import {LimitItemFactory, LimitPostFactory} from 'test-utils/factories/licenseModel/LimitFactories.js'; import {getStrValue} from 'nfvo-utils/getValue.js'; +import {SyncStates} from 'sdc-app/common/merge/MergeEditorConstants.js'; +import CurrentScreenFactory from 'test-utils/factories/common/CurrentScreenFactory.js'; describe('Entitlement Pools Module Tests', function () { const LICENSE_MODEL_ID = '555'; - const version = VersionControllerUtilsFactory.build().version; + const version = VersionFactory.build(); + const itemPermissionAndProps = CurrentScreenFactory.build({}, {version}); + const returnedVersionFields = {baseId: version.baseId, description: version.description, id: version.id, name: version.name, status: version.status}; it('Load Entitlement Pools List', () => { @@ -54,6 +58,7 @@ describe('Entitlement Pools Module Tests', function () { const entitlementPoolsList = buildListFromFactory(EntitlementPoolStoreFactory,1); deepFreeze(entitlementPoolsList); const store = storeCreator({ + currentScreen: {...itemPermissionAndProps}, licenseModel: { entitlementPool: { entitlementPoolsList @@ -62,7 +67,16 @@ describe('Entitlement Pools Module Tests', function () { }); deepFreeze(store.getState()); - const expectedStore = cloneAndSet(store.getState(), 'licenseModel.entitlementPool.entitlementPoolsList', []); + const expectedCurrentScreenProps = { + ...itemPermissionAndProps, + itemPermission: { + ...itemPermissionAndProps.itemPermission, + isDirty: true + } + }; + + let expectedStore = cloneAndSet(store.getState(), 'licenseModel.entitlementPool.entitlementPoolsList', []); + expectedStore = cloneAndSet(expectedStore, 'currentScreen.itemPermission', expectedCurrentScreenProps.itemPermission); mockRest.addHandler('destroy', ({data, options, baseUrl}) => { expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-license-models/${LICENSE_MODEL_ID}/versions/${version.id}/entitlement-pools/${entitlementPoolsList[0].id}`); @@ -75,6 +89,13 @@ describe('Entitlement Pools Module Tests', function () { }; }); + mockRest.addHandler('fetch', ({data, options, baseUrl}) => { + expect(baseUrl).toEqual(`/onboarding-api/v1.0/items/${LICENSE_MODEL_ID}/versions/${version.id}`); + expect(data).toEqual(undefined); + expect(options).toEqual(undefined); + return {...returnedVersionFields, state: {synchronizationState: SyncStates.UP_TO_DATE, dirty: true}}; + }); + return EntitlementPoolsActionHelper.deleteEntitlementPool(store.dispatch, { licenseModelId: LICENSE_MODEL_ID, version, @@ -86,7 +107,9 @@ describe('Entitlement Pools Module Tests', function () { it('Add Entitlement Pool', () => { - const store = storeCreator(); + const store = storeCreator({ + currentScreen: {...itemPermissionAndProps} + }); deepFreeze(store.getState()); const EntitlementPoolPostRequest = EntitlementPoolPostFactory.build(); @@ -97,7 +120,16 @@ describe('Entitlement Pools Module Tests', function () { const entitlementPoolAfterAdd = EntitlementPoolStoreFactory.build({id: entitlementPoolIdFromResponse}); deepFreeze(entitlementPoolAfterAdd); - const expectedStore = cloneAndSet(store.getState(), 'licenseModel.entitlementPool.entitlementPoolsList', [entitlementPoolAfterAdd]); + const expectedCurrentScreenProps = { + ...itemPermissionAndProps, + itemPermission: { + ...itemPermissionAndProps.itemPermission, + isDirty: true + } + }; + + let expectedStore = cloneAndSet(store.getState(), 'licenseModel.entitlementPool.entitlementPoolsList', [entitlementPoolAfterAdd]); + expectedStore = cloneAndSet(expectedStore, 'currentScreen.itemPermission', expectedCurrentScreenProps.itemPermission); mockRest.addHandler('post', ({data, options, baseUrl}) => { expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-license-models/${LICENSE_MODEL_ID}/versions/${version.id}/entitlement-pools`); @@ -109,6 +141,13 @@ describe('Entitlement Pools Module Tests', function () { }; }); + mockRest.addHandler('fetch', ({data, options, baseUrl}) => { + expect(baseUrl).toEqual(`/onboarding-api/v1.0/items/${LICENSE_MODEL_ID}/versions/${version.id}`); + expect(data).toEqual(undefined); + expect(options).toEqual(undefined); + return {...returnedVersionFields, state: {synchronizationState: SyncStates.UP_TO_DATE, dirty: true}}; + }); + return EntitlementPoolsActionHelper.saveEntitlementPool(store.dispatch, { licenseModelId: LICENSE_MODEL_ID, @@ -127,6 +166,7 @@ describe('Entitlement Pools Module Tests', function () { deepFreeze(entitlementPoolsList); const store = storeCreator({ + currentScreen: {...itemPermissionAndProps}, licenseModel: { entitlementPool: { entitlementPoolsList @@ -144,7 +184,16 @@ describe('Entitlement Pools Module Tests', function () { const entitlementPoolPutRequest = EntitlementPoolPostFactory.build({name: 'ep1_UPDATED', description: 'string_UPDATED'}); deepFreeze(entitlementPoolPutRequest); - const expectedStore = cloneAndSet(store.getState(), 'licenseModel.entitlementPool.entitlementPoolsList', [entitlementPoolUpdateData]); + const expectedCurrentScreenProps = { + ...itemPermissionAndProps, + itemPermission: { + ...itemPermissionAndProps.itemPermission, + isDirty: true + } + }; + + let expectedStore = cloneAndSet(store.getState(), 'licenseModel.entitlementPool.entitlementPoolsList', [entitlementPoolUpdateData]); + expectedStore = cloneAndSet(expectedStore, 'currentScreen.itemPermission', expectedCurrentScreenProps.itemPermission); mockRest.addHandler('put', ({data, options, baseUrl}) => { @@ -154,6 +203,13 @@ describe('Entitlement Pools Module Tests', function () { return {returnCode: 'OK'}; }); + mockRest.addHandler('fetch', ({data, options, baseUrl}) => { + expect(baseUrl).toEqual(`/onboarding-api/v1.0/items/${LICENSE_MODEL_ID}/versions/${version.id}`); + expect(data).toEqual(undefined); + expect(options).toEqual(undefined); + return {...returnedVersionFields, state: {synchronizationState: SyncStates.UP_TO_DATE, dirty: true}}; + }); + return EntitlementPoolsActionHelper.saveEntitlementPool(store.dispatch, { licenseModelId: LICENSE_MODEL_ID, version, @@ -187,7 +243,9 @@ describe('Entitlement Pools Module Tests', function () { it('Add Limit', () => { - const store = storeCreator(); + const store = storeCreator({ + currentScreen: {...itemPermissionAndProps} + }); deepFreeze(store.getState()); const limitToAdd = LimitPostFactory.build(); @@ -203,7 +261,16 @@ describe('Entitlement Pools Module Tests', function () { deepFreeze(limitAddedItem); const entitlementPool = EntitlementPoolStoreFactory.build(); - const expectedStore = cloneAndSet(store.getState(), 'licenseModel.entitlementPool.entitlementPoolEditor.limitsList', [limitAddedItem]); + const expectedCurrentScreenProps = { + ...itemPermissionAndProps, + itemPermission: { + ...itemPermissionAndProps.itemPermission, + isDirty: true + } + }; + + let expectedStore = cloneAndSet(store.getState(), 'licenseModel.entitlementPool.entitlementPoolEditor.limitsList', [limitAddedItem]); + expectedStore = cloneAndSet(expectedStore, 'currentScreen.itemPermission', expectedCurrentScreenProps.itemPermission); mockRest.addHandler('post', ({data, options, baseUrl}) => { expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-license-models/${LICENSE_MODEL_ID}/versions/${version.id}/entitlement-pools/${entitlementPool.id}/limits`); @@ -222,6 +289,13 @@ describe('Entitlement Pools Module Tests', function () { return {results: [limitAddedItem]}; }); + mockRest.addHandler('fetch', ({data, options, baseUrl}) => { + expect(baseUrl).toEqual(`/onboarding-api/v1.0/items/${LICENSE_MODEL_ID}/versions/${version.id}`); + expect(data).toEqual(undefined); + expect(options).toEqual(undefined); + return {...returnedVersionFields, state: {synchronizationState: SyncStates.UP_TO_DATE, dirty: true}}; + }); + return EntitlementPoolsActionHelper.submitLimit(store.dispatch, { licenseModelId: LICENSE_MODEL_ID, @@ -241,6 +315,7 @@ describe('Entitlement Pools Module Tests', function () { deepFreeze(limitsList); const store = storeCreator({ + currentScreen: {...itemPermissionAndProps}, licenseModel: { entitlementPool: { entitlementPoolEditor: { @@ -252,7 +327,17 @@ describe('Entitlement Pools Module Tests', function () { deepFreeze(store.getState()); const entitlementPool = EntitlementPoolStoreFactory.build(); - const expectedStore = cloneAndSet(store.getState(), 'licenseModel.entitlementPool.entitlementPoolEditor.limitsList', []); + + const expectedCurrentScreenProps = { + ...itemPermissionAndProps, + itemPermission: { + ...itemPermissionAndProps.itemPermission, + isDirty: true + } + }; + + let expectedStore = cloneAndSet(store.getState(), 'licenseModel.entitlementPool.entitlementPoolEditor.limitsList', []); + expectedStore = cloneAndSet(expectedStore, 'currentScreen.itemPermission', expectedCurrentScreenProps.itemPermission); mockRest.addHandler('destroy', ({data, options, baseUrl}) => { expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-license-models/${LICENSE_MODEL_ID}/versions/${version.id}/entitlement-pools/${entitlementPool.id}/limits/${limitsList[0].id}`); @@ -272,6 +357,13 @@ describe('Entitlement Pools Module Tests', function () { return {results: []}; }); + mockRest.addHandler('fetch', ({data, options, baseUrl}) => { + expect(baseUrl).toEqual(`/onboarding-api/v1.0/items/${LICENSE_MODEL_ID}/versions/${version.id}`); + expect(data).toEqual(undefined); + expect(options).toEqual(undefined); + return {...returnedVersionFields, state: {synchronizationState: SyncStates.UP_TO_DATE, dirty: true}}; + }); + return EntitlementPoolsActionHelper.deleteLimit(store.dispatch, { licenseModelId: LICENSE_MODEL_ID, version, @@ -288,6 +380,7 @@ describe('Entitlement Pools Module Tests', function () { deepFreeze(limitsList); const entitlementPool = EntitlementPoolStoreFactory.build(); const store = storeCreator({ + currentScreen: {...itemPermissionAndProps}, licenseModel: { entitlementPool: { entitlementPoolEditor: { @@ -312,7 +405,16 @@ describe('Entitlement Pools Module Tests', function () { updatedLimit.unit = {choice: updatedLimit.unit, other: ''}; deepFreeze(updatedLimit); - const expectedStore = cloneAndSet(store.getState(), 'licenseModel.entitlementPool.entitlementPoolEditor.limitsList', [updatedLimitForPut]); + const expectedCurrentScreenProps = { + ...itemPermissionAndProps, + itemPermission: { + ...itemPermissionAndProps.itemPermission, + isDirty: true + } + }; + + let expectedStore = cloneAndSet(store.getState(), 'licenseModel.entitlementPool.entitlementPoolEditor.limitsList', [updatedLimitForPut]); + expectedStore = cloneAndSet(expectedStore, 'currentScreen.itemPermission', expectedCurrentScreenProps.itemPermission); mockRest.addHandler('put', ({data, options, baseUrl}) => { @@ -329,6 +431,13 @@ describe('Entitlement Pools Module Tests', function () { return {results: [updatedLimitForPut]}; }); + mockRest.addHandler('fetch', ({data, options, baseUrl}) => { + expect(baseUrl).toEqual(`/onboarding-api/v1.0/items/${LICENSE_MODEL_ID}/versions/${version.id}`); + expect(data).toEqual(undefined); + expect(options).toEqual(undefined); + return {...returnedVersionFields, state: {synchronizationState: SyncStates.UP_TO_DATE, dirty: true}}; + }); + return EntitlementPoolsActionHelper.submitLimit(store.dispatch, { licenseModelId: LICENSE_MODEL_ID, diff --git a/openecomp-ui/test/licenseModel/featureGroups/test.js b/openecomp-ui/test/licenseModel/featureGroups/test.js index 7d0d7242b5..eb947b83d0 100644 --- a/openecomp-ui/test/licenseModel/featureGroups/test.js +++ b/openecomp-ui/test/licenseModel/featureGroups/test.js @@ -19,13 +19,17 @@ 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'; +import VersionFactory from 'test-utils/factories/common/VersionFactory.js'; +import CurrentScreenFactory from 'test-utils/factories/common/CurrentScreenFactory.js'; +import {SyncStates} from 'sdc-app/common/merge/MergeEditorConstants.js'; describe('Feature Groups Module Tests', function () { const LICENSE_MODEL_ID = '555'; - const version = VersionControllerUtilsFactory.build().version; + const version = VersionFactory.build(); + const itemPermissionAndProps = CurrentScreenFactory.build({}, {version}); + const returnedVersionFields = {baseId: version.baseId, description: version.description, id: version.id, name: version.name, status: version.status}; it('Load Feature Groups List', () => { @@ -53,6 +57,7 @@ describe('Feature Groups Module Tests', function () { const featureGroupsList = buildListFromFactory(FeatureGroupStoreFactory, 1); deepFreeze(featureGroupsList); const store = storeCreator({ + currentScreen: {...itemPermissionAndProps}, licenseModel: { featureGroup: { featureGroupsList @@ -61,7 +66,16 @@ describe('Feature Groups Module Tests', function () { }); deepFreeze(store.getState()); - const expectedStore = cloneAndSet(store.getState(), 'licenseModel.featureGroup.featureGroupsList', []); + const expectedCurrentScreenProps = { + ...itemPermissionAndProps, + itemPermission: { + ...itemPermissionAndProps.itemPermission, + isDirty: true + } + }; + + let expectedStore = cloneAndSet(store.getState(), 'licenseModel.featureGroup.featureGroupsList', []); + expectedStore = cloneAndSet(expectedStore, 'currentScreen.itemPermission', expectedCurrentScreenProps.itemPermission); const idToDelete = featureGroupsList[0].id; @@ -76,6 +90,13 @@ describe('Feature Groups Module Tests', function () { }; }); + mockRest.addHandler('fetch', ({data, options, baseUrl}) => { + expect(baseUrl).toEqual(`/onboarding-api/v1.0/items/${LICENSE_MODEL_ID}/versions/${version.id}`); + expect(data).toEqual(undefined); + expect(options).toEqual(undefined); + return {...returnedVersionFields, state: {synchronizationState: SyncStates.UP_TO_DATE, dirty: true}}; + }); + return FeatureGroupsActionHelper.deleteFeatureGroup(store.dispatch, { licenseModelId: LICENSE_MODEL_ID, version, @@ -87,7 +108,14 @@ describe('Feature Groups Module Tests', function () { it('Add Feature Group', () => { - const store = storeCreator(); + const store = storeCreator({ + currentScreen: {...itemPermissionAndProps}, + licenseModel: { + featureGroup: { + featureGroupsList: [] + } + } + }); deepFreeze(store.getState()); const FeatureGroupPostRequest = FeatureGroupPostFactory.build({ @@ -105,7 +133,16 @@ describe('Feature Groups Module Tests', function () { id: featureGroupIdFromResponse }); - const expectedStore = cloneAndSet(store.getState(), 'licenseModel.featureGroup.featureGroupsList', [featureGroupAfterAdd]); + const expectedCurrentScreenProps = { + ...itemPermissionAndProps, + itemPermission: { + ...itemPermissionAndProps.itemPermission, + isDirty: true + } + }; + + let expectedStore = cloneAndSet(store.getState(), 'licenseModel.featureGroup.featureGroupsList', [featureGroupAfterAdd]); + expectedStore = cloneAndSet(expectedStore, 'currentScreen.itemPermission', expectedCurrentScreenProps.itemPermission); mockRest.addHandler('post', ({data, options, baseUrl}) => { expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-license-models/${LICENSE_MODEL_ID}/versions/${version.id}/feature-groups`); @@ -131,6 +168,13 @@ describe('Feature Groups Module Tests', function () { return {results: []}; }); + mockRest.addHandler('fetch', ({data, options, baseUrl}) => { + expect(baseUrl).toEqual(`/onboarding-api/v1.0/items/${LICENSE_MODEL_ID}/versions/${version.id}`); + expect(data).toEqual(undefined); + expect(options).toEqual(undefined); + return {...returnedVersionFields, state: {synchronizationState: SyncStates.UP_TO_DATE, dirty: true}}; + }); + return FeatureGroupsActionHelper.saveFeatureGroup(store.dispatch, { licenseModelId: LICENSE_MODEL_ID, @@ -149,6 +193,7 @@ describe('Feature Groups Module Tests', function () { deepFreeze(featureGroupsList); const store = storeCreator({ + currentScreen: {...itemPermissionAndProps}, licenseModel: { featureGroup: { featureGroupsList @@ -178,7 +223,16 @@ describe('Feature Groups Module Tests', function () { }); deepFreeze(FeatureGroupPutFactoryRequest); - const expectedStore = cloneAndSet(store.getState(), 'licenseModel.featureGroup.featureGroupsList', [featureGroupUpdateData]); + const expectedCurrentScreenProps = { + ...itemPermissionAndProps, + itemPermission: { + ...itemPermissionAndProps.itemPermission, + isDirty: true + } + }; + + let expectedStore = cloneAndSet(store.getState(), 'licenseModel.featureGroup.featureGroupsList', [featureGroupUpdateData]); + expectedStore = cloneAndSet(expectedStore, 'currentScreen.itemPermission', expectedCurrentScreenProps.itemPermission); mockRest.addHandler('put', ({data, options, baseUrl}) => { @@ -202,6 +256,13 @@ describe('Feature Groups Module Tests', function () { return {results: []}; }); + mockRest.addHandler('fetch', ({data, options, baseUrl}) => { + expect(baseUrl).toEqual(`/onboarding-api/v1.0/items/${LICENSE_MODEL_ID}/versions/${version.id}`); + expect(data).toEqual(undefined); + expect(options).toEqual(undefined); + return {...returnedVersionFields, state: {synchronizationState: SyncStates.UP_TO_DATE, dirty: true}}; + }); + return FeatureGroupsActionHelper.saveFeatureGroup(store.dispatch, { licenseModelId: LICENSE_MODEL_ID, version, @@ -220,7 +281,6 @@ describe('Feature Groups Module Tests', function () { 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}) => { @@ -238,13 +298,9 @@ describe('Feature Groups Module Tests', function () { }); - FeatureGroupsActionHelper.openFeatureGroupsEditor(store.dispatch, {featureGroup: editorData, licenseModelId: '123', version}); - setTimeout(() =>{ - expect(store.getState()).toEqual(expectedStore); - }, 100); - - - + return FeatureGroupsActionHelper.openFeatureGroupsEditor(store.dispatch, {featureGroup: editorData, licenseModelId: '123', version}).then(() => { + expect(store.getState().licenseModel.featureGroup.featureGroupEditor.data).toEqual(editorData); + }); }); }); diff --git a/openecomp-ui/test/licenseModel/licenseAgreement/test.js b/openecomp-ui/test/licenseModel/licenseAgreement/test.js index 40b60da77f..11dc7edde5 100644 --- a/openecomp-ui/test/licenseModel/licenseAgreement/test.js +++ b/openecomp-ui/test/licenseModel/licenseAgreement/test.js @@ -21,12 +21,16 @@ 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'; +import VersionFactory from 'test-utils/factories/common/VersionFactory.js'; +import {SyncStates} from 'sdc-app/common/merge/MergeEditorConstants.js'; +import CurrentScreenFactory from 'test-utils/factories/common/CurrentScreenFactory.js'; describe('License Agreement Module Tests', () => { const LICENSE_MODEL_ID = '777'; - const version = VersionControllerUtilsFactory.build().version; + const version = VersionFactory.build(); + const itemPermissionAndProps = CurrentScreenFactory.build({}, {version}); + const returnedVersionFields = {baseId: version.baseId, description: version.description, id: version.id, name: version.name, status: version.status}; it('Load License Agreement List', () => { const licenseAgreementList = buildListFromFactory(LicenseAgreementStoreFactory); @@ -50,6 +54,7 @@ describe('License Agreement Module Tests', () => { it('Delete License Agreement', () => { const licenseAgreementList = buildListFromFactory(LicenseAgreementStoreFactory, 1); const store = storeCreator({ + currentScreen: {...itemPermissionAndProps}, licenseModel: { licenseAgreement: { licenseAgreementList @@ -57,14 +62,28 @@ describe('License Agreement Module Tests', () => { } }); deepFreeze(store.getState()); + const expectedCurrentScreenProps = { + ...itemPermissionAndProps, + itemPermission: { + ...itemPermissionAndProps.itemPermission, + isDirty: true + } + }; const toBeDeletedLicenseAgreementId = licenseAgreementList[0].id; - const expectedStore = cloneAndSet(store.getState(), 'licenseModel.licenseAgreement.licenseAgreementList', []); + let expectedStore = cloneAndSet(store.getState(), 'licenseModel.licenseAgreement.licenseAgreementList', []); + expectedStore = cloneAndSet(expectedStore, 'currentScreen.itemPermission', expectedCurrentScreenProps.itemPermission); mockRest.addHandler('destroy', ({data, options, baseUrl}) => { 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); }); + mockRest.addHandler('fetch', ({data, options, baseUrl}) => { + expect(baseUrl).toEqual(`/onboarding-api/v1.0/items/${LICENSE_MODEL_ID}/versions/${version.id}`); + expect(data).toEqual(undefined); + expect(options).toEqual(undefined); + return {...returnedVersionFields, state: {synchronizationState: SyncStates.UP_TO_DATE, dirty: true}}; + }); return LicenseAgreementActionHelper.deleteLicenseAgreement(store.dispatch, { licenseAgreementId: toBeDeletedLicenseAgreementId, @@ -76,7 +95,9 @@ describe('License Agreement Module Tests', () => { }); it('Add License Agreement', () => { - const store = storeCreator(); + const store = storeCreator({ + currentScreen: {...itemPermissionAndProps} + }); deepFreeze(store.getState()); const licenseAgreementToAdd = LicenseAgreementDispatchFactory.build(); @@ -94,9 +115,16 @@ describe('License Agreement Module Tests', () => { }); deepFreeze(licenseAgreementAfterAdd); const licenseAgreementList = [licenseAgreementAfterAdd]; - + const expectedCurrentScreenProps = { + ...itemPermissionAndProps, + itemPermission: { + ...itemPermissionAndProps.itemPermission, + isDirty: true + } + }; const featureGroupsList = licenseAgreementList.featureGroupsIds; - const expectedStore = cloneAndSet(store.getState(), 'licenseModel.licenseAgreement.licenseAgreementList', [licenseAgreementAfterAdd]); + let expectedStore = cloneAndSet(store.getState(), 'licenseModel.licenseAgreement.licenseAgreementList', [licenseAgreementAfterAdd]); + expectedStore = cloneAndSet(expectedStore, 'currentScreen.itemPermission', expectedCurrentScreenProps.itemPermission); mockRest.addHandler('post', ({options, data, baseUrl}) => { expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-license-models/${LICENSE_MODEL_ID}/versions/${version.id}/license-agreements`); @@ -118,6 +146,13 @@ describe('License Agreement Module Tests', () => { expect(options).toEqual(undefined); return {results: featureGroupsList}; }); + mockRest.addHandler('fetch', ({data, options, baseUrl}) => { + expect(baseUrl).toEqual(`/onboarding-api/v1.0/items/${LICENSE_MODEL_ID}/versions/${version.id}`); + expect(data).toEqual(undefined); + expect(options).toEqual(undefined); + return {...returnedVersionFields, state: {synchronizationState: SyncStates.UP_TO_DATE, dirty: true}}; + + }); return LicenseAgreementActionHelper.saveLicenseAgreement(store.dispatch, { licenseAgreement: licenseAgreementToAdd, licenseModelId: LICENSE_MODEL_ID, @@ -130,6 +165,7 @@ describe('License Agreement Module Tests', () => { it('Update License Agreement', () => { const licenseAgreementList = buildListFromFactory(LicenseAgreementStoreFactory, 1, {featureGroupsIds: ['77']}); const store = storeCreator({ + currentScreen: {...itemPermissionAndProps}, licenseModel: { licenseAgreement: { licenseAgreementList @@ -157,7 +193,15 @@ describe('License Agreement Module Tests', () => { deepFreeze(LicenseAgreementPutFactoryRequest); - const expectedStore = cloneAndSet(store.getState(), 'licenseModel.licenseAgreement.licenseAgreementList', [licenseAgreementUpdateData]); + const expectedCurrentScreenProps = { + ...itemPermissionAndProps, + itemPermission: { + ...itemPermissionAndProps.itemPermission, + isDirty: true + } + }; + let expectedStore = cloneAndSet(store.getState(), 'licenseModel.licenseAgreement.licenseAgreementList', [licenseAgreementUpdateData]); + expectedStore = cloneAndSet(expectedStore, 'currentScreen.itemPermission', expectedCurrentScreenProps.itemPermission); 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}`); @@ -170,12 +214,19 @@ describe('License Agreement Module Tests', () => { expect(options).toEqual(undefined); return {results: [licenseAgreementUpdateData]}; }); + mockRest.addHandler('fetch', ({data, options, baseUrl}) => { + expect(baseUrl).toEqual(`/onboarding-api/v1.0/items/${LICENSE_MODEL_ID}/versions/${version.id}`); + expect(data).toEqual(undefined); + expect(options).toEqual(undefined); + return {...returnedVersionFields, state: {synchronizationState: SyncStates.UP_TO_DATE, dirty: true}}; + }); mockRest.addHandler('fetch', ({options, data, baseUrl}) => { 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: newFeatureGroupsIds}; }); + return LicenseAgreementActionHelper.saveLicenseAgreement(store.dispatch, { licenseModelId: LICENSE_MODEL_ID, version, diff --git a/openecomp-ui/test/licenseModel/licenseKeyGroups/test.js b/openecomp-ui/test/licenseModel/licenseKeyGroups/test.js index 739e266d7f..09a2c6f53a 100644 --- a/openecomp-ui/test/licenseModel/licenseKeyGroups/test.js +++ b/openecomp-ui/test/licenseModel/licenseKeyGroups/test.js @@ -20,14 +20,18 @@ 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'; +import VersionFactory from 'test-utils/factories/common/VersionFactory.js'; +import CurrentScreenFactory from 'test-utils/factories/common/CurrentScreenFactory.js'; import {LimitItemFactory, LimitPostFactory} from 'test-utils/factories/licenseModel/LimitFactories.js'; import {getStrValue} from 'nfvo-utils/getValue.js'; +import {SyncStates} from 'sdc-app/common/merge/MergeEditorConstants.js'; describe('License Key Groups Module Tests', function () { const LICENSE_MODEL_ID = '555'; - const version = VersionControllerUtilsFactory.build().version; + const version = VersionFactory.build(); + const itemPermissionAndProps = CurrentScreenFactory.build({}, {version}); + const returnedVersionFields = {baseId: version.baseId, description: version.description, id: version.id, name: version.name, status: version.status}; it('Load License Key Group', () => { @@ -57,6 +61,7 @@ describe('License Key Groups Module Tests', function () { deepFreeze(licenseKeyGroupsList); const store = storeCreator({ + currentScreen: {...itemPermissionAndProps}, licenseModel: { licenseKeyGroup: { licenseKeyGroupsList @@ -65,7 +70,17 @@ describe('License Key Groups Module Tests', function () { }); deepFreeze(store.getState()); const toBeDeletedLicenseKeyGroupId = licenseKeyGroupsList[0].id; - const expectedStore = cloneAndSet(store.getState(), 'licenseModel.licenseKeyGroup.licenseKeyGroupsList', []); + + const expectedCurrentScreenProps = { + ...itemPermissionAndProps, + itemPermission: { + ...itemPermissionAndProps.itemPermission, + isDirty: true + } + }; + + let expectedStore = cloneAndSet(store.getState(), 'licenseModel.licenseKeyGroup.licenseKeyGroupsList', []); + expectedStore = cloneAndSet(expectedStore, 'currentScreen.itemPermission', expectedCurrentScreenProps.itemPermission); mockRest.addHandler('destroy', ({data, options, baseUrl}) => { expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-license-models/${LICENSE_MODEL_ID}/versions/${version.id}/license-key-groups/${toBeDeletedLicenseKeyGroupId}`); @@ -73,6 +88,13 @@ describe('License Key Groups Module Tests', function () { expect(options).toEqual(undefined); }); + mockRest.addHandler('fetch', ({data, options, baseUrl}) => { + expect(baseUrl).toEqual(`/onboarding-api/v1.0/items/${LICENSE_MODEL_ID}/versions/${version.id}`); + expect(data).toEqual(undefined); + expect(options).toEqual(undefined); + return {...returnedVersionFields, state: {synchronizationState: SyncStates.UP_TO_DATE, dirty: true}}; + }); + return LicenseKeyGroupsActionHelper.deleteLicenseKeyGroup(store.dispatch, { licenseKeyGroupId: toBeDeletedLicenseKeyGroupId, licenseModelId: LICENSE_MODEL_ID, @@ -84,7 +106,9 @@ describe('License Key Groups Module Tests', function () { it('Add License Key Group', () => { - const store = storeCreator(); + const store = storeCreator({ + currentScreen: {...itemPermissionAndProps} + }); deepFreeze(store.getState()); const LicenseKeyGroupPost = LicenseKeyGroupPostFactory.build(); @@ -93,7 +117,16 @@ describe('License Key Groups Module Tests', function () { const LicenseKeyGroupStore = LicenseKeyGroupStoreFactory.build(); deepFreeze(LicenseKeyGroupStore); - const expectedStore = cloneAndSet(store.getState(), 'licenseModel.licenseKeyGroup.licenseKeyGroupsList', [LicenseKeyGroupStore]); + const expectedCurrentScreenProps = { + ...itemPermissionAndProps, + itemPermission: { + ...itemPermissionAndProps.itemPermission, + isDirty: true + } + }; + + let expectedStore = cloneAndSet(store.getState(), 'licenseModel.licenseKeyGroup.licenseKeyGroupsList', [LicenseKeyGroupStore]); + expectedStore = cloneAndSet(expectedStore, 'currentScreen.itemPermission', expectedCurrentScreenProps.itemPermission); 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`); @@ -104,6 +137,13 @@ describe('License Key Groups Module Tests', function () { }; }); + mockRest.addHandler('fetch', ({data, options, baseUrl}) => { + expect(baseUrl).toEqual(`/onboarding-api/v1.0/items/${LICENSE_MODEL_ID}/versions/${version.id}`); + expect(data).toEqual(undefined); + expect(options).toEqual(undefined); + return {...returnedVersionFields, state: {synchronizationState: SyncStates.UP_TO_DATE, dirty: true}}; + }); + return LicenseKeyGroupsActionHelper.saveLicenseKeyGroup(store.dispatch, { licenseKeyGroup: LicenseKeyGroupPost, licenseModelId: LICENSE_MODEL_ID, @@ -117,6 +157,7 @@ describe('License Key Groups Module Tests', function () { const licenseKeyGroupsList = buildListFromFactory(LicenseKeyGroupStoreFactory, 1); deepFreeze(licenseKeyGroupsList); const store = storeCreator({ + currentScreen: {...itemPermissionAndProps}, licenseModel: { licenseKeyGroup: { licenseKeyGroupsList @@ -141,7 +182,16 @@ describe('License Key Groups Module Tests', function () { deepFreeze(licenseKeyGroupPutRequest); - const expectedStore = cloneAndSet(store.getState(), 'licenseModel.licenseKeyGroup.licenseKeyGroupsList', [licenseKeyGroupUpdatedData]); + const expectedCurrentScreenProps = { + ...itemPermissionAndProps, + itemPermission: { + ...itemPermissionAndProps.itemPermission, + isDirty: true + } + }; + + let expectedStore = cloneAndSet(store.getState(), 'licenseModel.licenseKeyGroup.licenseKeyGroupsList', [licenseKeyGroupUpdatedData]); + expectedStore = cloneAndSet(expectedStore, 'currentScreen.itemPermission', expectedCurrentScreenProps.itemPermission); 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}`); @@ -149,6 +199,13 @@ describe('License Key Groups Module Tests', function () { expect(options).toEqual(undefined); }); + mockRest.addHandler('fetch', ({data, options, baseUrl}) => { + expect(baseUrl).toEqual(`/onboarding-api/v1.0/items/${LICENSE_MODEL_ID}/versions/${version.id}`); + expect(data).toEqual(undefined); + expect(options).toEqual(undefined); + return {...returnedVersionFields, state: {synchronizationState: SyncStates.UP_TO_DATE, dirty: true}}; + }); + return LicenseKeyGroupsActionHelper.saveLicenseKeyGroup(store.dispatch, { previousLicenseKeyGroup: previousLicenseKeyGroupData, licenseKeyGroup: licenseKeyGroupUpdatedData, @@ -182,7 +239,9 @@ describe('License Key Groups Module Tests', function () { it('Add Limit', () => { - const store = storeCreator(); + const store = storeCreator({ + currentScreen: {...itemPermissionAndProps} + }); deepFreeze(store.getState()); const limitToAdd = LimitPostFactory.build(); @@ -198,7 +257,16 @@ describe('License Key Groups Module Tests', function () { deepFreeze(limitAddedItem); const licenseKeyGroup = LicenseKeyGroupStoreFactory.build(); - const expectedStore = cloneAndSet(store.getState(), 'licenseModel.licenseKeyGroup.licenseKeyGroupsEditor.limitsList', [limitAddedItem]); + const expectedCurrentScreenProps = { + ...itemPermissionAndProps, + itemPermission: { + ...itemPermissionAndProps.itemPermission, + isDirty: true + } + }; + + let expectedStore = cloneAndSet(store.getState(), 'licenseModel.licenseKeyGroup.licenseKeyGroupsEditor.limitsList', [limitAddedItem]); + expectedStore = cloneAndSet(expectedStore, 'currentScreen.itemPermission', expectedCurrentScreenProps.itemPermission); mockRest.addHandler('post', ({data, options, baseUrl}) => { expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-license-models/${LICENSE_MODEL_ID}/versions/${version.id}/license-key-groups/${licenseKeyGroup.id}/limits`); @@ -217,6 +285,13 @@ describe('License Key Groups Module Tests', function () { return {results: [limitAddedItem]}; }); + mockRest.addHandler('fetch', ({data, options, baseUrl}) => { + expect(baseUrl).toEqual(`/onboarding-api/v1.0/items/${LICENSE_MODEL_ID}/versions/${version.id}`); + expect(data).toEqual(undefined); + expect(options).toEqual(undefined); + return {...returnedVersionFields, state: {synchronizationState: SyncStates.UP_TO_DATE, dirty: true}}; + }); + return LicenseKeyGroupsActionHelper.submitLimit(store.dispatch, { licenseModelId: LICENSE_MODEL_ID, @@ -235,6 +310,7 @@ describe('License Key Groups Module Tests', function () { deepFreeze(limitsList); const store = storeCreator({ + currentScreen: {...itemPermissionAndProps}, licenseModel: { entitlementPool: { entitlementPoolEditor: { @@ -246,7 +322,17 @@ describe('License Key Groups Module Tests', function () { deepFreeze(store.getState()); const licenseKeyGroup = LicenseKeyGroupStoreFactory.build(); - const expectedStore = cloneAndSet(store.getState(), 'licenseModel.licenseKeyGroup.licenseKeyGroupsEditor.limitsList', []); + + const expectedCurrentScreenProps = { + ...itemPermissionAndProps, + itemPermission: { + ...itemPermissionAndProps.itemPermission, + isDirty: true + } + }; + + let expectedStore = cloneAndSet(store.getState(), 'licenseModel.licenseKeyGroup.licenseKeyGroupsEditor.limitsList', []); + expectedStore = cloneAndSet(expectedStore, 'currentScreen.itemPermission', expectedCurrentScreenProps.itemPermission); mockRest.addHandler('destroy', ({data, options, baseUrl}) => { expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-license-models/${LICENSE_MODEL_ID}/versions/${version.id}/license-key-groups/${licenseKeyGroup.id}/limits/${limitsList[0].id}`); @@ -266,6 +352,13 @@ describe('License Key Groups Module Tests', function () { return {results: []}; }); + mockRest.addHandler('fetch', ({data, options, baseUrl}) => { + expect(baseUrl).toEqual(`/onboarding-api/v1.0/items/${LICENSE_MODEL_ID}/versions/${version.id}`); + expect(data).toEqual(undefined); + expect(options).toEqual(undefined); + return {...returnedVersionFields, state: {synchronizationState: SyncStates.UP_TO_DATE, dirty: true}}; + }); + return LicenseKeyGroupsActionHelper.deleteLimit(store.dispatch, { licenseModelId: LICENSE_MODEL_ID, version, @@ -282,6 +375,7 @@ describe('License Key Groups Module Tests', function () { deepFreeze(limitsList); const licenseKeyGroup = LicenseKeyGroupStoreFactory.build(); const store = storeCreator({ + currentScreen: {...itemPermissionAndProps}, licenseModel: { licenseKeyGroup: { licenseKeyGroupsEditor: { @@ -304,7 +398,16 @@ describe('License Key Groups Module Tests', function () { updatedLimit.unit = {choice: updatedLimit.unit, other: ''}; deepFreeze(updatedLimit); - const expectedStore = cloneAndSet(store.getState(), 'licenseModel.licenseKeyGroup.licenseKeyGroupsEditor.limitsList', [updatedLimitForPut]); + const expectedCurrentScreenProps = { + ...itemPermissionAndProps, + itemPermission: { + ...itemPermissionAndProps.itemPermission, + isDirty: true + } + }; + + let expectedStore = cloneAndSet(store.getState(), 'licenseModel.licenseKeyGroup.licenseKeyGroupsEditor.limitsList', [updatedLimitForPut]); + expectedStore = cloneAndSet(expectedStore, 'currentScreen.itemPermission', expectedCurrentScreenProps.itemPermission); mockRest.addHandler('put', ({data, options, baseUrl}) => { @@ -321,6 +424,13 @@ describe('License Key Groups Module Tests', function () { return {results: [updatedLimitForPut]}; }); + mockRest.addHandler('fetch', ({data, options, baseUrl}) => { + expect(baseUrl).toEqual(`/onboarding-api/v1.0/items/${LICENSE_MODEL_ID}/versions/${version.id}`); + expect(data).toEqual(undefined); + expect(options).toEqual(undefined); + return {...returnedVersionFields, state: {synchronizationState: SyncStates.UP_TO_DATE, dirty: true}}; + }); + return LicenseKeyGroupsActionHelper.submitLimit(store.dispatch, { licenseModelId: LICENSE_MODEL_ID, diff --git a/openecomp-ui/test/licenseModel/overview/summary/SummaryCountList.test.js b/openecomp-ui/test/licenseModel/overview/summary/SummaryCountList.test.js index 27f7aa68fd..87e35785ca 100644 --- a/openecomp-ui/test/licenseModel/overview/summary/SummaryCountList.test.js +++ b/openecomp-ui/test/licenseModel/overview/summary/SummaryCountList.test.js @@ -55,7 +55,6 @@ describe('License Model Overview Summary Count List module test', () => { ]; var result = mapStateToProps(obj); - expect(result.isReadOnlyMode).toEqual(true); expect(result.description).toEqual(obj.licenseModel.licenseModelEditor.data.description); expect(result.counts).toEqual(counts); }); @@ -79,7 +78,7 @@ describe('License Model Overview Summary Count List module test', () => { 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 index 7ec85a456b..57ae2618ce 100644 --- a/openecomp-ui/test/licenseModel/overview/summary/VendorDataView.test.js +++ b/openecomp-ui/test/licenseModel/overview/summary/VendorDataView.test.js @@ -33,7 +33,6 @@ describe('License Model Overview Summary module test', () => { }; var props = mapStateToProps(state); - expect(props.isReadOnlyMode).toEqual(true); expect(props.description).toEqual(undefined); expect(props.data).toEqual(state.licenseModel.licenseModelEditor.data); @@ -41,7 +40,7 @@ describe('License Model Overview Summary module test', () => { it('jsx view test', () => { var data = LicenseModelStoreFactory.build(); - var view = TestUtils.renderIntoDocument(<VendorDataView isReadOnlyMode={false} description='' data={data} genericFieldInfo={{description: {isValid: true}}}/>); + var view = TestUtils.renderIntoDocument(<VendorDataView description='' data={data} genericFieldInfo={{description: {isValid: true}}}/>); expect(view).toBeTruthy(); }); diff --git a/openecomp-ui/test/licenseModel/overview/test.js b/openecomp-ui/test/licenseModel/overview/test.js index cb1a9c34b2..d881985088 100644 --- a/openecomp-ui/test/licenseModel/overview/test.js +++ b/openecomp-ui/test/licenseModel/overview/test.js @@ -47,7 +47,6 @@ describe('License Model Overview: ', function () { }; 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); @@ -79,7 +78,6 @@ describe('License Model Overview: ', function () { }; 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); @@ -112,7 +110,6 @@ describe('License Model Overview: ', function () { }; 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); @@ -121,7 +118,7 @@ describe('License Model Overview: ', function () { }); it('should mapper return overview data for show EP modal', () => { - const VLM1 = LicenseModelOverviewFactory.build( { + const VLM1 = LicenseModelOverviewFactory.build({ featureGroup: { featureGroupsList: [], }, @@ -141,7 +138,6 @@ describe('License Model Overview: ', function () { }; 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); @@ -173,7 +169,6 @@ describe('License Model Overview: ', function () { }; 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); @@ -233,7 +228,6 @@ describe('License Model Overview: ', function () { 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); @@ -282,7 +276,6 @@ describe('License Model Overview: ', function () { 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); @@ -310,6 +303,7 @@ describe('License Model Overview: ', function () { selectedTab: selectedButton.NOT_IN_USE } }); + const state = { licenseModel: VLM1 }; @@ -322,7 +316,6 @@ describe('License Model Overview: ', function () { 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); @@ -372,7 +365,6 @@ describe('License Model Overview: ', function () { 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); @@ -380,5 +372,4 @@ describe('License Model Overview: ', function () { expect(props.orphanDataList).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 index cee34145a8..c750f3dc02 100644 --- a/openecomp-ui/test/licenseModel/overview/views.test.js +++ b/openecomp-ui/test/licenseModel/overview/views.test.js @@ -39,7 +39,7 @@ describe('License Model Overview - View: ', function () { it('should render SummaryView', () => { var renderer = TestUtils.createRenderer(); renderer.render( - <SummaryView /> + <SummaryView isReadOnly={false} /> ); let renderedOutput = renderer.getRenderOutput(); expect(renderedOutput).toBeTruthy(); diff --git a/openecomp-ui/test/licenseModel/test.js b/openecomp-ui/test/licenseModel/test.js index eac1297f3e..6cb2168cbb 100644 --- a/openecomp-ui/test/licenseModel/test.js +++ b/openecomp-ui/test/licenseModel/test.js @@ -16,9 +16,15 @@ import deepFreeze from 'deep-freeze'; import mockRest from 'test-utils/MockRest.js'; import {storeCreator} from 'sdc-app/AppStore.js'; +import {cloneAndSet} from 'test-utils/Util.js'; +import LicenseModelActionHelper from 'sdc-app/onboarding/licenseModel/LicenseModelActionHelper.js'; import LicenseModelCreationActionHelper from 'sdc-app/onboarding/licenseModel/creation/LicenseModelCreationActionHelper.js'; - -import {LicenseModelPostFactory, LicenseModelDispatchFactory} from 'test-utils/factories/licenseModel/LicenseModelFactories.js'; +import {LicenseModelPostFactory, LicenseModelDispatchFactory, LicenseModelStoreFactory} from 'test-utils/factories/licenseModel/LicenseModelFactories.js'; +import VersionFactory from 'test-utils/factories/common/VersionFactory.js'; +import {default as CurrentScreenFactory} from 'test-utils/factories/common/CurrentScreenFactory.js'; +import {actionsEnum as VersionControllerActionsEnum} from 'nfvo-components/panel/versionController/VersionControllerConstants.js'; +import {SyncStates} from 'sdc-app/common/merge/MergeEditorConstants.js'; +import {itemTypes} from 'sdc-app/onboarding/versionsPage/VersionsPageConstants.js'; describe('License Model Module Tests', function () { it('Add License Model', () => { @@ -46,4 +52,90 @@ describe('License Model Module Tests', function () { expect(response.value).toEqual(licenseModelIdFromResponse); }); }); + + it('Validating readonly screen after submit', () => { + const version = VersionFactory.build({}, {isCertified: false}); + const itemPermissionAndProps = CurrentScreenFactory.build({}, {version}); + const licenseModel = LicenseModelStoreFactory.build(); + deepFreeze(licenseModel); + + const store = storeCreator({ + currentScreen: {...itemPermissionAndProps}, + licenseModel: { + licenseModelEditor: {data: licenseModel}, + } + }); + deepFreeze(store.getState()); + + const certifiedVersion = { + ...itemPermissionAndProps.props.version, + status: 'Certified' + }; + + const expectedCurrentScreenProps = { + itemPermission: { + ...itemPermissionAndProps.itemPermission, + isCertified: true + }, + props: { + isReadOnlyMode: true, + version: certifiedVersion + } + }; + const expectedSuccessModal = { + cancelButtonText: 'OK', + modalClassName: 'notification-modal', + msg: 'This license model successfully submitted', + timeout: 2000, + title: 'Submit Succeeded', + type: 'success' + }; + + const versionsList = { + itemType: itemTypes.LICENSE_MODEL, + itemId: licenseModel.id, + versions: [{...certifiedVersion}] + }; + + let expectedStore = store.getState(); + expectedStore = cloneAndSet(expectedStore, 'currentScreen.itemPermission', expectedCurrentScreenProps.itemPermission); + expectedStore = cloneAndSet(expectedStore, 'currentScreen.props', expectedCurrentScreenProps.props); + expectedStore = cloneAndSet(expectedStore, 'modal', expectedSuccessModal); + expectedStore = cloneAndSet(expectedStore, 'versionsPage.versionsList', versionsList ); + + mockRest.addHandler('put', ({data, options, baseUrl}) => { + expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-license-models/${licenseModel.id}/versions/${version.id}/actions`); + expect(data).toEqual({action: VersionControllerActionsEnum.SUBMIT}); + expect(options).toEqual(undefined); + return {returnCode: 'OK'}; + }); + + mockRest.addHandler('put', ({data, options, baseUrl}) => { + expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-license-models/${licenseModel.id}/versions/${version.id}/actions`); + expect(data).toEqual({action: VersionControllerActionsEnum.CREATE_PACKAGE}); + expect(options).toEqual(undefined); + return {returnCode: 'OK'}; + }); + + mockRest.addHandler('fetch', ({data, options, baseUrl}) => { + expect(baseUrl).toEqual(`/onboarding-api/v1.0/items/${licenseModel.id}/versions/${version.id}`); + expect(data).toEqual(undefined); + expect(options).toEqual(undefined); + return {...certifiedVersion, state: {synchronizationState: SyncStates.UP_TO_DATE, dirty: false}}; + }); + + mockRest.addHandler('fetch', ({data, options, baseUrl}) => { + expect(baseUrl).toEqual(`/onboarding-api/v1.0/items/${licenseModel.id}/versions`); + expect(data).toEqual(undefined); + expect(options).toEqual(undefined); + return {results: [{...certifiedVersion}]}; + }); + + return LicenseModelActionHelper.performSubmitAction(store.dispatch, { + licenseModelId: licenseModel.id, + version + }).then(() => { + expect(store.getState()).toEqual(expectedStore); + }); + }); }); diff --git a/openecomp-ui/test/nfvo-components/editor/TabulatedEditor.test.js b/openecomp-ui/test/nfvo-components/editor/TabulatedEditor.test.js index e61261e09a..5f9f06b714 100644 --- a/openecomp-ui/test/nfvo-components/editor/TabulatedEditor.test.js +++ b/openecomp-ui/test/nfvo-components/editor/TabulatedEditor.test.js @@ -18,13 +18,15 @@ import React from 'react'; import TestUtils from 'react-addons-test-utils'; import TabulatedEditor from 'nfvo-components/editor/TabulatedEditor.jsx'; +import { Provider } from 'react-redux'; +import {storeCreator} from 'sdc-app/AppStore.js'; describe('Tabulated Editor test: ', function () { - + const store = storeCreator(); it('basic view test', () => { let renderer = TestUtils.createRenderer(); renderer.render( - <TabulatedEditor><button>test</button></TabulatedEditor> + <Provider store={store}><TabulatedEditor><button>test</button></TabulatedEditor></Provider> ); let renderedOutput = renderer.getRenderOutput(); expect(renderedOutput).toBeTruthy(); @@ -41,11 +43,12 @@ describe('Tabulated Editor test: ', function () { isCheckedOut: false, version: {id: '0.1', label: '0.1'}, viewableVersions: [{id: '0.1', label: '0.1'}], + itemPermission: {isCertified: false, isCollaborator: true, isDirty: false}, onSubmit: ()=>{}, onRevert: ()=>{} } }; - const view = TestUtils.renderIntoDocument(<TabulatedEditor {...props}><button>test</button></TabulatedEditor>); + const view = TestUtils.renderIntoDocument(<Provider store={store}><TabulatedEditor {...props}><button>test</button></TabulatedEditor></Provider>); expect(view).toBeTruthy(); }); diff --git a/openecomp-ui/test/nfvo-components/modal/globalModal.test.js b/openecomp-ui/test/nfvo-components/modal/globalModal.test.js index efe43b6c37..f27b1359f8 100644 --- a/openecomp-ui/test/nfvo-components/modal/globalModal.test.js +++ b/openecomp-ui/test/nfvo-components/modal/globalModal.test.js @@ -81,10 +81,10 @@ describe('Global Modal tests: ', function () { 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(window.document).toBeTruthy(); + let renderer = TestUtils.createRenderer(); + renderer.render(<GlobalModalView show={true} type={typeEnum.WARNING} title={title} msg={msg} onDeclined={()=>{}} />); + let globalModalView = renderer.getRenderOutput(); expect(globalModalView).toBeTruthy(); }); 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 e14e9b76f5..f2db01f3f1 100644 --- a/openecomp-ui/test/nfvo-components/panel/VersionController/versionController.test.js +++ b/openecomp-ui/test/nfvo-components/panel/VersionController/versionController.test.js @@ -16,13 +16,14 @@ import React from 'react'; -import ReactDOMServer from 'react-dom/server'; + import TestUtils from 'react-addons-test-utils'; -import {mount} from 'enzyme'; import VersionController from 'nfvo-components/panel/versionController/VersionController.jsx'; -import {actionsEnum, statusEnum} from 'nfvo-components/panel/versionController/VersionControllerConstants.js'; +import {actionsEnum} from 'nfvo-components/panel/versionController/VersionControllerConstants.js'; import {scryRenderedDOMComponentsWithTestId} from 'test-utils/Util.js'; import {VSPComponentsVersionControllerFactory} from 'test-utils/factories/softwareProduct/SoftwareProductComponentsNetworkFactories.js'; +import { Provider } from 'react-redux'; +import {storeCreator} from 'sdc-app/AppStore.js'; describe('versionController UI Component', () => { let onSave, onClose, onVersionSwitching = onSave = onClose = () => {return Promise.resolve();}; @@ -30,42 +31,42 @@ describe('versionController UI Component', () => { const isFormDataValid = true; const viewableVersions = versionData.viewableVersions; const version = versionData.version; - const props = {onSave, onClose, isFormDataValid, viewableVersions, version, onVersionSwitching}; + const itemPermission = {isCertified: false, isCollaborator: true, isDirty: false}; + const props = {onSave, onClose, isFormDataValid, viewableVersions, version, onVersionSwitching, itemPermission}; + const store = storeCreator(); it('function does exist', () => { var renderer = TestUtils.createRenderer(); - renderer.render(<VersionController isCheckedOut={false} status={statusEnum.CHECK_OUT_STATUS} {...props} />); + + renderer.render(<Provider store={store}><VersionController {...props} /></Provider>); var renderedOutput = renderer.getRenderOutput(); expect(renderedOutput).toBeTruthy(); }); - it('validating checkin function', () => { - 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 provider = TestUtils.renderIntoDocument(<Provider store={store}> + <VersionController {...props} /></Provider>); + let versionController = TestUtils.findRenderedComponentWithType( + provider, + VersionController + ); 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); + let provider = TestUtils.renderIntoDocument(<Provider store={store}><VersionController {...props} /></Provider>); + let versionController = TestUtils.findRenderedComponentWithType( + provider, + VersionController + ); + let cb = action => expect(action).toBe(actionsEnum.REVERT); + versionController.revert(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 versionController = TestUtils.renderIntoDocument(<Provider store={store}><VersionController {...noSaveProps} /></Provider>); let elem = scryRenderedDOMComponentsWithTestId(versionController,'vc-save-btn'); expect(elem).toBeTruthy(); expect(elem.length).toBe(0); @@ -73,7 +74,7 @@ describe('versionController UI Component', () => { 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 versionController = TestUtils.renderIntoDocument(<Provider store={store}><VersionController {...callVCActionProps} /></Provider>); let elem = scryRenderedDOMComponentsWithTestId(versionController,'vc-submit-btn'); expect(elem).toBeTruthy(); expect(elem.length).toBe(0); @@ -81,72 +82,45 @@ describe('versionController UI Component', () => { 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 versionController = TestUtils.renderIntoDocument(<Provider store={store}><VersionController {...callVCActionProps} /></Provider>); 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 versionController = TestUtils.renderIntoDocument(<Provider store={store}><VersionController {...props} /></Provider>); 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} />); + it('Shows the submit button when callVCAction available and user is owner', () => { + const permissions = {owner: {userId: '111'}}, + userInfo = {userId: '111'}; + let callVCActionProps = { ...props, callVCAction: function(){}, permissions, userInfo}; + let versionController = TestUtils.renderIntoDocument(<Provider store={store}><VersionController {...callVCActionProps} /></Provider>); 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'); + it('Doesn\'t show the submit button when user is not owner', () => { + const permissions = {owner: {userId: '111'}}, + userInfo = {userId: '222'}; + let callVCActionProps = { ...props, callVCAction: function(){}, permissions, userInfo}; + let versionController = TestUtils.renderIntoDocument(<Provider store={store}><VersionController {...callVCActionProps} /></Provider>); + let elem = scryRenderedDOMComponentsWithTestId(versionController,'vc-submit-btn'); expect(elem).toBeTruthy(); - expect(elem.length).toBe(1); + expect(elem.length).toBe(0); }); - it('Shows the checkout button', () => { + it('Shows the revert 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-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"]'); - - expect(elem).toBeTruthy(); - expect(elem.length).toEqual(1); - expect(elem.find('.svg-icon').length).toEqual(1); - expect(elem.find('.svg-icon').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 versionController = TestUtils.renderIntoDocument(<Provider store={store}><VersionController {...callVCActionProps} /></Provider>); + let elem = scryRenderedDOMComponentsWithTestId(versionController,'vc-revert-btn'); expect(elem).toBeTruthy(); expect(elem.length).toBe(1); - expect(elem.find('.svg-icon').length).toEqual(1); - expect(elem.find('.svg-icon').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 deleted file mode 100644 index d654e16ddf..0000000000 --- a/openecomp-ui/test/nfvo-components/panel/VersionController/versionControllerUtils.test.js +++ /dev/null @@ -1,128 +0,0 @@ -/*! - * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ - - -import 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).toBeTruthy(); - }); - - it('validating getCheckOutStatusKindByUserID - without "UserID"', () => { - var result = VersionControllerUtils.getCheckOutStatusKindByUserID(status); - expect(result.status).toBe(status); - expect(result.isCheckedOut).toBe(false); - }); - - it('validating getCheckOutStatusKindByUserID - without "UserID" with locking user', () => { - var result = VersionControllerUtils.getCheckOutStatusKindByUserID(status, 'locking user'); - expect(result.status).toBe(statusEnum.LOCK_STATUS); - expect(result.isCheckedOut).toBe(false); - }); - - it('validating getCheckOutStatusKindByUserID - with "UserID" with configuration set', () => { - 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); - }); - - - - it('validating isCheckedOutByCurrentUser - when resource is not checked out', () => { - const resource = VersionControllerUtilsFactory.build({status: statusEnum.SUBMIT_STATUS}); - - Configuration.set('UserID', currentUser); - const result = VersionControllerUtils.isCheckedOutByCurrentUser(resource); - Configuration.set('UserID', undefined); - - expect(result).toBe(false); - }); - - it('validating isCheckedOutByCurrentUser - when resource is checked out', () => { - const resource = VersionControllerUtilsFactory.build(); - - Configuration.set('UserID', currentUser); - const result = VersionControllerUtils.isCheckedOutByCurrentUser(resource); - Configuration.set('UserID', undefined); - - expect(result).toBe(true); - }); - - it('validating isCheckedOutByCurrentUser - when resource is checked out by another user', () => { - const resource = VersionControllerUtilsFactory.build({lockingUser: 'another'}); - - Configuration.set('UserID', currentUser); - const result = VersionControllerUtils.isCheckedOutByCurrentUser(resource); - Configuration.set('UserID', undefined); - - expect(result).toBe(false); - }); - - - - it('validating isReadOnly - when resource is not checked out', () => { - const resource = VersionControllerUtilsFactory.build({status: statusEnum.SUBMIT_STATUS}); - - Configuration.set('UserID', currentUser); - const result = VersionControllerUtils.isReadOnly(resource); - Configuration.set('UserID', undefined); - - expect(result).toBe(true); - }); - - it('validating isReadOnly - when resource is checked out', () => { - const resource = VersionControllerUtilsFactory.build(); - - Configuration.set('UserID', currentUser); - const result = VersionControllerUtils.isReadOnly(resource); - Configuration.set('UserID', undefined); - - expect(result).toBe(false); - }); - - it('validating isReadOnly - when version of resource is not latest', () => { - - const resource = VersionControllerUtilsFactory.build({version: defaultVersions[defaultVersions.length - 2]}); - - Configuration.set('UserID', currentUser); - const result = VersionControllerUtils.isReadOnly(resource); - Configuration.set('UserID', undefined); - - expect(result).toBe(true); - }); - - it('validating isReadOnly - when resource is checked out by another user', () => { - const resource = VersionControllerUtilsFactory.build({lockingUser: 'another'}); - - Configuration.set('UserID', currentUser); - const result = VersionControllerUtils.isReadOnly(resource); - Configuration.set('UserID', undefined); - - expect(result).toBe(true); - }); -}); diff --git a/openecomp-ui/test/nfvo-components/tree/tree.test.js b/openecomp-ui/test/nfvo-components/tree/tree.test.js new file mode 100644 index 0000000000..95d0ae7f87 --- /dev/null +++ b/openecomp-ui/test/nfvo-components/tree/tree.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 Tree from 'nfvo-components/tree/Tree.jsx'; + +describe('Tree Module Tests', function () { + + it('Tree view should exist', () => { + expect(Tree).toBeTruthy(); + }); + + it('should render Tree and call onNodeClick', done => { + const tree = [{id: '123', name: '', parent: ''}]; + let treeView = new Tree({nodes: tree, onNodeClick: () => done()}); + expect(treeView).toBeTruthy(); + treeView.onNodeClick(tree[0]); + }); + +}); diff --git a/openecomp-ui/test/onboard/onboardingCatalog/views.test.js b/openecomp-ui/test/onboard/onboardingCatalog/views.test.js index fb038eb680..fedd25b160 100644 --- a/openecomp-ui/test/onboard/onboardingCatalog/views.test.js +++ b/openecomp-ui/test/onboard/onboardingCatalog/views.test.js @@ -20,6 +20,7 @@ import {defaultStoreFactory} from 'test-utils/factories/onboard/OnboardingCatalo 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 {catalogItemTypes} from 'sdc-app/onboarding/onboard/onboardingCatalog/OnboardingCatalogConstants.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'; @@ -49,9 +50,9 @@ describe('OnBoarding Catalog test - View: ', function () { 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 licenseModelList = FinalizedLicenseModelFactory.buildList(3); + const finalizedSoftwareProductList = VSPEditorFactory.buildList(4, {vendorId: finalizedLicenseModelList[0].id}); + const softwareProductList = VSPEditorFactory.buildList(4, {vendorId: finalizedLicenseModelList[1].id}); const data = defaultStoreFactory.build({licenseModelList, finalizedLicenseModelList, softwareProductList, finalizedSoftwareProductList}); var results = mapStateToProps(data); @@ -63,7 +64,7 @@ describe('OnBoarding Catalog test - View: ', function () { const dummyFunc = () => {}; const licenseModelList = FinalizedLicenseModelFactory.buildList(3); - const softwareProductList = VSPEditorFactory.buildList(4 ,{vendorId: licenseModelList[0].id}); + const softwareProductList = VSPEditorFactory.buildList(4, {vendorId: licenseModelList[0].id}); const data = defaultStoreFactory.build({licenseModelList, softwareProductList}); const func = { @@ -118,7 +119,7 @@ describe('OnBoarding Catalog test - View: ', function () { let params = { catalogItemData: FinalizedLicenseModelFactory.build(), onSelect: () => {}, - catalogItemTypeClass: '' + catalogItemTypeClass: catalogItemTypes.LICENSE_MODEL }; let CatalogItemDetailsView = TestUtils.renderIntoDocument(<div><CatalogItemDetails {...params}/></div>); diff --git a/openecomp-ui/test/permissions/permissionsManaager.test.js b/openecomp-ui/test/permissions/permissionsManaager.test.js new file mode 100644 index 0000000000..2d880c7ce0 --- /dev/null +++ b/openecomp-ui/test/permissions/permissionsManaager.test.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 React from 'react'; +import TestUtils from 'react-addons-test-utils'; + +import {UserFactory} from 'test-utils/factories/users/UsersFactories.js'; +import {mapStateToProps} from 'sdc-app/onboarding/permissions/PermissionsManager.js'; +import PermissionsManager from 'sdc-app/onboarding/permissions/PermissionsManager.jsx'; + + + +describe('Manage Permissions: ', function () { + let globalItemId = '343434', usersList = [], userInfo = {}, versionsPage = {}, contributor = {}, contributorToAdd = {}, owner = {}; + beforeAll(function() { + usersList = UserFactory.buildList(3); + userInfo = usersList[0]; + owner = usersList[0]; + contributor = usersList[1]; + contributorToAdd = usersList[2]; + versionsPage = { + permissions: { + owner: owner, + contributors: [contributor], + viewers: [] + } + }; + }); + + it('should mapper exist', () => { + expect(mapStateToProps).toBeTruthy(); + }); + + it('should mapper return basic permissions page data', () => { + const obj = {versionsPage, users: {usersList, userInfo}}; + const result = mapStateToProps(obj); + result.itemId = globalItemId; + expect(result.owner).toBeTruthy(); + expect(result.itemUsers).toBeTruthy(); + expect(result.userInfo).toBeTruthy(); + expect(result.itemId).toBeTruthy(); + expect(result.users).toBeTruthy(); + }); + + it('permission manager basic view', () => { + + const obj = {versionsPage, users: {usersList, userInfo}}; + const params = mapStateToProps(obj); + let permissionsView = TestUtils.renderIntoDocument(<PermissionsManager {...params}/>); + expect(permissionsView).toBeTruthy(); + }); + + it('permisssion manager onChange contributors test', () => { + + const obj = {versionsPage, users: {usersList, userInfo}}; + const params = mapStateToProps(obj); + params.itemId = globalItemId; + let permissionsView = TestUtils.renderIntoDocument(<PermissionsManager {...params}/>); + expect(permissionsView).toBeTruthy(); + const userToAdd = { + value: contributorToAdd.userId, + label: contributorToAdd.fullName + }; + let itemUsers = [{...userToAdd}]; + + permissionsView.onChangeItemUsers({itemUsers}); + expect(permissionsView.state.itemUsers[0].userId).toEqual(userToAdd.value); + }); + + it('permisssion manager onSave contributors test', () => { + + const obj = {versionsPage, users: {usersList, userInfo}}; + let params = mapStateToProps(obj); + params.itemId = globalItemId; + const userToAdd = { + value: contributorToAdd.userId, + label: contributorToAdd.fullName + }; + let itemUsers = [{...userToAdd}]; + + + params.onSubmit = ({itemId, addedUsersIds, removedUsersIds, allUsers, owner}) => { + expect(itemId).toEqual(globalItemId); + expect(addedUsersIds[0]).toEqual(contributorToAdd.userId); + expect(removedUsersIds[0]).toEqual(contributor.userId); + expect(allUsers).toEqual(usersList); + expect(owner).toEqual(owner); + }; + let permissionsView = TestUtils.renderIntoDocument(<PermissionsManager {...params}/>); + expect(permissionsView).toBeTruthy(); + permissionsView.onChangeItemUsers({itemUsers}); + permissionsView.onsaveItemUsers(); + }); + + + +});
\ No newline at end of file diff --git a/openecomp-ui/test/revisions/revisions.test.js b/openecomp-ui/test/revisions/revisions.test.js new file mode 100644 index 0000000000..1b5f35c9db --- /dev/null +++ b/openecomp-ui/test/revisions/revisions.test.js @@ -0,0 +1,240 @@ +/*! + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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 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 {actionsEnum as vcActionsEnum} from 'nfvo-components/panel/versionController/VersionControllerConstants.js'; +import Configuration from 'sdc-app/config/Configuration.js'; +import {mapStateToProps, mapActionsToProps} from 'sdc-app/onboarding/revisions/Revisions.js'; +import RevisionsView from 'sdc-app/onboarding/revisions/RevisionsView.jsx'; +import RevisionsActionHelper from 'sdc-app/onboarding/revisions/RevisionsActionHelper.js'; +import {RevisionsPagePropsFactory} from 'test-utils/factories/revisions/RevisionsFactories.js'; +import {UserFactory} from 'test-utils/factories/users/UsersFactories.js'; +import VersionFactory from 'test-utils/factories/common/VersionFactory.js'; +import {screenTypes} from 'sdc-app/onboarding/OnboardingConstants.js'; +import ReactTestUtils from 'react-addons-test-utils'; +import {enums} from 'sdc-app/onboarding/OnboardingConstants.js'; + +const state = {}; +state.revisions = RevisionsPagePropsFactory.buildList(2); +state.users = {usersList : UserFactory.buildList(2)}; +state.revisions[0].user = state.users.usersList[0].userId; +state.revisions[1].user = state.users.usersList[1].userId; + + +describe('Revision List Tests', () => { + /* + it ('mapStateToProps mapper exists', () => { + + expect(mapStateToProps).toBeTruthy(); + + }); + + it ('should have state in props', () => { + + const props = mapStateToProps(state); + expect(props.revisions.length).toEqual(2); + + }); + + it('simple jsx test', () => { + + const store = storeCreator(); + const dispatch = store.dispatch; + + const props = Object.assign({}, mapStateToProps(state), mapActionsToProps(dispatch, {})); + const renderer = TestUtils.createRenderer(); + renderer.render(<RevisionsView {...props} />); + + const renderedOutput = renderer.getRenderOutput(); + expect(renderedOutput).toBeTruthy(); + + }); + + it('get list data', () => { + + const store = storeCreator(); + const dispatch = store.dispatch; + + const props = Object.assign({}, mapStateToProps(state), mapActionsToProps(dispatch, {})); + + let revisionsView = TestUtils.renderIntoDocument( + <RevisionsView {...props} /> + ); + let list = scryRenderedDOMComponentsWithTestId(revisionsView,'revision-list-item'); + expect(list.length).toEqual(props.revisions.length); + let revert = scryRenderedDOMComponentsWithTestId(revisionsView,'form-submit-button'); + expect(revert[0].innerHTML).toEqual('Revert'); + let date = scryRenderedDOMComponentsWithTestId(revisionsView,'revision-date'); + expect(date.length).toEqual(props.revisions.length); + expect(date[0].children[0].className).toEqual('revision-date'); + expect(date[0].children[1].className).toEqual('revision-time'); + let user = ReactTestUtils.scryRenderedDOMComponentsWithClass(revisionsView, 'svg-icon-label'); + expect(user[0].innerHTML).toEqual(state.users.usersList[0].fullName); + expect(user[1].innerHTML).toEqual(state.users.usersList[1].fullName); + let message = scryRenderedDOMComponentsWithTestId(revisionsView,'revision-message'); + expect(message[0].children[0].innerHTML).toEqual('Show Message With More Mock'); + expect(message[1].children[0].innerHTML).toEqual('Show Message Mock'); + }); +*/ + +}); + + +describe('Revisions Action Helper', () => { + let store, dispatch, restPrefix = '', revisions, version; + let itemId = 'testRevisionId'; + + beforeAll(() => { + restPrefix = Configuration.get('restPrefix'); + store = storeCreator(); + dispatch = store.dispatch; + deepFreeze(store.getState()); + revisions = RevisionsPagePropsFactory.buildList(2); + version = VersionFactory.build(); + }); + + beforeEach(() => { + mockRest.resetQueue(); + }); + + + + it('Get revisions list', () => { + + const expectedStore = cloneAndSet(store.getState(), 'revisions', revisions); + mockRest.addHandler('fetch', ({options, data, baseUrl}) => { + expect(baseUrl).toEqual(`${restPrefix}/v1.0/items/${itemId}/versions/${version.id}/revisions`); + expect(data).toEqual(undefined); + expect(options).toEqual(undefined); + return {results: revisions}; + }); + + return RevisionsActionHelper.fetchRevisions(dispatch, {itemId, version}).then(() => { + expect(store.getState()).toEqual(expectedStore); + expect(store.getState().revisions.length).toEqual(2); + }); + }); +/* + it('Revert to revision software product model', () => { + mockRest.resetQueue(); + let revisionId = revisions[1].id; + mockRest.addHandler('put', ({options, data, baseUrl}) => { + expect(baseUrl).toEqual(`${restPrefix}/v1.0/items/${itemId}/versions/${version.id}/actions`); + expect(data).toEqual({ + action: vcActionsEnum.REVERT, + revisionRequest: { + revisionId: revisionId + } + + }); + expect(options).toEqual(undefined); + return {results: {}}; + }); + + mockRest.addHandler('fetch', ({options, data, baseUrl}) => { + expect(baseUrl).toEqual(`${restPrefix}/v1.0/items/${itemId}/versions/${version.id}`); + expect(data).toEqual(undefined); + expect(options).toEqual(undefined); + return {results: {}}; + }); + + mockRest.addHandler('fetch', ({options, data, baseUrl}) => { + expect(baseUrl).toEqual(`${restPrefix}/v1.0/vendor-software-products/${itemId}/versions/${version.id}`); + expect(data).toEqual(undefined); + expect(options).toEqual(undefined); + return {results: {}}; + }); + + + + mockRest.addHandler('fetch', ({options, data, baseUrl}) => { + expect(baseUrl).toEqual(`${restPrefix}/v1.0/vendor-software-products/${itemId}/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(`${restPrefix}/v1.0/vendor-software-products/${itemId}/versions/${version.id}/components`); + expect(data).toEqual(undefined); + expect(options).toEqual(undefined); + return {results: {}}; + }); + + + return RevisionsActionHelper.revertToRevision(dispatch, {itemId, version, revisionId, itemType: screenTypes.SOFTWARE_PRODUCT}).then(() => { + }); + + }); +*/ + it('Revert to revision license model', () => { + + let revisionId = revisions[0].id; + mockRest.addHandler('put', ({options, data, baseUrl}) => { + expect(baseUrl).toEqual(`${restPrefix}/v1.0/items/${itemId}/versions/${version.id}/actions`); + expect(data).toEqual({ + action: vcActionsEnum.REVERT, + revisionRequest: { + revisionId: revisionId + } + + }); + expect(options).toEqual(undefined); + return {results: {}}; + }); + + mockRest.addHandler('fetch', ({options, data, baseUrl}) => { + expect(baseUrl).toEqual(`${restPrefix}/v1.0/items/${itemId}/versions/${version.id}`); + expect(data).toEqual(undefined); + expect(options).toEqual(undefined); + return {results: {}}; + }); + + mockRest.addHandler('fetch', ({options, data, baseUrl}) => { + expect(baseUrl).toEqual(`${restPrefix}/v1.0/vendor-license-models/${itemId}/versions/${version.id}`); + expect(data).toEqual(undefined); + expect(options).toEqual(undefined); + return {results: {}}; + }); + + + let vlmFetched = ['license-agreements', 'feature-groups', 'entitlement-pools', 'license-key-groups']; + vlmFetched.forEach(fetchCall => { + mockRest.addHandler('fetch', ({options, data, baseUrl}) => { + expect(baseUrl).toEqual(`${restPrefix}/v1.0/vendor-license-models/${itemId}/versions/${version.id}/` + fetchCall); + expect(data).toEqual(undefined); + expect(options).toEqual(undefined); + return {results: {}}; + }); + }); + + + return RevisionsActionHelper.revertToRevision(dispatch, {itemId, version, revisionId, itemType: screenTypes.LICENSE_MODEL}).then(() => { + }); + + }); + + + + +}); diff --git a/openecomp-ui/test/softwareProduct/attachments/validation/HeatValidationView.test.js b/openecomp-ui/test/softwareProduct/attachments/validation/HeatValidationView.test.js index a5ba297d2b..a0a8a42660 100644 --- a/openecomp-ui/test/softwareProduct/attachments/validation/HeatValidationView.test.js +++ b/openecomp-ui/test/softwareProduct/attachments/validation/HeatValidationView.test.js @@ -19,8 +19,6 @@ 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', () => { @@ -41,7 +39,6 @@ describe('SoftwareProductAttachments Modal Mapper and View Classes', () => { id: 'D4774719D085414E9D5642D1ACD59D20', version: '0.10', viewableVersions: ['0.1', '0.2'], - status: versionStatusEnum.CHECK_OUT_STATUS, lockingUser: 'cs0008' }; const atTree = { diff --git a/openecomp-ui/test/softwareProduct/components/compute/SoftwareProductComponentComputeEditor.test.js b/openecomp-ui/test/softwareProduct/components/compute/SoftwareProductComponentComputeEditor.test.js index c14246f810..07268e514c 100644 --- a/openecomp-ui/test/softwareProduct/components/compute/SoftwareProductComponentComputeEditor.test.js +++ b/openecomp-ui/test/softwareProduct/components/compute/SoftwareProductComponentComputeEditor.test.js @@ -21,7 +21,7 @@ import ComputeEditorView from 'sdc-app/onboarding/softwareProduct/components/com import {SoftwareProductFactory} from 'test-utils/factories/softwareProduct/SoftwareProductFactory.js'; import {VSPEditorFactory} from 'test-utils/factories/softwareProduct/SoftwareProductEditorFactories.js'; import {ComputeFlavorBaseData, ComputeFlavorQData, VSPComponentsComputeDataMapFactory} from 'test-utils/factories/softwareProduct/SoftwareProductComponentsComputeFactory.js'; - +import CurrentScreenFactory from 'test-utils/factories/common/CurrentScreenFactory.js'; describe('Software Product Component Compute-Editor Mapper and View Classes.', () => { @@ -33,6 +33,7 @@ describe('Software Product Component Compute-Editor Mapper and View Classes.', ( const currentSoftwareProduct = VSPEditorFactory.build(); var obj = { + currentScreen: CurrentScreenFactory.build(), softwareProduct: SoftwareProductFactory.build({ softwareProductEditor: { data: currentSoftwareProduct @@ -58,7 +59,7 @@ describe('Software Product Component Compute-Editor Mapper and View Classes.', ( expect(results.qgenericFieldInfo).toBeTruthy(); expect(results.dataMap).toBeTruthy(); expect(results.genericFieldInfo).toBeTruthy(); - expect(results.isReadOnlyMode).toBeTruthy(); + expect(results.isReadOnlyMode).toBe(false); expect(results.isFormValid).toBeTruthy(); expect(results.formReady).toBeTruthy(); }); diff --git a/openecomp-ui/test/softwareProduct/components/compute/VSPComponentComputeActionHelperHeatMode.test.js b/openecomp-ui/test/softwareProduct/components/compute/VSPComponentComputeActionHelperHeatMode.test.js index 4fe9408e34..e8195314b4 100644 --- a/openecomp-ui/test/softwareProduct/components/compute/VSPComponentComputeActionHelperHeatMode.test.js +++ b/openecomp-ui/test/softwareProduct/components/compute/VSPComponentComputeActionHelperHeatMode.test.js @@ -22,11 +22,11 @@ import Configuration from 'sdc-app/config/Configuration.js'; import SoftwareProductComponentsActionHelper from 'sdc-app/onboarding/softwareProduct/components/SoftwareProductComponentsActionHelper.js'; import {ComputeFlavorQData, VSPComponentsComputeDataMapFactory} from 'test-utils/factories/softwareProduct/SoftwareProductComponentsComputeFactory.js'; -import VersionControllerUtilsFactory from 'test-utils/factories/softwareProduct/VersionControllerUtilsFactory.js'; +import VersionFactory from 'test-utils/factories/common/VersionFactory.js'; const softwareProductId = '123'; const vspComponentId = '111'; -const version = VersionControllerUtilsFactory.build().version; +const version = VersionFactory.build(); describe('Software Product Components Compute Module Tests - HEAT mode', function () { diff --git a/openecomp-ui/test/softwareProduct/components/compute/VSPComponentComputeActionHelperManualMode.test.js b/openecomp-ui/test/softwareProduct/components/compute/VSPComponentComputeActionHelperManualMode.test.js index ca3d12f3e9..addd800c43 100644 --- a/openecomp-ui/test/softwareProduct/components/compute/VSPComponentComputeActionHelperManualMode.test.js +++ b/openecomp-ui/test/softwareProduct/components/compute/VSPComponentComputeActionHelperManualMode.test.js @@ -19,14 +19,14 @@ import {cloneAndSet} from 'test-utils/Util.js'; import {storeCreator} from 'sdc-app/AppStore.js'; import Configuration from 'sdc-app/config/Configuration.js'; import ComputeFlavorActionHelper from 'sdc-app/onboarding/softwareProduct/components/compute/ComputeFlavorActionHelper.js'; -import {VSPEditorFactory} from 'test-utils/factories/softwareProduct/SoftwareProductEditorFactories.js'; +import VersionFactory from 'test-utils/factories/common/VersionFactory.js'; import {ComputeFlavorQData, ComputeFlavorBaseData, ComponentComputeFactory, VSPComponentsComputeDataMapFactory} from 'test-utils/factories/softwareProduct/SoftwareProductComponentsComputeFactory.js'; const softwareProductId = '123'; const vspComponentId = '111'; const computeId = '111'; -const version = VSPEditorFactory.build().version; +const version = VersionFactory.build(); describe('Software Product Components Compute Module Tests - Manual mode', function () { @@ -92,16 +92,6 @@ describe('Software Product Components Compute Module Tests - Manual mode', funct }; deepFreeze(softwareProductComponentCompute); - - const expectedStore = cloneAndSet(store.getState(), 'softwareProduct.softwareProductComponents.computeFlavor.computeEditor', { - data: computeData, - qdata, - dataMap, - qgenericFieldInfo: {}, - genericFieldInfo: {}, - formReady: true - }); - mockRest.addHandler('fetch', ({options, data, baseUrl}) => { expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-software-products/${softwareProductId}/versions/${version.id}/components/${vspComponentId}/compute-flavors/${computeId}`); expect(data).toEqual(undefined); @@ -109,15 +99,18 @@ describe('Software Product Components Compute Module Tests - Manual mode', funct return {data: computeData}; }); mockRest.addHandler('fetch', ({options, data, baseUrl}) => { - expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-software-products/${softwareProductId}/versions/${version.id}/components/${vspComponentId}/compute-flavors/${computeId}/questionnaire`); + expect(baseUrl).toEqual( + `/onboarding-api/v1.0/vendor-software-products/${softwareProductId}/versions/${version.id}/components/${vspComponentId}/compute-flavors/${computeId}/questionnaire` + ); expect(data).toEqual(undefined); expect(options).toEqual(undefined); return softwareProductComponentCompute; }); - return ComputeFlavorActionHelper.loadComputeData({softwareProductId, componentId: vspComponentId, version, computeId}).then(() => { - ComputeFlavorActionHelper.loadComputeQuestionnaire(store.dispatch, {softwareProductId, componentId: vspComponentId, computeId, version}).then(() => - expect(store.getState()).toEqual(expectedStore)); + return ComputeFlavorActionHelper.loadCompute(store.dispatch, {softwareProductId, componentId: vspComponentId, version, computeId}).then(() => { + expect(store.getState().softwareProduct.softwareProductComponents.computeFlavor.computeEditor.data).toEqual(computeData); + expect(store.getState().softwareProduct.softwareProductComponents.computeFlavor.computeEditor.qdata).toEqual(qdata); + expect(store.getState().softwareProduct.softwareProductComponents.computeFlavor.computeEditor.dataMap).toEqual(dataMap); }); }); @@ -142,7 +135,9 @@ describe('Software Product Components Compute Module Tests - Manual mode', funct deepFreeze(expectedStore); mockRest.addHandler('put', ({options, data, baseUrl}) => { - expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-software-products/${softwareProductId}/versions/${version.id}/components/${vspComponentId}/compute-flavors/${computeId}/questionnaire`); + expect(baseUrl).toEqual( + `/onboarding-api/v1.0/vendor-software-products/${softwareProductId}/versions/${version.id}/components/${vspComponentId}/compute-flavors/${computeId}/questionnaire` + ); expect(data).toEqual(qdata); expect(options).toEqual(undefined); return {returnCode: 'OK'}; diff --git a/openecomp-ui/test/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoring.test.js b/openecomp-ui/test/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoring.test.js index 423a7b39f6..21e58057e9 100644 --- a/openecomp-ui/test/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoring.test.js +++ b/openecomp-ui/test/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoring.test.js @@ -85,24 +85,18 @@ describe('SoftwareProductComponentsMonitoring Module Tests', function () { expect(renderedOutput).toBeTruthy(); }); - it('should change state to dragging', done => { + it('should change state to dragging', () => { var view = TestUtils.renderIntoDocument(<SoftwareProductComponentsMonitoringView />); expect(view.state.dragging).toBe(false); view.handleOnDragEnter(false); - setTimeout(()=> { - expect(view.state.dragging).toBe(true); - done(); - }, 100); + expect(view.state.dragging).toBe(true); }); - it('should not change state to dragging', done => { + it('should not change state to dragging', () => { var view = TestUtils.renderIntoDocument(<SoftwareProductComponentsMonitoringView />); expect(view.state.dragging).toBe(false); view.handleOnDragEnter(true); - setTimeout(()=> { - expect(view.state.dragging).toBe(false); - done(); - }, 0); + expect(view.state.dragging).toBe(false); }); }); diff --git a/openecomp-ui/test/softwareProduct/components/monitoring/test.js b/openecomp-ui/test/softwareProduct/components/monitoring/test.js index 8fafcdb968..50fda91871 100644 --- a/openecomp-ui/test/softwareProduct/components/monitoring/test.js +++ b/openecomp-ui/test/softwareProduct/components/monitoring/test.js @@ -16,16 +16,14 @@ import mockRest from 'test-utils/MockRest.js'; import {storeCreator} from 'sdc-app/AppStore.js'; -import SoftwareProductComponentsMonitoringConstants from 'sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringConstants.js'; import SoftwareProductComponentsMonitoringActionHelper from 'sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringActionHelper.js'; import {fileTypes} from 'sdc-app/onboarding/softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringConstants.js'; - +import VersionFactory from 'test-utils/factories/common/VersionFactory.js'; import {VSPComponentsMonitoringRestFactory, trap, poll, ves} from 'test-utils/factories/softwareProduct/SoftwareProductComponentsMonitoringFactories.js'; -import VersionControllerUtilsFactory from 'test-utils/factories/softwareProduct/VersionControllerUtilsFactory.js'; const softwareProductId = '123'; const componentId = '123'; -const version = VersionControllerUtilsFactory.build().version; +const version = VersionFactory.build(); describe('Software Product Components Monitoring Module Tests', function () { @@ -132,7 +130,7 @@ describe('Software Product Components Monitoring Module Tests', function () { version, componentId, type: fileTypes.SNMP_TRAP - }).then((dispatch) => { + }).then(() => { var {softwareProduct: {softwareProductComponents: {monitoring}}} = store.getState(); expect(monitoring[trap]).toEqual(undefined); done(); diff --git a/openecomp-ui/test/softwareProduct/components/network/SoftwareProductComponentsNICEditor.test.js b/openecomp-ui/test/softwareProduct/components/network/SoftwareProductComponentsNICEditor.test.js index 094b95a091..78d88b008a 100644 --- a/openecomp-ui/test/softwareProduct/components/network/SoftwareProductComponentsNICEditor.test.js +++ b/openecomp-ui/test/softwareProduct/components/network/SoftwareProductComponentsNICEditor.test.js @@ -23,6 +23,7 @@ import {VSPEditorFactory} from 'test-utils/factories/softwareProduct/SoftwarePro import {SoftwareProductFactory} from 'test-utils/factories/softwareProduct/SoftwareProductFactory.js'; import {VSPComponentsNicFactory, VSPComponentsNetworkQDataFactory, VSPComponentsNicFactoryQGenericFieldInfo, VSPComponentsNicFactoryGenericFieldInfo, VSPComponentsNetworkDataMapFactory} from 'test-utils/factories/softwareProduct/SoftwareProductComponentsNetworkFactories.js'; +import CurrentScreenFactory from 'test-utils/factories/common/CurrentScreenFactory.js'; describe('Software Product Component Network NIC Editor and View Classes', () => { it('mapStateToProps mapper exists', () => { @@ -34,8 +35,8 @@ describe('Software Product Component Network NIC Editor and View Classes', () => const currentSoftwareProduct = VSPEditorFactory.build(); - var obj = { + currentScreen: CurrentScreenFactory.build(), softwareProduct: SoftwareProductFactory.build({ softwareProductEditor: { data: currentSoftwareProduct @@ -55,12 +56,14 @@ describe('Software Product Component Network NIC Editor and View Classes', () => }; var results = mapStateToProps(obj); + expect(results.isReadOnlyMode).toBe(false); expect(results.currentSoftwareProduct).toBeTruthy(); expect(results.qdata).toBeTruthy(); expect(results.dataMap).toBeTruthy(); expect(results.genericFieldInfo).toBeTruthy(); expect(results.qgenericFieldInfo).toBeTruthy(); expect(results.data).toBeTruthy(); + }); diff --git a/openecomp-ui/test/softwareProduct/components/network/SoftwareProductComponentsNetworkActionHelper.test.js b/openecomp-ui/test/softwareProduct/components/network/SoftwareProductComponentsNetworkActionHelper.test.js index b6050265a6..11a0ca787f 100644 --- a/openecomp-ui/test/softwareProduct/components/network/SoftwareProductComponentsNetworkActionHelper.test.js +++ b/openecomp-ui/test/softwareProduct/components/network/SoftwareProductComponentsNetworkActionHelper.test.js @@ -19,15 +19,20 @@ 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 {VSPComponentsNicPostFactory, VSPComponentsNicFactory, VSPComponentsNetworkFactory, VSPComponentsNetworkQDataFactory, VSPComponentsNetworkDataMapFactory, VSPComponentsNicFactoryGenericFieldInfo} from 'test-utils/factories/softwareProduct/SoftwareProductComponentsNetworkFactories.js'; -import VersionControllerUtilsFactory from 'test-utils/factories/softwareProduct/VersionControllerUtilsFactory.js'; +import {VSPComponentsNicFactory, + VSPComponentsNicPostFactory, + VSPComponentsNetworkFactory, + VSPComponentsNetworkQDataFactory, + VSPComponentsNetworkDataMapFactory, + VSPComponentsNicFactoryGenericFieldInfo} from 'test-utils/factories/softwareProduct/SoftwareProductComponentsNetworkFactories.js'; +import VersionFactory from 'test-utils/factories/common/VersionFactory.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; +const version = VersionFactory.build(); describe('Software Product Components Network Action Helper Tests', function () { @@ -55,60 +60,62 @@ describe('Software Product Components Network Action Helper Tests', function () }); }); + it('Add NIC', () => { - const store = storeCreator(); - deepFreeze(store.getState()); - - const NICPostRequest = VSPComponentsNicPostFactory.build(); - - const expectedNIC = VSPComponentsNicFactory.build({...NICPostRequest, id: nicId}); - - mockRest.addHandler('post', ({options, data, baseUrl}) => { - expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-software-products/${softwareProductId}/versions/${version.id}/components/${componentId}/nics`); - expect(data).toEqual(NICPostRequest); - expect(options).toEqual(undefined); - return { - nicId - }; - }); - - mockRest.addHandler('fetch', ({options, data, baseUrl}) => { - expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-software-products/${softwareProductId}/versions/${version.id}/components/${componentId}/nics`); - expect(data).toEqual(undefined); - expect(options).toEqual(undefined); - return {results: [expectedNIC]}; - }); - - mockRest.addHandler('destroy', ({options, data, baseUrl}) => { - expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-software-products/${softwareProductId}/versions/${version.id}/components/${componentId}/nics/${nicId}`); - expect(data).toEqual(undefined); - expect(options).toEqual(undefined); - return {}; - }); - - mockRest.addHandler('fetch', ({options, data, baseUrl}) => { - expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-software-products/${softwareProductId}/versions/${version.id}/components/${componentId}/nics`); - expect(data).toEqual(undefined); - expect(options).toEqual(undefined); - return {results: []}; - }); - - const network = VSPComponentsNetworkFactory.build({ - nicList: [expectedNIC] - }); - - const networkAfterDelete = VSPComponentsNetworkFactory.build(); - - let expectedStore = cloneAndSet(store.getState(), 'softwareProduct.softwareProductComponents.network', network); - - return SoftwareProductComponentsNetworkActionHelper.createNIC(store.dispatch, {nic: NICPostRequest, softwareProductId, componentId, version}).then(() => { - expect(store.getState()).toEqual(expectedStore); - return SoftwareProductComponentsNetworkActionHelper.deleteNIC(store.dispatch, {softwareProductId, componentId, nicId, version}); - }).then(() => { - let expectedStore = cloneAndSet(store.getState(), 'softwareProduct.softwareProductComponents.network', networkAfterDelete); - expect(store.getState()).toEqual(expectedStore); - }); + const store = storeCreator(); + deepFreeze(store.getState()); + + const NICPostRequest = VSPComponentsNicPostFactory.build(); + + const expectedNIC = VSPComponentsNicFactory.build({...NICPostRequest, id: nicId}); + + mockRest.addHandler('post', ({options, data, baseUrl}) => { + expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-software-products/${softwareProductId}/versions/${version.id}/components/${componentId}/nics`); + expect(data).toEqual(NICPostRequest); + expect(options).toEqual(undefined); + return { + nicId + }; + }); + + mockRest.addHandler('fetch', ({options, data, baseUrl}) => { + expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-software-products/${softwareProductId}/versions/${version.id}/components/${componentId}/nics`); + expect(data).toEqual(undefined); + expect(options).toEqual(undefined); + return {results: [expectedNIC]}; + }); + + mockRest.addHandler('destroy', ({options, data, baseUrl}) => { + expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-software-products/${softwareProductId}/versions/${version.id}/components/${componentId}/nics/${nicId}`); + expect(data).toEqual(undefined); + expect(options).toEqual(undefined); + return {}; }); + + mockRest.addHandler('fetch', ({options, data, baseUrl}) => { + expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-software-products/${softwareProductId}/versions/${version.id}/components/${componentId}/nics`); + expect(data).toEqual(undefined); + expect(options).toEqual(undefined); + return {results: []}; + }); + + const network = VSPComponentsNetworkFactory.build({ + nicList: [expectedNIC] + }); + + const networkAfterDelete = VSPComponentsNetworkFactory.build(); + + let expectedStore = cloneAndSet(store.getState(), 'softwareProduct.softwareProductComponents.network', network); + + return SoftwareProductComponentsNetworkActionHelper.createNIC(store.dispatch, {nic: NICPostRequest, softwareProductId, componentId, version}).then(() => { + expect(store.getState()).toEqual(expectedStore); + return SoftwareProductComponentsNetworkActionHelper.deleteNIC(store.dispatch, {softwareProductId, componentId, nicId, version}); + }).then(() => { + let expectedStore = cloneAndSet(store.getState(), 'softwareProduct.softwareProductComponents.network', networkAfterDelete); + expect(store.getState()).toEqual(expectedStore); + }); + }); + it('open NICE editor', () => { const store = storeCreator(); @@ -172,7 +179,6 @@ describe('Software Product Components Network Action Helper Tests', function () }); }); - it('load NIC Questionnaire', () => { mockRest.resetQueue(); const store = storeCreator(); diff --git a/openecomp-ui/test/softwareProduct/components/processes/SoftwareProductComponentsProcessesView.test.js b/openecomp-ui/test/softwareProduct/components/processes/SoftwareProductComponentsProcessesView.test.js index ac866727a6..921d1bbc90 100644 --- a/openecomp-ui/test/softwareProduct/components/processes/SoftwareProductComponentsProcessesView.test.js +++ b/openecomp-ui/test/softwareProduct/components/processes/SoftwareProductComponentsProcessesView.test.js @@ -66,8 +66,8 @@ describe('SoftwareProductComponetsProcesses Mapper and View Classes', () => { softwareProductId={currentSoftwareProduct.id} componentId={currentSoftwareProductComponent.id} onAddProcess={() => {}} - onEditProcessClick={() => {}} - onDeleteProcessClick={() => {}} + onEditProcess={() => {}} + onDeleteProcess={() => {}} isDisplayEditor={false} isReadOnlyMode={false}/> ); diff --git a/openecomp-ui/test/softwareProduct/components/storage/test.js b/openecomp-ui/test/softwareProduct/components/storage/test.js index 138c4da7d6..1cc0c7b636 100644 --- a/openecomp-ui/test/softwareProduct/components/storage/test.js +++ b/openecomp-ui/test/softwareProduct/components/storage/test.js @@ -22,11 +22,11 @@ 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'; +import VersionFactory from 'test-utils/factories/common/VersionFactory.js'; const softwareProductId = '123'; const vspComponentId = '111'; -const version = VersionControllerUtilsFactory.build().version; +const version = VersionFactory.build(); describe('Software Product Components Storage Module Tests', function () { diff --git a/openecomp-ui/test/softwareProduct/components/test.js b/openecomp-ui/test/softwareProduct/components/test.js index b3994b1461..ab379937c0 100644 --- a/openecomp-ui/test/softwareProduct/components/test.js +++ b/openecomp-ui/test/softwareProduct/components/test.js @@ -20,11 +20,11 @@ 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'; +import VersionFactory from 'test-utils/factories/common/VersionFactory.js'; const softwareProductId = '123'; const vspComponentId = '321'; -const version = VersionControllerUtilsFactory.build().version; +const version = VersionFactory.build(); describe('Software Product Components Module Tests', function () { it('Get Software Products Components List', () => { diff --git a/openecomp-ui/test/softwareProduct/creation/SoftwareProductCreation.test.js b/openecomp-ui/test/softwareProduct/creation/SoftwareProductCreation.test.js index c7c55bdbaf..0b46721da0 100644 --- a/openecomp-ui/test/softwareProduct/creation/SoftwareProductCreation.test.js +++ b/openecomp-ui/test/softwareProduct/creation/SoftwareProductCreation.test.js @@ -35,6 +35,9 @@ describe('Software Product Creation Module Tests', function() { softwareProductCreation: { data: {} } + }, + users: { + usersList: [] } }; let props = mapStateToProps(state); @@ -54,6 +57,9 @@ describe('Software Product Creation Module Tests', function() { softwareProductCreation: { data: {} } + }, + users: { + usersList: [] } }; let props = mapStateToProps(state); @@ -71,7 +77,10 @@ describe('Software Product Creation Module Tests', function() { softwareProductCreation: SoftwareProductCreationFactory.build(), softwareProductCategories: CategoryWithSubFactory.buildList({}, {quantity: 2}) }, - finalizedLicenseModelList: FinalizedLicenseModelFactory.buildList(3) + finalizedLicenseModelList: FinalizedLicenseModelFactory.buildList(3), + users: { + usersList: [] + } }; let props = Object.assign({}, mapStateToProps(state), mapActionsToProps(dispatch)); var renderer = TestUtils.createRenderer(); @@ -92,7 +101,10 @@ describe('Software Product Creation Module Tests', function() { softwareProductCreation: SoftwareProductCreationFactoryWithSelectedVendor.build({selectedVendorId: finalizedLicenseModelList[0].id}), softwareProductCategories: CategoryWithSubFactory.buildList({}, {quantity: 2}) }, - finalizedLicenseModelList + finalizedLicenseModelList, + users: { + usersList: [] + } }; let props = Object.assign({}, mapStateToProps(state), mapActionsToProps(dispatch)); let renderer = TestUtils.createRenderer(); diff --git a/openecomp-ui/test/softwareProduct/dependencies/SoftwareProductDependencies.test.js b/openecomp-ui/test/softwareProduct/dependencies/SoftwareProductDependencies.test.js index 5325a58959..595a93fe60 100644 --- a/openecomp-ui/test/softwareProduct/dependencies/SoftwareProductDependencies.test.js +++ b/openecomp-ui/test/softwareProduct/dependencies/SoftwareProductDependencies.test.js @@ -21,34 +21,45 @@ 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 VersionFactory from 'test-utils/factories/common/VersionFactory.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 {relationTypes, NEW_RULE_TEMP_ID} from 'sdc-app/onboarding/softwareProduct/dependencies/SoftwareProductDependenciesConstants.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'; +function addNewRowElement(arr, data) { + if (data === undefined) { + arr.push({id: NEW_RULE_TEMP_ID, targetId: null, sourceId: null, relationType: relationTypes.DEPENDS_ON}); + } else { + arr.push(data); + } +} + describe('Software Product Dependencies Module Tests', function () { const softwareProductId = '555'; - const version = VersionControllerUtilsFactory.build().version; + const version = VersionFactory.build(); + 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)); + addNewRowElement(DependenciesListStore); 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(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-software-products/${softwareProductId}/versions/${version.id}/component-dependencies`); expect(data).toEqual(undefined); expect(options).toEqual(undefined); return {results: DependenciesListResponse}; @@ -59,92 +70,201 @@ describe('Software Product Dependencies Module Tests', function () { 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', () => { + /* + Test update: + - fetch initial item + - update existing item + - auto fetch again + */ + it('Update Software Product Dependency', () => { const store = storeCreator(); const dispatch = store.dispatch; - let DependenciesListResponse = SoftwareProductDependenciesResponseFactory.buildList(3); + let DependenciesListResponse = SoftwareProductDependenciesResponseFactory.buildList(1); let DependenciesListStore = DependenciesListResponse.map(dependency => SoftwareProductDependenciesStoreFactory.build(dependency)); + addNewRowElement(DependenciesListStore); 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(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-software-products/${softwareProductId}/versions/${version.id}/component-dependencies`); 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); - + let item = expectedStoreDependencies.find((dep) => dep.id !== NEW_RULE_TEMP_ID); + item.targetId = 'testChangeTarget'; + item.sourceId = 'testChangesource'; + // removing 'new row' from response + expectedStoreDependencies = expectedStoreDependencies.slice(0, expectedStoreDependencies.length - 1); + let expDependenciesListStore = expectedStoreDependencies.map(dependency => SoftwareProductDependenciesStoreFactory.build(dependency)); + + mockRest.addHandler('put', ({data, options, baseUrl}) => { + expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-software-products/${softwareProductId}/versions/${version.id}/component-dependencies/${item.id}`); + expect(data.targetId).toEqual('testChangeTarget'); + expect(data.sourceId).toEqual('testChangesource'); + expect(options).toEqual(undefined); + return {results: null}; + }); + mockRest.addHandler('fetch', ({data, options, baseUrl}) => { + expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-software-products/${softwareProductId}/versions/${version.id}/component-dependencies`); + expect(data).toEqual(undefined); + expect(options).toEqual(undefined); + return {results: expDependenciesListStore}; + }); + + addNewRowElement(expectedStoreDependencies); const newExpectedStore = cloneAndSet(expectedStore, 'softwareProduct.softwareProductDependencies', expectedStoreDependencies); + return SoftwareProductDependenciesActionHelper.updateDependency(dispatch, {softwareProductId, version, item}).then(() => { + const newState = store.getState(); + expect(newState).toEqual(newExpectedStore); - SoftwareProductDependenciesActionHelper.updateDependencyList(dispatch, {dependenciesList: expectedStoreDependencies}); - const newState = store.getState(); - expect(newState).toEqual(newExpectedStore); + }); }); }); - it('Add And Save Software Product Dependencies List', () => { + /* + - Fetch item list + - Delete item from list + - Fetch again + */ + it('Delete Software Product Dependency', () => { const store = storeCreator(); const dispatch = store.dispatch; + let DependenciesListResponse = SoftwareProductDependenciesResponseFactory.buildList(1); + let DependenciesListStore = DependenciesListResponse.map(dependency => SoftwareProductDependenciesStoreFactory.build(dependency)); + addNewRowElement(DependenciesListStore); + const expectedStore = cloneAndSet(store.getState(), 'softwareProduct.softwareProductDependencies', DependenciesListStore); - let mockServerDependencies = []; + let deleteItem = DependenciesListStore.find((dep) => dep.id !== NEW_RULE_TEMP_ID); - 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); + mockRest.addHandler('fetch', ({data, options, baseUrl}) => { + expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-software-products/${softwareProductId}/versions/${version.id}/component-dependencies`); + expect(data).toEqual(undefined); + expect(options).toEqual(undefined); + return {results: DependenciesListResponse}; + }); + mockRest.addHandler('destroy', ({data, options, baseUrl}) => { + expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-software-products/${softwareProductId}/versions/${version.id}/component-dependencies/${deleteItem.id}`); + expect(data).toEqual(undefined); + expect(options).toEqual(undefined); + return {results: null}; + }); + 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 newDependencies = SoftwareProductDependenciesStoreFactory.buildList(1); - const expectedStore = cloneAndSet(store.getState(), 'softwareProduct.softwareProductDependencies', newDependencies); - SoftwareProductDependenciesActionHelper.updateDependencyList(dispatch, {dependenciesList: newDependencies}); + const newExpectedStore = cloneAndSet(expectedStore, 'softwareProduct.softwareProductDependencies', expectedStoreDependencies); + expect(state).toEqual(newExpectedStore); - 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'}; + expectedStoreDependencies = expectedStoreDependencies.filter((dep) => dep.id !== deleteItem.id); + const postDeleteExpectedStore = cloneAndSet(expectedStore, 'softwareProduct.softwareProductDependencies', expectedStoreDependencies); + + mockRest.addHandler('fetch', ({data, options, baseUrl}) => { + expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-software-products/${softwareProductId}/versions/${version.id}/component-dependencies`); + expect(data).toEqual(undefined); + expect(options).toEqual(undefined); + return {results: []}; + }); + + return SoftwareProductDependenciesActionHelper.removeDependency(dispatch, {softwareProductId, version, item: deleteItem}).then(() => { + const state = store.getState(); + const depndenciesWithGeneratedId = state.softwareProduct.softwareProductDependencies; + const currentDependencies = postDeleteExpectedStore.softwareProduct.softwareProductDependencies; + expect(depndenciesWithGeneratedId).toEqual(currentDependencies); + }); }); + }); + + /* + - Create initial list + - Update the new row and make sure there is no API call + - Submit the new row + - Getch data with reset new row and new entity with info from the new item + */ + + it('Create Software Product Dependency', () => { + const store = storeCreator(); + const dispatch = store.dispatch; + + let DependenciesListResponse = SoftwareProductDependenciesResponseFactory.buildList(1); + let DependenciesListStore = DependenciesListResponse.map(dependency => SoftwareProductDependenciesStoreFactory.build(dependency)); + addNewRowElement(DependenciesListStore); + 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(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-software-products/${softwareProductId}/versions/${version.id}/component-dependencies`); expect(data).toEqual(undefined); expect(options).toEqual(undefined); - return {results: mockServerDependencies}; + return {results: DependenciesListResponse}; }); + return SoftwareProductDependenciesActionHelper.fetchDependencies(dispatch, {softwareProductId, version}).then(() => { + // setting properties on the 'new role' should not call an API + let addItem = {id: NEW_RULE_TEMP_ID, sourceId: 'sId', targetId : 'tId',relationType: relationTypes.DEPENDS_ON}; + try { + SoftwareProductDependenciesActionHelper.updateDependency(dispatch, {softwareProductId, version, item: addItem}).then(()=> { + //go to error that fetch was not defined + }); + } catch (error) { + if(error.name === 'TypeError') { + // Expected error because we expected there is no promise + } else { + fail('Error:' + error); + } + } - 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})); + // creating the new item + let item = SoftwareProductDependenciesResponseFactory.buildList(1, + {sourceId: 'sId', targetId : 'tId',relationType: relationTypes.DEPENDS_ON})[0]; + addNewRowElement(expectedStoreDependencies, item); + expectedStoreDependencies = expectedStoreDependencies.filter((dep) => dep.id !== NEW_RULE_TEMP_ID); + + mockRest.addHandler('post', ({data, options, baseUrl}) => { + expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-software-products/${softwareProductId}/versions/${version.id}/component-dependencies`); + expect(data.targetId).toEqual('tId'); + expect(data.sourceId).toEqual('sId'); + expect(data.id).toEqual(undefined); + expect(options).toEqual(undefined); + return {results: item.id}; + }); + mockRest.addHandler('fetch', ({data, options, baseUrl}) => { + expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-software-products/${softwareProductId}/versions/${version.id}/component-dependencies`); + expect(data).toEqual(undefined); + expect(options).toEqual(undefined); + return {results: expectedStoreDependencies}; + }); + + let PostCreateItemListStore = expectedStoreDependencies.map(dependency => SoftwareProductDependenciesStoreFactory.build(dependency)); + addNewRowElement(PostCreateItemListStore); + const newExpectedStore = cloneAndSet(store.getState(), 'softwareProduct.softwareProductDependencies', PostCreateItemListStore); + + return SoftwareProductDependenciesActionHelper.createDependency(dispatch, {softwareProductId, version, item: addItem}).then(() => { + const newState = store.getState(); + expect(newState.softwareProduct.softwareProductDependencies.length).toEqual(3); + expect(newState).toEqual(newExpectedStore); + }); - 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; @@ -161,10 +281,11 @@ describe('Software Product Dependencies Module Tests', function () { secondDependency.targetId = firstDependecy.sourceId; let DependenciesListStore = DependenciesListResponse.map(dependency => SoftwareProductDependenciesStoreFactory.build({...dependency, hasCycle: true})); + addNewRowElement(DependenciesListStore); 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(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-software-products/${softwareProductId}/versions/${version.id}/component-dependencies`); expect(data).toEqual(undefined); expect(options).toEqual(undefined); return {results: DependenciesListResponse}; @@ -187,9 +308,9 @@ describe('Software Product Dependencies Module Tests', function () { let expectedStoreDependencies = currentDependencies.map((dependency, index) => ({...dependency, id: depndenciesWithGeneratedId[index].id})); const newExpectedStore = { - ...expectedStore, + ...expectedStore, softwareProduct: { - ...expectedStore.softwareProduct, + ...expectedStore.softwareProduct, softwareProductDependencies: expectedStoreDependencies, softwareProductEditor: {data: vspEditor}, softwareProductComponents: { @@ -207,4 +328,5 @@ describe('Software Product Dependencies Module Tests', function () { expect(wrapper).toBeTruthy(); }); }); -});
\ No newline at end of file + +}); diff --git a/openecomp-ui/test/softwareProduct/deployment/SoftwareProductDeploymentEditor.test.js b/openecomp-ui/test/softwareProduct/deployment/SoftwareProductDeploymentEditor.test.js index 4277f28ee8..c355d9d273 100644 --- a/openecomp-ui/test/softwareProduct/deployment/SoftwareProductDeploymentEditor.test.js +++ b/openecomp-ui/test/softwareProduct/deployment/SoftwareProductDeploymentEditor.test.js @@ -20,6 +20,7 @@ import SoftwareProductDeploymentEditorView from 'sdc-app/onboarding/softwareProd import { VSPComponentsFactory } from 'test-utils/factories/softwareProduct/SoftwareProductComponentsFactories.js'; import { VSPEditorFactoryWithLicensingData } from 'test-utils/factories/softwareProduct/SoftwareProductEditorFactories.js'; import { FeatureGroupStoreFactory } from 'test-utils/factories/licenseModel/FeatureGroupFactories.js'; +import CurrentScreenFactory from 'test-utils/factories/common/CurrentScreenFactory.js'; describe('Software Product Deployment Editor Module Tests', function () { @@ -32,8 +33,10 @@ describe('Software Product Deployment Editor Module Tests', function () { const currentSoftwareProduct = VSPEditorFactoryWithLicensingData.build(); const componentsList = VSPComponentsFactory.buildList(1); const featureGroupsList = FeatureGroupStoreFactory.buildList(2); + const currentScreen = CurrentScreenFactory.build(); var state = { + currentScreen, softwareProduct: { softwareProductEditor: { data: currentSoftwareProduct diff --git a/openecomp-ui/test/softwareProduct/details/detailsView.test.js b/openecomp-ui/test/softwareProduct/details/detailsView.test.js index 37c5df5079..d83fedaf7d 100644 --- a/openecomp-ui/test/softwareProduct/details/detailsView.test.js +++ b/openecomp-ui/test/softwareProduct/details/detailsView.test.js @@ -24,10 +24,12 @@ import {FeatureGroupStoreFactory} from 'test-utils/factories/licenseModel/Featu 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'; +import VersionFactory from 'test-utils/factories/common/VersionFactory.js'; +import CurrentScreenFactory from 'test-utils/factories/common/CurrentScreenFactory.js'; describe('Software Product Details: ', function () { - let currentSoftwareProduct = {}, currentSoftwareProductWithLicensingData = {}, softwareProductCategories = [], + let currentSoftwareProduct = {}, currentSoftwareProductWithLicensingData = {}, softwareProductCategories = [], licensingVersionsList = [], currentScreen = {}, finalizedLicenseModelList, licenseAgreementList, featureGroupsList, qdata = {}, dataMap = {}, genericFieldInfo = {}, qGenericFieldInfo = {}; let dummyFunc = () => {}; @@ -35,11 +37,18 @@ describe('Software Product Details: ', function () { finalizedLicenseModelList = FinalizedLicenseModelFactory.buildList(2); currentSoftwareProduct = VSPEditorFactory.build({ id: 'RTRTG454545', + licensingVersion: undefined, vendorId: finalizedLicenseModelList[0].id, - vendorName: finalizedLicenseModelList[0].vendorName + vendorName: finalizedLicenseModelList[0].name }); softwareProductCategories = CategoryWithSubFactory.buildList(2, {}, {quantity: 1}); licenseAgreementList = LicenseAgreementStoreFactory.buildList(2); + licensingVersionsList = [ + { + "id":"0127b419e9574a11aab8e031a78fc534", + "name":"1.0","description":"Initial version", + "baseId":"","status":"Certified","creationTime":1506409288390,"modificationTime":1506409288390,"additionalInfo":{"OptionalCreationMethods":["minor"]}},{"id":"ea159ffedd9a4f9a8a56d53ba66b7314","name":"2.0","description":"ggggg","baseId":"0127b419e9574a11aab8e031a78fc534","status":"Draft","creationTime":1508839019802,"modificationTime":1508839019802,"additionalInfo":{"OptionalCreationMethods":[]}} + ]; featureGroupsList = FeatureGroupStoreFactory.buildList(2, {referencingLicenseAgreements: [licenseAgreementList[0].id]}); qdata = VspQdataFactory.build(); dataMap = VspDataMapFactory.build(); @@ -48,7 +57,8 @@ describe('Software Product Details: ', function () { licensingData: { licenseAgreement: licenseAgreementList[0].id, featureGroups: [featureGroupsList[0].id] - } + }, + licensingVersion : licensingVersionsList[0].id }; genericFieldInfo = { 'name': { @@ -66,6 +76,7 @@ describe('Software Product Details: ', function () { } }; qGenericFieldInfo = SchemaGenericFieldInfoFactory.build(); + currentScreen = CurrentScreenFactory.build(); }); it('should mapper exist', () => { @@ -75,10 +86,12 @@ describe('Software Product Details: ', function () { it('should mapper return vsp basic data', () => { var obj = { + currentScreen, softwareProduct: { softwareProductEditor: { data: currentSoftwareProduct, - genericFieldInfo + genericFieldInfo, + licensingVersionsList }, softwareProductCategories, softwareProductQuestionnaire: { @@ -104,7 +117,7 @@ describe('Software Product Details: ', function () { expect(result.finalizedLicenseModelList.length).toBeGreaterThan(0); expect(finalizedLicenseModelList[0]).toMatchObject({ id: result.currentSoftwareProduct.vendorId, - vendorName: result.currentSoftwareProduct.vendorName + name: result.currentSoftwareProduct.vendorName }); expect(result.softwareProductCategories).toEqual(softwareProductCategories); expect(result.licenseAgreementList).toEqual([]); @@ -112,16 +125,17 @@ describe('Software Product Details: ', function () { 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', () => { var obj = { + currentScreen, softwareProduct: { softwareProductEditor: { data: currentSoftwareProductWithLicensingData, - genericFieldInfo + genericFieldInfo, + licensingVersionsList }, softwareProductCategories, softwareProductQuestionnaire: { @@ -147,7 +161,7 @@ describe('Software Product Details: ', function () { expect(result.finalizedLicenseModelList.length).toBeGreaterThan(0); expect(result.finalizedLicenseModelList[0]).toMatchObject({ id: result.currentSoftwareProduct.vendorId, - vendorName: result.currentSoftwareProduct.vendorName + name: result.currentSoftwareProduct.vendorName }); expect(result.softwareProductCategories).toEqual(softwareProductCategories); expect(result.licenseAgreementList).toEqual(licenseAgreementList); @@ -156,12 +170,12 @@ describe('Software Product Details: ', function () { expect(featureGroupsList[0]).toMatchObject({...featureGroupsList[0], id: fg}); }); expect(result.qdata).toEqual(qdata); - expect(result.isReadOnlyMode).toEqual(true); }); it('VSP Details view test', () => { let params = { + ...currentScreen.props, currentSoftwareProduct, softwareProductCategories, qdata, @@ -170,6 +184,7 @@ describe('Software Product Details: ', function () { finalizedLicenseModelList, licenseAgreementList, featureGroupsList, + licensingVersionsList, genericFieldInfo, qGenericFieldInfo, }; @@ -185,6 +200,8 @@ describe('Software Product Details: ', function () { ); let renderedOutput = renderer.getRenderOutput(); expect(renderedOutput).toBeTruthy(); + expect(renderedOutput.props.children.props.isReadOnlyMode).toBe(false); + }); it('in view: should change vendorId and update vsp licensing-version', done => { @@ -199,11 +216,12 @@ describe('Software Product Details: ', function () { qGenericFieldInfo, finalizedLicenseModelList, licenseAgreementList, + licensingVersionsList, featureGroupsList }; const onVendorChangedListener = (deltaData) => { expect(deltaData.vendorId).toEqual(finalizedLicenseModelList[1].id); - expect(deltaData.vendorName).toEqual(finalizedLicenseModelList[1].vendorName); + expect(deltaData.vendorName).toEqual(finalizedLicenseModelList[1].name); expect(deltaData.licensingVersion).toEqual(''); expect(deltaData.licensingData).toEqual({}); done(); @@ -215,6 +233,7 @@ describe('Software Product Details: ', function () { qdata = {params.qdata} qGenericFieldInfo = {params.qGenericFieldInfo} genericFieldInfo = {params.genericFieldInfo} + licensingVersionsList={params.licensingVersionsList} isFormValid={params.isFormValid} dataMap={params.dataMap} finalizedLicenseModelList = {params.finalizedLicenseModelList} @@ -235,6 +254,7 @@ describe('Software Product Details: ', function () { softwareProductCategories, qdata, dataMap, + licensingVersionsList, isFormValid: true, genericFieldInfo, qGenericFieldInfo, @@ -244,8 +264,8 @@ describe('Software Product Details: ', function () { }; const onVendorChangedListener = (deltaData) => { expect(deltaData.vendorId).toEqual(finalizedLicenseModelList[1].id); - expect(deltaData.vendorName).toEqual(finalizedLicenseModelList[1].vendorName); - expect(deltaData.licensingVersion).toEqual(finalizedLicenseModelList[1].viewableVersion[0]); + expect(deltaData.vendorName).toEqual(finalizedLicenseModelList[1].name); + expect(deltaData.licensingVersion).toEqual(licensingVersionsList[1]); expect(deltaData.licensingData).toEqual({}); done(); }; @@ -258,7 +278,7 @@ describe('Software Product Details: ', function () { onQDataChanged = {dummyFunc} onVendorParamChanged = {(deltaData) => onVendorChangedListener(deltaData)}/>); expect(vspDetailsView).toBeTruthy(); - vspDetailsView.onVendorParamChanged({vendorId: finalizedLicenseModelList[1].id, licensingVersion: finalizedLicenseModelList[1].viewableVersion[0]}); + vspDetailsView.onVendorParamChanged({vendorId: finalizedLicenseModelList[1].id, licensingVersion: licensingVersionsList[1]}); }); it('in view: should change subcategory', done => { @@ -270,6 +290,7 @@ describe('Software Product Details: ', function () { isFormValid: true, genericFieldInfo, qGenericFieldInfo, + licensingVersionsList, finalizedLicenseModelList, licenseAgreementList, featureGroupsList @@ -301,6 +322,7 @@ describe('Software Product Details: ', function () { isFormValid: true, genericFieldInfo, qGenericFieldInfo, + licensingVersionsList, finalizedLicenseModelList, licenseAgreementList, featureGroupsList @@ -328,8 +350,8 @@ describe('Software Product Details: ', function () { ]}); }); - it('in view: should change license agreement', done => { + it('in view: should change license agreement', done => { let params = { currentSoftwareProduct: currentSoftwareProductWithLicensingData, softwareProductCategories, @@ -338,6 +360,7 @@ describe('Software Product Details: ', function () { isFormValid: true, genericFieldInfo, qGenericFieldInfo, + licensingVersionsList, finalizedLicenseModelList, licenseAgreementList, featureGroupsList @@ -358,4 +381,5 @@ describe('Software Product Details: ', function () { 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 df84d184ce..27cbaa40ef 100644 --- a/openecomp-ui/test/softwareProduct/details/test.js +++ b/openecomp-ui/test/softwareProduct/details/test.js @@ -30,10 +30,11 @@ import {heatSetupManifest} from 'test-utils/factories/softwareProduct/SoftwarePr 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'; +import VersionFactory from 'test-utils/factories/common/VersionFactory.js'; +import {InitializedCurrentScreenFactory} from 'test-utils/factories/common/CurrentScreenFactory.js'; -describe('Software Product Module Tests', function () { +describe('Software Product Details Module Tests', function () { it('Get Software Products List', () => { const store = storeCreator(); deepFreeze(store.getState()); @@ -43,14 +44,14 @@ describe('Software Product Module Tests', function () { const expectedStore = cloneAndSet(store.getState(), 'softwareProductList', softwareProductList); mockRest.addHandler('fetch', ({options, data, baseUrl}) => { - expect(baseUrl).toEqual('/onboarding-api/v1.0/vendor-software-products/'); + expect(baseUrl).toEqual('/onboarding-api/v1.0/vendor-software-products/?versionFilter=Draft'); 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(baseUrl).toEqual('/onboarding-api/v1.0/vendor-software-products/?versionFilter=Certified'); expect(data).toEqual(undefined); expect(options).toEqual(undefined); return {results: []}; @@ -130,6 +131,10 @@ describe('Software Product Module Tests', function () { let manifest = heatSetupManifest.build(); expectedStore = cloneAndSet(expectedStore, 'softwareProduct.softwareProductAttachments.heatSetup', manifest); + const expectedCurrentScreen = InitializedCurrentScreenFactory.build(); + expectedStore = cloneAndSet(expectedStore, 'currentScreen.itemPermission', expectedCurrentScreen.itemPermission); + expectedStore = cloneAndSet(expectedStore, 'currentScreen.props', expectedCurrentScreen.props); + mockRest.addHandler('post', ({options, data, baseUrl}) => { expect(baseUrl).toEqual('/onboarding-api/v1.0/vendor-software-products/'); expect(data).toEqual(softwareProductPostRequest); @@ -184,7 +189,7 @@ describe('Software Product Module Tests', function () { deepFreeze(softwareProductPostRequest); const licenseModelId = softwareProductPostRequest.vendorId; - const LMVersion = VersionControllerUtilsFactory.build().version; + const LMVersion = VersionFactory.build(); const secondLicenseModelId = 'secondLicenseModelId'; let FG1 = FeatureGroup.build(); @@ -205,13 +210,20 @@ describe('Software Product Module Tests', function () { }); mockRest.addHandler('fetch', ({options, data, baseUrl}) => { - expect(baseUrl).toEqual('/onboarding-api/v1.0/vendor-license-models/?versionFilter=Final'); + expect(baseUrl).toEqual('/onboarding-api/v1.0/vendor-license-models/?versionFilter=Certified'); expect(data).toEqual(undefined); expect(options).toEqual(undefined); return {results: []}; }); mockRest.addHandler('fetch', ({options, data, baseUrl}) => { + expect(baseUrl).toEqual(`/onboarding-api/v1.0/items/${licenseModelId}/versions/${LMVersion.id}`); + 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); @@ -226,6 +238,13 @@ describe('Software Product Module Tests', function () { }); mockRest.addHandler('fetch', ({options, data, baseUrl}) => { + expect(baseUrl).toEqual(`/onboarding-api/v1.0/items/${secondLicenseModelId}/versions/${LMVersion.id}`); + 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/${secondLicenseModelId}/versions/${LMVersion.id}/license-agreements`); expect(data).toEqual(undefined); expect(options).toEqual(undefined); @@ -239,17 +258,18 @@ describe('Software Product Module Tests', function () { return {results: [FG2]}; }); - return SoftwareProductActionHelper.loadSoftwareProductDetailsData(store.dispatch, {licenseModelId, licensingVersion: LMVersion}).then(() => { + return SoftwareProductActionHelper.loadSoftwareProductDetailsData(store.dispatch, {licenseModelId, licensingVersion: LMVersion.id}).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]); + {deltaData: {vendorId: secondLicenseModelId, licensingVersion: LMVersion.id}, + 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]); + }); }); }); @@ -258,6 +278,8 @@ describe('Software Product Module Tests', function () { const softwareProduct = VSPEditorFactoryWithLicensingData.build(); deepFreeze(softwareProduct); + const version = VersionFactory.build(); + const store = storeCreator({ softwareProduct: { softwareProductEditor: {data: softwareProduct}, @@ -291,13 +313,13 @@ describe('Software Product Module Tests', function () { deepFreeze(questionnaireData); mockRest.addHandler('put', ({data, options, baseUrl}) => { - expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-software-products/${toBeUpdatedSoftwareProductId}/versions/${softwareProduct.version.id}`); + expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-software-products/${toBeUpdatedSoftwareProductId}/versions/${version.id}`); expect(data).toEqual(softwareProductUpdateData); expect(options).toEqual(undefined); return {returnCode: 'OK'}; }); mockRest.addHandler('put', ({data, options, baseUrl}) => { - expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-software-products/${toBeUpdatedSoftwareProductId}/versions/${softwareProduct.version.id}/questionnaire`); + expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-software-products/${toBeUpdatedSoftwareProductId}/versions/${version.id}/questionnaire`); expect(data).toEqual(questionnaireData); expect(options).toEqual(undefined); return {returnCode: 'OK'}; @@ -305,7 +327,8 @@ describe('Software Product Module Tests', function () { return SoftwareProductActionHelper.updateSoftwareProduct(store.dispatch, { softwareProduct: softwareProductPutRequest, - qdata: questionnaireData + qdata: questionnaireData, + version }).then(() => { expect(store.getState()).toEqual(expectedStore); }); @@ -316,6 +339,8 @@ describe('Software Product Module Tests', function () { const softwareProduct = VSPEditorFactoryWithLicensingData.build(); deepFreeze(softwareProduct); + const version = VersionFactory.build(); + const store = storeCreator({ softwareProduct: { softwareProductEditor: {data: softwareProduct}, @@ -334,19 +359,20 @@ describe('Software Product Module Tests', function () { let softwareProductUpdateData = VSPEditorPostFactoryWithLicensingData.build(dataForUpdate); delete softwareProductUpdateData.version; - const softwareProductPutRequest = buildFromExistingObject(VSPEditorFactoryWithLicensingData, softwareProductUpdateData, {id: toBeUpdatedSoftwareProductId, version: softwareProduct.version}); + const softwareProductPutRequest = buildFromExistingObject(VSPEditorFactoryWithLicensingData, softwareProductUpdateData, {id: toBeUpdatedSoftwareProductId}); deepFreeze(softwareProductUpdateData); mockRest.addHandler('put', ({data, options, baseUrl}) => { - expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-software-products/${toBeUpdatedSoftwareProductId}/versions/${softwareProduct.version.id}`); + expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-software-products/${toBeUpdatedSoftwareProductId}/versions/${version.id}`); expect(data).toEqual(softwareProductUpdateData); expect(options).toEqual(undefined); return {returnCode: 'OK'}; }); return SoftwareProductActionHelper.updateSoftwareProductData(store.dispatch, { - softwareProduct: softwareProductPutRequest + softwareProduct: softwareProductPutRequest, + version }).then(() => { expect(store.getState()).toEqual(expectedStore); }); @@ -356,6 +382,8 @@ describe('Software Product Module Tests', function () { const softwareProduct = VSPEditorFactoryWithLicensingData.build(); deepFreeze(softwareProduct); + const version = VersionFactory.build(); + const store = storeCreator({ softwareProduct: { softwareProductEditor: {data: softwareProduct}, @@ -377,7 +405,7 @@ describe('Software Product Module Tests', function () { deepFreeze(questionnaireData); mockRest.addHandler('put', ({data, options, baseUrl}) => { - expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-software-products/${toBeUpdatedSoftwareProductId}/versions/${softwareProduct.version.id}/questionnaire`); + expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-software-products/${toBeUpdatedSoftwareProductId}/versions/${version.id}/questionnaire`); expect(data).toEqual(questionnaireData); expect(options).toEqual(undefined); return {returnCode: 'OK'}; @@ -385,7 +413,7 @@ describe('Software Product Module Tests', function () { return SoftwareProductActionHelper.updateSoftwareProductQuestionnaire(store.dispatch, { softwareProductId: softwareProduct.id, - version: softwareProduct.version, + version, qdata: questionnaireData }).then(() => { expect(store.getState()).toEqual(expectedStore); diff --git a/openecomp-ui/test/softwareProduct/landingPage/landingPage.test.js b/openecomp-ui/test/softwareProduct/landingPage/landingPage.test.js index 4da0ec98d4..c53919b802 100644 --- a/openecomp-ui/test/softwareProduct/landingPage/landingPage.test.js +++ b/openecomp-ui/test/softwareProduct/landingPage/landingPage.test.js @@ -19,6 +19,9 @@ import React from 'react'; import TestUtils from 'react-addons-test-utils'; +import {Provider} from 'react-redux'; +import {storeCreator} from 'sdc-app/AppStore.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'; @@ -27,9 +30,7 @@ import {default as SoftwareProductQSchemaFactory} from 'test-utils/factories/so 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 { Provider } from 'react-redux'; -import {storeCreator} from 'sdc-app/AppStore.js'; +import CurrentScreenFactory from 'test-utils/factories/common/CurrentScreenFactory.js'; import {mapStateToProps} from 'sdc-app/onboarding/softwareProduct/landingPage/SoftwareProductLandingPage.js'; import SoftwareProductLandingPageView from 'sdc-app/onboarding/softwareProduct/landingPage/SoftwareProductLandingPageView.jsx'; @@ -37,28 +38,28 @@ import SoftwareProductLandingPageView from 'sdc-app/onboarding/softwareProduct/l describe('Software Product Landing Page: ', function () { - let currentSoftwareProduct = {}, softwareProductCategories = [], + let currentSoftwareProduct = {}, softwareProductCategories = [], currentScreen = {}, 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}); + currentSoftwareProduct = VSPEditorFactory.build({id:'RTRTG454545', vendorId: finalizedLicenseModelList[0].id, vendorName: finalizedLicenseModelList[0].name, onBoardingMethod: 'HEAT'}); softwareProductCategories = CategoryWithSubFactory.buildList(2,{},{quantity: 1}); licenseAgreementList = LicenseAgreementStoreFactory.buildList(2); featureGroupsList = FeatureGroupStoreFactory.buildList(2,{referencingLicenseAgreements:[licenseAgreementList[0].id]}); + currentScreen = CurrentScreenFactory.build(); qdata = VspQdataFactory.build(); qschema = SoftwareProductQSchemaFactory.build(qdata); - }); - - it('should mapper exist', () => { expect(mapStateToProps).toBeTruthy(); }); it('should mapper return vsp basic data', () => { - const obj = { + const state = { + currentScreen, softwareProduct: { softwareProductEditor: { data: currentSoftwareProduct @@ -70,6 +71,9 @@ describe('Software Product Landing Page: ', function () { }, softwareProductComponents: { componentsList:[] + }, + softwareProductAttachments: { + heatSetup: {} } }, finalizedLicenseModelList, @@ -83,23 +87,25 @@ describe('Software Product Landing Page: ', function () { } }; - const result = mapStateToProps(obj); + const result = mapStateToProps(state); expect(result.currentSoftwareProduct).toBeTruthy(); - expect(result.isReadOnlyMode).toEqual(true); }); it('vsp landing basic view', () => { const params = { + ...currentScreen.props, currentSoftwareProduct, - isReadOnlyMode: false, componentsList: VSPComponentsFactory.buildList(2) }; const store = storeCreator(); - let vspLandingView = TestUtils.renderIntoDocument(<Provider store={store}><SoftwareProductLandingPageView - {...params}/></Provider>); + let vspLandingView = TestUtils.renderIntoDocument( + <Provider store={store}> + <SoftwareProductLandingPageView {...params}/> + </Provider> + ); expect(vspLandingView).toBeTruthy(); }); @@ -107,13 +113,16 @@ describe('Software Product Landing Page: ', function () { const params = { currentSoftwareProduct, - isReadOnlyMode: false, + ...currentScreen.props, componentsList: VSPComponentsFactory.buildList(2) }; const store = storeCreator(); - let vspLandingView = TestUtils.renderIntoDocument(<Provider store={store}><SoftwareProductLandingPageView - {...params}/></Provider>); + let vspLandingView = TestUtils.renderIntoDocument( + <Provider store={store}> + <SoftwareProductLandingPageView {...params}/> + </Provider> + ); let vspLandingViewWrapper = TestUtils.findRenderedComponentWithType( vspLandingView, SoftwareProductLandingPageView @@ -127,8 +136,8 @@ describe('Software Product Landing Page: ', function () { it('vsp landing handleImportSubmit test ', () => { const params = { + ...currentScreen.props, currentSoftwareProduct, - isReadOnlyMode: false, componentsList: VSPComponentsFactory.buildList(2), onUploadConfirmation: dummyFunc, onUpload: dummyFunc, @@ -144,7 +153,12 @@ describe('Software Product Landing Page: ', function () { const store = storeCreator(); - let vspLandingView = TestUtils.renderIntoDocument(<Provider store={store}><SoftwareProductLandingPageView {...params}/></Provider>); + let vspLandingView = TestUtils.renderIntoDocument( + <Provider store={store}> + <SoftwareProductLandingPageView {...params}/> + </Provider> + ); + let vspLandingViewWrapper = TestUtils.findRenderedComponentWithType( vspLandingView, SoftwareProductLandingPageView @@ -166,7 +180,7 @@ describe('Software Product Landing Page: ', function () { const params = { currentSoftwareProduct, - isReadOnlyMode: false, + ...currentScreen.props, componentsList: VSPComponentsFactory.buildList(2), onUploadConfirmation: dummyFunc, onUpload: dummyFunc, @@ -175,8 +189,11 @@ describe('Software Product Landing Page: ', function () { const store = storeCreator(); - let vspLandingView = TestUtils.renderIntoDocument(<Provider store={store}><SoftwareProductLandingPageView - {...params}/></Provider>); + let vspLandingView = TestUtils.renderIntoDocument( + <Provider store={store}> + <SoftwareProductLandingPageView {...params}/> + </Provider> + ); let vspLandingViewWrapper = TestUtils.findRenderedComponentWithType( vspLandingView, diff --git a/openecomp-ui/test/softwareProduct/networks/SoftwareProductNetworksView.test.js b/openecomp-ui/test/softwareProduct/networks/SoftwareProductNetworksView.test.js index 6ef6bcf02a..b4ea4049a6 100644 --- a/openecomp-ui/test/softwareProduct/networks/SoftwareProductNetworksView.test.js +++ b/openecomp-ui/test/softwareProduct/networks/SoftwareProductNetworksView.test.js @@ -57,9 +57,8 @@ describe('SoftwareProductNetworks Mapper and View Classes', () => { const networksList = VSPNetworkFactory.buildList(2); const versionControllerData = VSPComponentsVersionControllerFactory.build(); - var renderer = TestUtils.createRenderer(); - renderer.render(<SoftwareProductNetworksView networksList={networksList} versionControllerData={versionControllerData} currentSoftwareProduct={currentSoftwareProduct}/>); + renderer.render(<SoftwareProductNetworksView isReadOnlyMode={true} networksList={networksList} versionControllerData={versionControllerData} currentSoftwareProduct={currentSoftwareProduct}/>); 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 43110d2e55..6ad696ae85 100644 --- a/openecomp-ui/test/softwareProduct/processes/test.js +++ b/openecomp-ui/test/softwareProduct/processes/test.js @@ -29,10 +29,10 @@ import { 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'; +import VersionFactory from 'test-utils/factories/common/VersionFactory.js'; const softwareProductId = '123'; -const version = VSPEditorFactory.build().version; +const version = VersionFactory.build(); describe('Software Product Processes Module Tests', function () { @@ -317,7 +317,6 @@ describe('Software Product Processes Module Tests', function () { }); const processId = softwareProductProcessesList[0].id; - const version = store.getState().softwareProduct.softwareProductEditor.data.version; const versionId = version.id; deepFreeze(store.getState()); @@ -343,7 +342,7 @@ describe('Software Product Processes Module Tests', function () { }); }); - it('Validating Software Products Processes Delete confirmation', done => { + it('Validating Software Products Processes Delete confirmation', () => { const store = storeCreator(); deepFreeze(store.getState()); @@ -352,15 +351,12 @@ describe('Software Product Processes Module Tests', function () { const expectedStore = cloneAndSet(store.getState(), 'softwareProduct.softwareProductProcesses.processToDelete', process); - SoftwareProductProcessesActionHelper.openDeleteProcessesConfirm(store.dispatch, {process}); + return SoftwareProductProcessesActionHelper.openDeleteProcessesConfirm(store.dispatch, {process}); - setTimeout(function(){ - expect(store.getState()).toEqual(expectedStore); - done(); - }, 100); + expect(store.getState()).toEqual(expectedStore); }); - it('Validating Software Products Processes Cancel Delete', done => { + it('Validating Software Products Processes Cancel Delete', () => { const store = storeCreator(); deepFreeze(store.getState()); @@ -368,10 +364,7 @@ describe('Software Product Processes Module Tests', function () { SoftwareProductProcessesActionHelper.hideDeleteConfirm(store.dispatch); - setTimeout(function(){ - expect(store.getState()).toEqual(expectedStore); - done(); - }, 100); + expect(store.getState()).toEqual(expectedStore); }); //** diff --git a/openecomp-ui/test/softwareProduct/test.js b/openecomp-ui/test/softwareProduct/test.js new file mode 100644 index 0000000000..15f7a21866 --- /dev/null +++ b/openecomp-ui/test/softwareProduct/test.js @@ -0,0 +1,116 @@ +/*! + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +import 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 SoftwareProductActionHelper from 'sdc-app/onboarding/softwareProduct/SoftwareProductActionHelper.js'; +import {VSPEditorFactoryWithLicensingData} from 'test-utils/factories/softwareProduct/SoftwareProductEditorFactories.js'; +import VersionFactory from 'test-utils/factories/common/VersionFactory.js'; +import {default as CurrentScreenFactory} from 'test-utils/factories/common/CurrentScreenFactory.js'; +import {actionsEnum as VersionControllerActionsEnum} from 'nfvo-components/panel/versionController/VersionControllerConstants.js'; +import {SyncStates} from 'sdc-app/common/merge/MergeEditorConstants.js'; +import {itemTypes} from 'sdc-app/onboarding/versionsPage/VersionsPageConstants.js'; + +describe('Software Product Module Tests', function () { + it('Validating readonly screen after submit', () => { + const version = VersionFactory.build({}, {isCertified: false}); + const itemPermissionAndProps = CurrentScreenFactory.build({}, {version}); + const softwareProduct = VSPEditorFactoryWithLicensingData.build(); + deepFreeze(softwareProduct); + + const store = storeCreator({ + currentScreen: {...itemPermissionAndProps}, + softwareProduct: { + softwareProductEditor: {data: softwareProduct}, + softwareProductQuestionnaire: {qdata: 'test', qschema: {type: 'string'}} + } + }); + deepFreeze(store.getState()); + + const certifiedVersion = { + ...itemPermissionAndProps.props.version, + status: 'Certified' + }; + + const versionsList = { + itemType: itemTypes.SOFTWARE_PRODUCT, + itemId: softwareProduct.id, + versions: [{...certifiedVersion}] + }; + const expectedCurrentScreenProps = { + itemPermission: { + ...itemPermissionAndProps.itemPermission, + isCertified: true + }, + props: { + isReadOnlyMode: true, + version: certifiedVersion + } + }; + const expectedSuccessModal = { + cancelButtonText: 'OK', + modalClassName: 'notification-modal', + msg: 'This software product successfully submitted', + timeout: 2000, + title: 'Submit Succeeded', + type: 'success' + }; + + let expectedStore = store.getState(); + expectedStore = cloneAndSet(expectedStore, 'currentScreen.itemPermission', expectedCurrentScreenProps.itemPermission); + expectedStore = cloneAndSet(expectedStore, 'currentScreen.props', expectedCurrentScreenProps.props); + expectedStore = cloneAndSet(expectedStore, 'modal', expectedSuccessModal); + expectedStore = cloneAndSet(expectedStore, 'versionsPage.versionsList', versionsList ); + + mockRest.addHandler('put', ({data, options, baseUrl}) => { + expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-software-products/${softwareProduct.id}/versions/${version.id}/actions`); + expect(data).toEqual({action: VersionControllerActionsEnum.SUBMIT}); + expect(options).toEqual(undefined); + return {returnCode: 'OK'}; + }); + + mockRest.addHandler('put', ({data, options, baseUrl}) => { + expect(baseUrl).toEqual(`/onboarding-api/v1.0/vendor-software-products/${softwareProduct.id}/versions/${version.id}/actions`); + expect(data).toEqual({action: VersionControllerActionsEnum.CREATE_PACKAGE}); + expect(options).toEqual(undefined); + return {returnCode: 'OK'}; + }); + + mockRest.addHandler('fetch', ({data, options, baseUrl}) => { + expect(baseUrl).toEqual(`/onboarding-api/v1.0/items/${softwareProduct.id}/versions/${version.id}`); + expect(data).toEqual(undefined); + expect(options).toEqual(undefined); + return {...certifiedVersion, state: {synchronizationState: SyncStates.UP_TO_DATE, dirty: false}}; + }); + + mockRest.addHandler('fetch', ({data, options, baseUrl}) => { + expect(baseUrl).toEqual(`/onboarding-api/v1.0/items/${softwareProduct.id}/versions`); + expect(data).toEqual(undefined); + expect(options).toEqual(undefined); + return {results: [{...certifiedVersion}]}; + }); + + return SoftwareProductActionHelper.performSubmitAction(store.dispatch, { + softwareProductId: softwareProduct.id, + version + }).then(() => { + expect(store.getState()).toEqual(expectedStore); + }); + }); +});
\ No newline at end of file diff --git a/openecomp-ui/test/utils/errorResponseHandler.test.js b/openecomp-ui/test/utils/errorResponseHandler.test.js index 40836f728a..07f7ff72ac 100644 --- a/openecomp-ui/test/utils/errorResponseHandler.test.js +++ b/openecomp-ui/test/utils/errorResponseHandler.test.js @@ -26,7 +26,7 @@ describe('Error Response Handler Util', () => { deepFreeze(store.getState()); }); - it('validating error in policyException', done => { + it('validating error in policyException', () => { let textStatus = '', errorThrown = ''; let xhr = { responseJSON: { @@ -53,13 +53,10 @@ describe('Error Response Handler Util', () => { errorResponseHandler(xhr, textStatus, errorThrown); - setTimeout(function () { - expect(store.getState()).toEqual(expectedStore); - done(); - }, 100); + expect(store.getState()).toEqual(expectedStore); }); - it('validating error in serviceException with variables', done => { + it('validating error in serviceException with variables', () => { let textStatus = '', errorThrown = ''; let xhr = { responseJSON: { @@ -85,13 +82,10 @@ describe('Error Response Handler Util', () => { errorResponseHandler(xhr, textStatus, errorThrown); - setTimeout(function () { - expect(store.getState()).toEqual(expectedStore); - done(); - }, 100); + expect(store.getState()).toEqual(expectedStore); }); - it('validating error in response', done => { + it('validating error in response', () => { let textStatus = '', errorThrown = ''; let xhr = { responseJSON: { @@ -112,13 +106,10 @@ describe('Error Response Handler Util', () => { errorResponseHandler(xhr, textStatus, errorThrown); - setTimeout(function () { - expect(store.getState()).toEqual(expectedStore); - done(); - }, 100); + expect(store.getState()).toEqual(expectedStore); }); - it('validating error in request', done => { + it('validating error in request', () => { let textStatus = '', errorThrown = ''; let xhr = { statusText: '500', @@ -137,9 +128,6 @@ describe('Error Response Handler Util', () => { errorResponseHandler(xhr, textStatus, errorThrown); - setTimeout(function () { - expect(store.getState()).toEqual(expectedStore); - done(); - }, 100); + expect(store.getState()).toEqual(expectedStore); }); }); diff --git a/openecomp-ui/test/versionsPage/VersionsPage.test.js b/openecomp-ui/test/versionsPage/VersionsPage.test.js new file mode 100644 index 0000000000..7265ebf0a9 --- /dev/null +++ b/openecomp-ui/test/versionsPage/VersionsPage.test.js @@ -0,0 +1,154 @@ +/*! + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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 deepFreeze from 'deep-freeze'; +import mockRest from 'test-utils/MockRest.js'; +import Configuration from 'sdc-app/config/Configuration.js'; +import {storeCreator} from 'sdc-app/AppStore.js'; + +import {mapStateToProps, mapActionsToProps} from 'sdc-app/onboarding/versionsPage/VersionsPage.js'; +import VersionsPageView from 'sdc-app/onboarding/versionsPage/VersionsPage.jsx'; +import VersionsPageActionHelper from 'sdc-app/onboarding/versionsPage/VersionsPageActionHelper.js'; +import VersionsPageCreationActionHelper from 'sdc-app/onboarding/versionsPage/creation/VersionsPageCreationActionHelper.js'; +import {itemTypes as versionPageItemTypes} from 'sdc-app/onboarding/versionsPage/VersionsPageConstants.js'; +import VersionFactory from 'test-utils/factories/common/VersionFactory.js'; +import {VersionsPageCreationFactory} from 'test-utils/factories/versionsPage/VersionsPageCreationFactories.js'; +import {VersionsPageAdditionalPropsFactory} from 'test-utils/factories/versionsPage/VersionsPageFactories.js'; + +describe('Versions Page Module Tests', () => { + + const state = { + currentScreen: { + itemPermission: { + isCollaborator: true + }, + props: { + itemId: '23' + } + }, + users: { + userInfo: 'user123' + }, + versionsPage: { + permissions: {}, + versionsList: {versions: []}, + versionCreation: {} + } + }; + + it ('mapStateToProps mapper exists', () => { + + expect(mapStateToProps).toBeTruthy(); + + }); + + it ('should have state in props', () => { + + const props = mapStateToProps(state); + expect(props.currentUser).toEqual('user123'); + + }); + + it('simple jsx test', () => { + + const store = storeCreator(); + const dispatch = store.dispatch; + + const additionalProps = VersionsPageAdditionalPropsFactory.build(); + + const props = Object.assign({}, mapStateToProps(state), mapActionsToProps(dispatch, additionalProps)); + const renderer = TestUtils.createRenderer(); + renderer.render(<VersionsPageView {...props} />); + + const renderedOutput = renderer.getRenderOutput(); + expect(renderedOutput).toBeTruthy(); + + }); + +}); + +describe('Versions Page Actions', () => { + + let store, dispatch, restPrefix = '', version; + + beforeAll(() => { + restPrefix = Configuration.get('restPrefix'); + store = storeCreator(); + dispatch = store.dispatch; + deepFreeze(store.getState()); + version = VersionFactory.build(); + }); + + it('Select and deselect version', () => { + + let selectedVersionOf = (state) => state.versionsPage.versionsList.selectedVersion; + VersionsPageActionHelper.selectVersion(dispatch, {version}); + expect(selectedVersionOf(store.getState())).toEqual(version.id); + VersionsPageActionHelper.selectNone(dispatch); + expect(selectedVersionOf(store.getState())).toEqual(null); + + }); + + it('Create version', () => { + + const {id, baseId} = version; + + mockRest.addHandler('post', ({baseUrl}) => { + expect(baseUrl).toEqual(`${restPrefix}/v1.0/items/${id}/versions/${baseId}/`); + return version; + }); + + mockRest.addHandler('fetch', ({baseUrl}) => { + expect(baseUrl).toEqual(`${restPrefix}/v1.0/items/${id}/versions`); + return {results: [version]}; + }); + + return VersionsPageCreationActionHelper.createVersion(dispatch, { + itemId: id, + baseVersion: {id: baseId}, + payload: VersionsPageCreationFactory.build() + }) + .then(result => { + expect(result.id).toEqual(id); + }); + + }); + + it('Fetch versions', () => { + + const {id} = version; + + mockRest.addHandler('fetch', ({baseUrl}) => { + expect(baseUrl).toEqual(`${restPrefix}/v1.0/items/${id}/versions`); + return {results: [version]}; + }); + + return VersionsPageActionHelper.fetchVersions(dispatch, { + itemType: versionPageItemTypes.SOFTWARE_PRODUCT, + itemId: id + }) + .then(() => { + const {versionsPage: {versionsList}} = store.getState(); + expect(versionsList.versions[0].id).toEqual(id); + expect(versionsList.itemId).toEqual(id); + expect(versionsList.itemType).toEqual(versionPageItemTypes.SOFTWARE_PRODUCT); + }); + + }); + +}); diff --git a/openecomp-ui/test/versionsPage/creation/VersionsPageCreation.test.js b/openecomp-ui/test/versionsPage/creation/VersionsPageCreation.test.js new file mode 100644 index 0000000000..d490111178 --- /dev/null +++ b/openecomp-ui/test/versionsPage/creation/VersionsPageCreation.test.js @@ -0,0 +1,113 @@ +/*! + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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/versionsPage/creation/VersionsPageCreation.js'; +import {VERSION_CREATION_FORM_NAME} from 'sdc-app/onboarding/versionsPage/creation/VersionsPageCreationConstants.js'; +import VersionsPageCreationActionHelper from 'sdc-app/onboarding/versionsPage/creation/VersionsPageCreationActionHelper.js'; +import VersionsPageCreationView from 'sdc-app/onboarding/versionsPage/creation/VersionsPageCreationView.jsx'; +import {VersionsPageCreationFactory, + VersionsPageCreationFieldInfoFactory} from 'test-utils/factories/versionsPage/VersionsPageCreationFactories.js'; +import {VersionsPageAdditionalPropsFactory} from 'test-utils/factories/versionsPage/VersionsPageFactories.js'; +import {storeCreator} from 'sdc-app/AppStore.js'; + +describe('Versions Page Creation Module Tests', function() { + + let versionCreationData, genericFieldInfo; + let store, dispatch; + + beforeAll(() => { + store = storeCreator(); + dispatch = store.dispatch; + versionCreationData = VersionsPageCreationFactory.build(); + genericFieldInfo = VersionsPageCreationFieldInfoFactory.build(); + }); + + const additionalProps = VersionsPageAdditionalPropsFactory.build(); + + it ('mapStateToProps mapper exists', () => { + + expect(mapStateToProps).toBeTruthy(); + + }); + + it ('should return empty data', () => { + + const state = { + versionsPage: { + versionCreation: { + data: {}, + genericFieldInfo: {} + } + } + }; + + const props = mapStateToProps(state); + expect(props.data).toEqual({}); + expect(props.isFormValid).toEqual(true); + + }); + + it ('should have state in props', () => { + + const state = { + versionsPage: { + versionCreation: { + data: versionCreationData, + genericFieldInfo + } + } + }; + + const props = mapStateToProps(state); + expect(props.isFormValid).toEqual(true); + expect(props.data.description).toEqual(versionCreationData.description); + expect(props.genericFieldInfo).toEqual(genericFieldInfo); + + }); + + it('simple jsx test', () => { + + const state = { + versionsPage: { + versionCreation: { + data: versionCreationData, + genericFieldInfo + } + } + }; + + const props = Object.assign({}, mapStateToProps(state), mapActionsToProps(dispatch, additionalProps), additionalProps); + const renderer = TestUtils.createRenderer(); + renderer.render(<VersionsPageCreationView {...props} />); + + const renderedOutput = renderer.getRenderOutput(); + expect(renderedOutput).toBeTruthy(); + + }); + + it('open/close form actions', () => { + + VersionsPageCreationActionHelper.open(dispatch, additionalProps); + expect(store.getState().versionsPage.versionCreation.formName).toEqual(VERSION_CREATION_FORM_NAME); + + VersionsPageCreationActionHelper.close(dispatch); + expect(store.getState().versionsPage.versionCreation).toEqual({}); + + }); + +});
\ No newline at end of file diff --git a/openecomp-ui/webpack.common.js b/openecomp-ui/webpack.common.js index ebe4a8454a..68d8923458 100644 --- a/openecomp-ui/webpack.common.js +++ b/openecomp-ui/webpack.common.js @@ -5,7 +5,9 @@ let path = require('path'); let localDevConfig = {}; try { localDevConfig = require('./devConfig'); -} catch (e) {} +} catch (e) { + console.log('Could not find local dev config.'); +} let devConfig = Object.assign({}, require('./devConfig.defaults'), localDevConfig); module.exports = { @@ -23,11 +25,11 @@ module.exports = { }, module: { rules: [ - {test: /\.(js|jsx)$/, loader: 'source-map-loader', exclude: /node_modules/, enforce: 'pre'}, + {test: /\.(js|jsx)$/, loader: 'source-map-loader', exclude: [/node_modules/, path.resolve(__dirname, '../dox-sequence-diagram/')], enforce: 'pre'}, {test: /\.(js|jsx)$/, use: [ {loader : 'react-hot-loader'}, {loader : 'babel-loader'}, - {loader : 'eslint-loader'}], exclude: /node_modules/}, + {loader : 'eslint-loader'}], exclude: [/node_modules/, path.resolve(__dirname, '../dox-sequence-diagram/')]}, {test: /\.(css|scss)$/, use: [ {loader: 'style-loader'}, {loader: 'css-loader?sourceMap'}, |