Onboarding filter
Issue-ID: SDC-1187
Change-Id: I74ce464c8ee4060c381b094d26d1ded270cdf40d
Signed-off-by: svishnev <shlomo-stanisla.vishnevetskiy@amdocs.com>
diff --git a/openecomp-ui/package.json b/openecomp-ui/package.json
index 70c86cc..6cd9f72 100644
--- a/openecomp-ui/package.json
+++ b/openecomp-ui/package.json
@@ -11,13 +11,17 @@
"static-keys-bundle": "gulp static-keys-bundle",
"check-keys-against-bundles": "gulp static-keys-bundle-with-report",
"test": "jest",
- "test-failedTestReport": "jest --json | node test-utils/failedTestReport.js",
+ "test-failedTestReport":
+ "jest --json | node test-utils/failedTestReport.js",
"test-dev": "jest --watch",
- "test-coverage": "jest --coverage && start ./coverage/lcov-report/index.html",
+ "test-coverage":
+ "jest --coverage && start ./coverage/lcov-report/index.html",
"test-build": "jest --coverage",
- "storybook": "start-storybook -p 9090 -c .storybook -s .storybook/fonts",
+ "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",
+ "build-storybook":
+ "build-storybook -c .storybook -o .storybook-dist && gulp copy-storybook-fonts",
"lint-fix": "eslint --fix --ext .js --ext .jsx src"
},
"dependencies": {
@@ -49,7 +53,7 @@
"react-show-more": "^1.1.1",
"react-sortable": "^1.2.0",
"redux": "^3.7.2",
- "sdc-ui": "1.6.24",
+ "sdc-ui": "1.6.27",
"uuid-js": "^0.7.5",
"validator": "^4.3.0"
},
@@ -121,10 +125,12 @@
},
"jest": {
"moduleNameMapper": {
- "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/test-utils/fileMock.js",
+ "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$":
+ "<rootDir>/test-utils/fileMock.js",
"\\.(css|scss)$": "<rootDir>/test-utils/styleMock.js",
"^nfvo-utils/RestAPIUtil.js$": "<rootDir>/test-utils/MockRest.js",
- "^sdc-ui/lib/react/SVGIcon.js$": "<rootDir>/test-utils/MockSVGIcon.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",
@@ -136,23 +142,14 @@
"globals": {
"DEBUG": false
},
- "setupFiles": [
- "<rootDir>/test-utils/test-env-setup.js"
- ],
+ "setupFiles": ["<rootDir>/test-utils/test-env-setup.js"],
"setupTestFrameworkScriptFile": "<rootDir>/test-utils/test-setup.js",
"testPathIgnorePatterns": [
"<rootDir>/node_modules/",
"<rootDir>/test/nfvo-components/storyshots.test.js"
],
- "collectCoverageFrom": [
- "src/**/*.{js,jsx}"
- ],
- "coveragePathIgnorePatterns": [
- "/node_modules/",
- "(.)*.stories.js"
- ],
- "coverageReporters": [
- "lcov"
- ]
+ "collectCoverageFrom": ["src/**/*.{js,jsx}"],
+ "coveragePathIgnorePatterns": ["/node_modules/", "(.)*.stories.js"],
+ "coverageReporters": ["lcov"]
}
}
diff --git a/openecomp-ui/resources/scss/_components.scss b/openecomp-ui/resources/scss/_components.scss
index ce5c732..e18b260 100644
--- a/openecomp-ui/resources/scss/_components.scss
+++ b/openecomp-ui/resources/scss/_components.scss
@@ -21,7 +21,6 @@
@import "components/commitModal";
@import "components/userNotifications";
@import "components/overlay";
-@import "components/accordion";
@import "components/vspDetailsVendorSelect";
%noselect {
diff --git a/openecomp-ui/resources/scss/components/_accordion.scss b/openecomp-ui/resources/scss/components/_accordion.scss
deleted file mode 100644
index c96bc71..0000000
--- a/openecomp-ui/resources/scss/components/_accordion.scss
+++ /dev/null
@@ -1,28 +0,0 @@
-.accordion {
- display: flex;
- flex-direction: column;
- .accordion-header {
- display: flex;
- flex-direction: row;
- cursor: pointer;
- margin-bottom: 10px;
- .svg-icon-wrapper {
- margin-right: 20px;
- transition: transform .4s;
- &.down {
- transform: rotate(180deg);
- }
- }
- }
- .accordion-body {
- padding-left: 10px;
- opacity: 0;
- overflow-y: hidden;
- max-height: 0;
- transition: max-height .3s cubic-bezier(0, 1.18, 1, 1), opacity 0.33s linear;
- &.open {
- opacity: 1;
- max-height: 100%;
- }
- }
-}
\ No newline at end of file
diff --git a/openecomp-ui/resources/scss/modules/onboardingCatalog/_catalogFilter.scss b/openecomp-ui/resources/scss/modules/onboardingCatalog/_catalogFilter.scss
index cda47c6..a7a7628 100644
--- a/openecomp-ui/resources/scss/modules/onboardingCatalog/_catalogFilter.scss
+++ b/openecomp-ui/resources/scss/modules/onboardingCatalog/_catalogFilter.scss
@@ -1,16 +1,22 @@
.catalog-filter {
- width: 242px;
- overflow-y: auto;
- height: 100%;
- box-shadow: 1px 0px 4px 0px rgba(24, 24, 25, 0.17);
- background-color: $white;
- padding: 12px 18px;
- .form-group {
- margin-bottom: 10px;
+ .catalog-filter-by-vendor-view {
+ margin-left: 18px;
+ margin-right: 18px;
+ }
+ .empty-block {
+ height: 34px;
+ width: 100%;
}
.catalog-filter-items-type {
width: 100%;
- background-color: $gray;
- color: $white;
+ background-color: $tlv-light-gray;
+ height: 34px;
}
-}
\ No newline at end of file
+ .sdc-accordion {
+ padding-left: 18px;
+ padding-right: 18px;
+ }
+ .first-line {
+ margin-top: 40px;
+ }
+}
diff --git a/openecomp-ui/resources/scss/modules/onboardingCatalog/_catalogList.scss b/openecomp-ui/resources/scss/modules/onboardingCatalog/_catalogList.scss
index 071268c..11a739d 100644
--- a/openecomp-ui/resources/scss/modules/onboardingCatalog/_catalogList.scss
+++ b/openecomp-ui/resources/scss/modules/onboardingCatalog/_catalogList.scss
@@ -24,6 +24,14 @@
display: block;
width: 100%;
}
+ .venodor-tile-btn {
+ border: 1px solid $light-gray;
+ color: $black;
+ line-height: 20px;
+ &:hover {
+ background-color: $light-gray;
+ }
+ }
}
// Bottom spacing - cross browser solution
diff --git a/openecomp-ui/src/nfvo-components/accordion/Accordion.jsx b/openecomp-ui/src/nfvo-components/accordion/Accordion.jsx
deleted file mode 100644
index 72f8de0..0000000
--- a/openecomp-ui/src/nfvo-components/accordion/Accordion.jsx
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright © 2016-2018 European Support Limited
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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 SVGIcon from 'sdc-ui/lib/react/SVGIcon.js';
-import PropTypes from 'prop-types';
-
-class Accordion extends React.Component {
- static propTypes = {
- title: PropTypes.string,
- children: PropTypes.node
- };
-
- constructor(props) {
- super(props);
- this.state = {
- open: false
- };
- }
- render() {
- const { children, title } = this.props;
- const { open } = this.state;
- return (
- <div className="accordion">
- <div
- onClick={() => this.setState({ open: !open })}
- className="accordion-header">
- <SVGIcon
- name="chevronUp"
- iconClassName={open ? 'down' : ''}
- />
- <div className="title">{title}</div>
- </div>
- <div className={`accordion-body ${open ? 'open' : ''}`}>
- {children}
- </div>
- </div>
- );
- }
-}
-
-export default Accordion;
diff --git a/openecomp-ui/src/nfvo-utils/i18n/en.json b/openecomp-ui/src/nfvo-utils/i18n/en.json
index 347a8ed..cbc2031 100644
--- a/openecomp-ui/src/nfvo-utils/i18n/en.json
+++ b/openecomp-ui/src/nfvo-utils/i18n/en.json
@@ -83,7 +83,8 @@
"This software product successfully submitted": "This software product successfully submitted",
"Submit Failed": "Submit Failed",
"Vendor Name": "Vendor Name",
- "License model by the name \\": "License model by the name \\",
+ "License model by the name": "License model by the name",
+ "License model name must be unique": "License model name must be unique",
"please select…": "please select…",
"Warning": "Warning",
"Operational Scope": "Operational Scope",
@@ -160,7 +161,9 @@
"Vendor": "Vendor",
"Category": "Category",
"please select...": "please select...",
- "Software product by the name \\": "Software product by the name \\",
+ "Software product by the name": "Software product by the name",
+ "Software product name must be unique": "Software product name must be unique",
+ "already exists": "already exists",
"Onboarding procedure": "Onboarding procedure",
"HEAT file": "HEAT file",
"Manual": "Manual",
@@ -356,7 +359,12 @@
"Granted": "Granted",
"Taken": "Taken",
"Permission": "Permission",
-
+ "By Vendor View": "By Vendor View",
+ "PERMISSIONS": "PERMISSIONS",
+ "Contributor": "Contributor",
+ "Active Items": "Active Items",
+ "Archived Items": "Archived Items",
+
"VendorSoftwareProduct": "VSP",
"VendorSoftwareProduct/category": "Category",
"VendorSoftwareProduct/description": "Description",
diff --git a/openecomp-ui/src/nfvo-utils/objectPropsToUrlString.js b/openecomp-ui/src/nfvo-utils/objectPropsToUrlString.js
new file mode 100644
index 0000000..6c18bb6
--- /dev/null
+++ b/openecomp-ui/src/nfvo-utils/objectPropsToUrlString.js
@@ -0,0 +1,23 @@
+export default function objectPropsToUrlString(data) {
+ let str = '';
+ Object.keys(data).map(key => {
+ if (typeof data[key] === 'object') {
+ let obj = data[key];
+ let arr = [];
+
+ Object.keys(obj).map(prop => {
+ if (obj[prop]) {
+ arr.push(encodeURIComponent(prop));
+ }
+ });
+ if (arr.length) {
+ str += `&${encodeURIComponent(key)}=${arr.join(',')}`;
+ }
+ } else if (data[key]) {
+ str += `&${encodeURIComponent(key)}=${encodeURIComponent(
+ data[key]
+ )}`;
+ }
+ });
+ return str;
+}
diff --git a/openecomp-ui/src/sdc-app/AppStore.js b/openecomp-ui/src/sdc-app/AppStore.js
index bca750a..5cab6ae 100644
--- a/openecomp-ui/src/sdc-app/AppStore.js
+++ b/openecomp-ui/src/sdc-app/AppStore.js
@@ -16,17 +16,20 @@
import { createStore, applyMiddleware, compose } from 'redux';
import Reducers from './Reducers.js';
+import filterUpdater from 'sdc-app/onboarding/onboard/filter/FilterMiddleware.js';
+
const thunk = store => next => action =>
typeof action === 'function'
? action(store.dispatch, store.getState)
: next(action);
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
+
export const storeCreator = initialState =>
createStore(
Reducers,
initialState,
- composeEnhancers(applyMiddleware(thunk))
+ composeEnhancers(applyMiddleware(thunk, filterUpdater))
);
const store = storeCreator();
diff --git a/openecomp-ui/src/sdc-app/common/helpers/ItemsHelper.js b/openecomp-ui/src/sdc-app/common/helpers/ItemsHelper.js
index 99ecae9..ae5c270 100644
--- a/openecomp-ui/src/sdc-app/common/helpers/ItemsHelper.js
+++ b/openecomp-ui/src/sdc-app/common/helpers/ItemsHelper.js
@@ -1,36 +1,32 @@
-/*!
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+/*
+ * Copyright © 2016-2018 European Support Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing
- * permissions and limitations under the License.
+ * WITHOUT WARRANTIES 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';
-import restToggle from 'sdc-app/features/restToggle.js';
+import { restToggle } from 'sdc-app/features/featureToggleUtils.js';
import { featureToggleNames } from 'sdc-app/features/FeaturesConstants.js';
+import objectPropsToUrlString from 'nfvo-utils/objectPropsToUrlString.js';
+
export const archiveActions = {
ARCHIVE: 'ARCHIVE',
RESTORE: 'RESTORE'
};
-export const itemStatus = {
- ARCHIVED: 'ARCHIVED',
- DRAFT: 'Draft',
- CERTIFIED: 'Certified'
-};
-
function baseUrl() {
const restPrefix = Configuration.get('restPrefix');
return `${restPrefix}/v1.0/items`;
@@ -118,6 +114,15 @@
return RestAPIUtil.put(`${baseUrl()}/${itemId}/actions`, {
action: archiveActions.RESTORE
});
+ },
+
+ fetchItems(filterData) {
+ const str = objectPropsToUrlString(filterData);
+ return restToggle({
+ restFunction: () => RestAPIUtil.fetch(`${baseUrl()}?${str}`),
+ featureName: featureToggleNames.FILTER,
+ mockResult: { results: [] }
+ });
}
};
diff --git a/openecomp-ui/src/sdc-app/common/helpers/ItemsHelperConstants.js b/openecomp-ui/src/sdc-app/common/helpers/ItemsHelperConstants.js
new file mode 100644
index 0000000..ebbbfde
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/common/helpers/ItemsHelperConstants.js
@@ -0,0 +1,29 @@
+/*
+ * Copyright © 2016-2018 European Support Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+export const itemStatus = {
+ ACTIVE: 'ACTIVE',
+ ARCHIVED: 'ARCHIVED'
+};
+
+export const versionStatus = {
+ DRAFT: 'Draft',
+ CERTIFIED: 'Certified'
+};
+
+export const itemType = {
+ VSP: 'vsp',
+ VLM: 'vlm'
+};
diff --git a/openecomp-ui/src/sdc-app/common/helpers/UniqueTypesHelper.js b/openecomp-ui/src/sdc-app/common/helpers/UniqueTypesHelper.js
new file mode 100644
index 0000000..de84f91
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/common/helpers/UniqueTypesHelper.js
@@ -0,0 +1,69 @@
+/*!
+ * Copyright © 2016-2018 European Support Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 ValidationHelper from 'sdc-app/common/helpers/ValidationHelper.js';
+import { featureToggleNames } from 'sdc-app/features/FeaturesConstants.js';
+import { restToggle } from 'sdc-app/features/featureToggleUtils.js';
+
+const itemTypesMapper = {
+ vsp: 'VspName',
+ vlm: 'VlmName'
+};
+
+function baseUrl() {
+ const restPrefix = Configuration.get('restPrefix');
+ return `${restPrefix}/v1.0/unique-types/`;
+}
+
+function uniqueValue(type, value) {
+ return restToggle({
+ restFunction: () =>
+ RestAPIUtil.fetch(`${baseUrl()}${type}/values/${value}`),
+ featureName: featureToggleNames.FILTER,
+ mockResult: { occupied: false }
+ });
+}
+
+export default {
+ async isNameUnique(
+ dispatch,
+ { value, name, formName, errorText, itemType }
+ ) {
+ const { occupied } = await uniqueValue(
+ itemTypesMapper[itemType],
+ value
+ );
+ const validation = occupied
+ ? {
+ isValid: false,
+ errorText
+ }
+ : { isValid: true, errorText: '' };
+
+ let deltaData = {};
+ deltaData[name] = value;
+ let customValidations = {};
+ customValidations[name] = () => validation;
+
+ ValidationHelper.dataChanged(dispatch, {
+ deltaData,
+ formName,
+ customValidations
+ });
+ }
+};
diff --git a/openecomp-ui/src/sdc-app/features/featureToggle.js b/openecomp-ui/src/sdc-app/features/featureToggle.js
index d33c76e..861db6a 100644
--- a/openecomp-ui/src/sdc-app/features/featureToggle.js
+++ b/openecomp-ui/src/sdc-app/features/featureToggle.js
@@ -38,12 +38,14 @@
export const FeatureComponent = props => {
const { features = [], featureName, InnerComponent, ...otherProps } = props;
- const AComp = InnerComponent.AComp ? InnerComponent.AComp : InnerComponent;
+ const OnComp = InnerComponent.OnComp
+ ? InnerComponent.OnComp
+ : InnerComponent;
return !!features.find(el => el.name === featureName && el.active) ? (
- <AComp {...otherProps} />
- ) : InnerComponent.BComp ? (
- <InnerComponent.BComp {...otherProps} />
+ <OnComp {...otherProps} />
+ ) : InnerComponent.OffComp ? (
+ <InnerComponent.OffComp {...otherProps} />
) : null;
};
diff --git a/openecomp-ui/src/sdc-app/features/restToggle.js b/openecomp-ui/src/sdc-app/features/featureToggleUtils.js
similarity index 72%
rename from openecomp-ui/src/sdc-app/features/restToggle.js
rename to openecomp-ui/src/sdc-app/features/featureToggleUtils.js
index 505dace..1263336 100644
--- a/openecomp-ui/src/sdc-app/features/restToggle.js
+++ b/openecomp-ui/src/sdc-app/features/featureToggleUtils.js
@@ -16,9 +16,16 @@
import store from 'sdc-app/AppStore.js';
-export default ({ featureName, restFunction, mockResult }) => {
+export const restToggle = ({ featureName, restFunction, mockResult }) => {
const { features } = store.getState();
return !!features.find(el => el.name === featureName && el.active)
? restFunction()
: Promise.resolve(mockResult);
};
+
+export const functionToggle = (featureName, { onFunction, offFunction }) => {
+ const { features } = store.getState();
+ return !!features.find(el => el.name === featureName && el.active)
+ ? onFunction()
+ : offFunction();
+};
diff --git a/openecomp-ui/src/sdc-app/onboarding/OnboardingActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/OnboardingActionHelper.js
index 2fccfcb..b8ce714 100644
--- a/openecomp-ui/src/sdc-app/onboarding/OnboardingActionHelper.js
+++ b/openecomp-ui/src/sdc-app/onboarding/OnboardingActionHelper.js
@@ -45,6 +45,8 @@
import licenseModelOverviewActionHelper from 'sdc-app/onboarding/licenseModel/overview/licenseModelOverviewActionHelper.js';
import { tabsMapping as attachmentsTabsMapping } from 'sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachmentsConstants.js';
import SoftwareProductAttachmentsActionHelper from 'sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachmentsActionHelper.js';
+import { actionTypes as filterActionTypes } from './onboard/filter/FilterConstants.js';
+import FeaturesActionHelper from 'sdc-app/features/FeaturesActionHelper.js';
function setCurrentScreen(dispatch, screen, props = {}) {
dispatch({
@@ -74,11 +76,16 @@
SoftwareProductActionHelper.fetchArchivedSoftwareProductList(dispatch);
},
- navigateToOnboardingCatalog(dispatch) {
+ async navigateToOnboardingCatalog(dispatch) {
+ await FeaturesActionHelper.getFeaturesList(dispatch);
UsersActionHelper.fetchUsersList(dispatch);
this.loadItemsLists(dispatch);
OnboardActionHelper.resetOnboardStore(dispatch);
setCurrentScreen(dispatch, enums.SCREEN.ONBOARDING_CATALOG);
+ dispatch({
+ type: filterActionTypes.FILTER_DATA_CHANGED,
+ deltaData: {}
+ });
},
autoSaveBeforeNavigate(
@@ -207,6 +214,7 @@
{ softwareProductId, version, status }
) {
SoftwareProductComponentsActionHelper.clearComponentsStore(dispatch);
+ LicenseModelActionHelper.fetchFinalizedLicenseModels(dispatch);
SoftwareProductActionHelper.fetchSoftwareProduct(dispatch, {
softwareProductId,
version
@@ -559,7 +567,7 @@
);
},
- navigateToVersionsPage(
+ async navigateToVersionsPage(
dispatch,
{ itemType, itemId, itemName, additionalProps, users }
) {
@@ -568,19 +576,19 @@
allUsers: users
});
VersionsPageActionHelper.selectNone(dispatch);
- VersionsPageActionHelper.fetchVersions(dispatch, {
+ await VersionsPageActionHelper.fetchVersions(dispatch, {
itemType,
itemId
- }).then(() => {
- ItemsHelper.fetchItem(itemId).then(result => {
- setCurrentScreen(dispatch, enums.SCREEN.VERSIONS_PAGE, {
- status: result.status,
- itemType,
- itemId,
- itemName,
- additionalProps
- });
- });
+ });
+ const items = await ItemsHelper.fetchItem(itemId);
+ setCurrentScreen(dispatch, enums.SCREEN.VERSIONS_PAGE, {
+ status: items.status,
+ itemType,
+ itemId,
+ itemName,
+ vendorName: items.properties.vendorName,
+ vendorId: items.properties.vendorId,
+ additionalProps
});
},
diff --git a/openecomp-ui/src/sdc-app/onboarding/OnboardingPunchOut.jsx b/openecomp-ui/src/sdc-app/onboarding/OnboardingPunchOut.jsx
index f462dd7..245dd2b 100644
--- a/openecomp-ui/src/sdc-app/onboarding/OnboardingPunchOut.jsx
+++ b/openecomp-ui/src/sdc-app/onboarding/OnboardingPunchOut.jsx
@@ -21,8 +21,6 @@
import isEqual from 'lodash/isEqual.js';
-import lodashUnionBy from 'lodash/unionBy.js';
-
import i18n from 'nfvo-utils/i18n/i18n.js';
import Application from 'sdc-app/Application.jsx';
import store from 'sdc-app/AppStore.js';
@@ -356,10 +354,6 @@
handleStoreChange() {
let {
currentScreen,
- licenseModelList,
- finalizedLicenseModelList,
- softwareProductList,
- finalizedSoftwareProductList,
versionsPage: { versionsList: { itemType, itemId } },
softwareProduct: {
softwareProductEditor: {
@@ -367,26 +361,17 @@
},
softwareProductComponents: { componentsList }
},
- archivedLicenseModelList,
- archivedSoftwareProductList
+ licenseModel: {
+ licenseModelEditor: { data: currentLicenseModel = {} }
+ }
} = store.getState();
- const wholeSoftwareProductList = lodashUnionBy(
- softwareProductList,
- [...finalizedSoftwareProductList, ...archivedSoftwareProductList],
- 'id'
- );
- const wholeLicenseModelList = lodashUnionBy(
- licenseModelList,
- [...finalizedLicenseModelList, ...archivedLicenseModelList],
- 'id'
- );
+
let breadcrumbsData = {
itemType,
itemId,
currentScreen,
- wholeLicenseModelList,
- wholeSoftwareProductList,
currentSoftwareProduct,
+ currentLicenseModel,
componentsList
};
@@ -415,8 +400,7 @@
itemType,
itemId,
currentSoftwareProduct,
- wholeLicenseModelList,
- wholeSoftwareProductList,
+ currentLicenseModel,
componentsList
}) {
let {
@@ -435,12 +419,12 @@
? [
{
selectedKey: itemId,
- menuItems: wholeLicenseModelList.map(
- ({ id, name }) => ({
- key: id,
- displayText: name
- })
- )
+ menuItems: [
+ {
+ key: itemId,
+ displayText: props.itemName
+ }
+ ]
}
]
: [
@@ -448,12 +432,12 @@
selectedKey:
props.additionalProps.licenseModelId ||
currentSoftwareProduct.vendorId,
- menuItems: wholeLicenseModelList.map(
- ({ id, name }) => ({
- key: id,
- displayText: name
- })
- )
+ menuItems: [
+ {
+ key: props.vendorId,
+ displayText: props.vendorName
+ }
+ ]
},
{
selectedKey:
@@ -472,17 +456,12 @@
},
{
selectedKey: itemId,
- menuItems: wholeSoftwareProductList
- .filter(
- ({ id, vendorId }) =>
- vendorId ===
- currentSoftwareProduct.vendorId ||
- id === itemId
- )
- .map(({ id, name }) => ({
- key: id,
- displayText: name
- }))
+ menuItems: [
+ {
+ key: itemId,
+ displayText: props.itemName
+ }
+ ]
}
];
return [
@@ -519,13 +498,13 @@
};
return [
{
- selectedKey: props.licenseModelId,
- menuItems: wholeLicenseModelList.map(
- ({ id, name }) => ({
- key: id,
- displayText: name
- })
- )
+ selectedKey: currentLicenseModel.id,
+ menuItems: [
+ {
+ key: currentLicenseModel.id,
+ displayText: currentLicenseModel.vendorName
+ }
+ ]
},
{
selectedKey: enums.BREADCRUMS.LICENSE_MODEL,
@@ -533,19 +512,7 @@
{
key: enums.BREADCRUMS.LICENSE_MODEL,
displayText: i18n('License Model')
- },
- ...(wholeSoftwareProductList.findIndex(
- ({ vendorId }) =>
- vendorId === props.licenseModelId
- ) === -1
- ? []
- : [
- {
- key:
- enums.BREADCRUMS.SOFTWARE_PRODUCT,
- displayText: i18n('Software Products')
- }
- ])
+ }
]
},
{
@@ -636,16 +603,16 @@
[enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_MONITORING]:
enums.BREADCRUMS.SOFTWARE_PRODUCT_COMPONENT_MONITORING
};
- let licenseModelId = currentSoftwareProduct.vendorId;
+
let returnedBreadcrumb = [
{
- selectedKey: licenseModelId,
- menuItems: wholeLicenseModelList.map(
- ({ id, name }) => ({
- key: id,
- displayText: name
- })
- )
+ selectedKey: currentSoftwareProduct.vendorId,
+ menuItems: [
+ {
+ key: currentSoftwareProduct.vendorId,
+ displayText: currentSoftwareProduct.vendorName
+ }
+ ]
},
{
selectedKey: enums.BREADCRUMS.SOFTWARE_PRODUCT,
@@ -661,17 +628,13 @@
]
},
{
- selectedKey: props.softwareProductId,
- menuItems: wholeSoftwareProductList
- .filter(
- ({ vendorId, id }) =>
- vendorId === licenseModelId ||
- id === props.softwareProductId
- )
- .map(({ id, name }) => ({
- key: id,
- displayText: name
- }))
+ selectedKey: currentSoftwareProduct.id,
+ menuItems: [
+ {
+ key: currentSoftwareProduct.id,
+ displayText: currentSoftwareProduct.name
+ }
+ ]
},
.../*screen === enums.SCREEN.SOFTWARE_PRODUCT_LANDING_PAGE ? [] :*/ [
{
diff --git a/openecomp-ui/src/sdc-app/onboarding/OnboardingReducersMap.js b/openecomp-ui/src/sdc-app/onboarding/OnboardingReducersMap.js
index 3b526a6..09f4ffb 100644
--- a/openecomp-ui/src/sdc-app/onboarding/OnboardingReducersMap.js
+++ b/openecomp-ui/src/sdc-app/onboarding/OnboardingReducersMap.js
@@ -28,7 +28,7 @@
import mergeEditorReducer from 'sdc-app/common/merge/MergeEditorReducer.js';
import revisionsReducer from './revisions/RevisionsReducer.js';
import featuresReducer from 'sdc-app/features/FeaturesReducer.js';
-
+import itemsReducer from 'sdc-app/onboarding/onboard/filter/ItemsReducer.js';
export default {
currentScreen: currentScreenReducer,
licenseModel: licenseModelReducer,
@@ -44,5 +44,6 @@
users: usersReducer,
versionsPage: versionsPageReducer,
revisions: revisionsReducer,
- features: featuresReducer
+ features: featuresReducer,
+ filteredItems: itemsReducer
};
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModelActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModelActionHelper.js
index cfff9f1..be33af7 100644
--- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModelActionHelper.js
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/LicenseModelActionHelper.js
@@ -29,8 +29,11 @@
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';
+import {
+ itemStatus,
+ versionStatus
+} from 'sdc-app/common/helpers/ItemsHelperConstants.js';
function baseUrl() {
const restPrefix = Configuration.get('restPrefix');
@@ -39,19 +42,17 @@
function fetchLicenseModels() {
return RestAPIUtil.fetch(
- `${baseUrl()}?versionFilter=${catalogItemStatuses.DRAFT}`
+ `${baseUrl()}?versionFilter=${versionStatus.DRAFT}`
);
}
function fetchFinalizedLicenseModels() {
return RestAPIUtil.fetch(
- `${baseUrl()}?versionFilter=${catalogItemStatuses.CERTIFIED}`
+ `${baseUrl()}?versionFilter=${versionStatus.CERTIFIED}`
);
}
function fetchArchivedLicenseModels() {
- return RestAPIUtil.fetch(
- `${baseUrl()}?Status=${catalogItemStatuses.ARCHIVED}`
- );
+ return RestAPIUtil.fetch(`${baseUrl()}?Status=${itemStatus.ARCHIVED}`);
}
function fetchLicenseModelById(licenseModelId, version) {
const { id: versionId } = version;
@@ -206,9 +207,8 @@
version
}).then(({ inMerge, isDirty, updatedVersion }) => {
if (
- (updatedVersion.status === catalogItemStatuses.CERTIFIED ||
- updatedVersion.archivedStatus ===
- catalogItemStatuses.ARCHIVED) &&
+ (updatedVersion.status === versionStatus.CERTIFIED ||
+ updatedVersion.archivedStatus === versionStatus.ARCHIVED) &&
(action === VersionControllerActionsEnum.COMMIT ||
action === VersionControllerActionsEnum.SYNC)
) {
@@ -217,8 +217,7 @@
itemId: licenseModelId
});
const msg =
- updatedVersion.archivedStatus ===
- catalogItemStatuses.ARCHIVED
+ updatedVersion.archivedStatus === versionStatus.ARCHIVED
? i18n('Item was Archived')
: i18n('Item version already Certified');
dispatch({
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 4bbab86..c6a0702 100644
--- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/creation/LicenseModelCreation.js
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/creation/LicenseModelCreation.js
@@ -14,8 +14,12 @@
* limitations under the License.
*/
import { connect } from 'react-redux';
+import featureToggle from 'sdc-app/features/featureToggle.js';
+import { featureToggleNames } from 'sdc-app/features/FeaturesConstants.js';
import LicenseModelCreationActionHelper from './LicenseModelCreationActionHelper.js';
import LicenseModelCreationView from './LicenseModelCreationView.jsx';
+import LicenseModelCreationViewWithFilter from './LicenseModelCreationViewWithFilter.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';
@@ -23,6 +27,16 @@
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';
+import UniqueTypesHelper from 'sdc-app/common/helpers/UniqueTypesHelper.js';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import { itemType } from 'sdc-app/common/helpers/ItemsHelperConstants.js';
+
+const ToggledLicenseModelCreationView = featureToggle(
+ featureToggleNames.FILTER
+)({
+ OnComp: LicenseModelCreationViewWithFilter,
+ OffComp: LicenseModelCreationView
+});
export const mapStateToProps = ({
users: { usersList },
@@ -87,10 +101,22 @@
});
},
onValidateForm: formName =>
- ValidationHelper.validateForm(dispatch, formName)
+ ValidationHelper.validateForm(dispatch, formName),
+ isNameUnique: (value, name, formName) =>
+ UniqueTypesHelper.isNameUnique(dispatch, {
+ value,
+ name,
+ formName,
+ errorText: `${i18n(
+ 'License model by the name'
+ )} ${value} ${i18n('already exists')}. ${i18n(
+ 'License model name must be unique'
+ )}`,
+ itemType: itemType.VLM
+ })
};
};
export default connect(mapStateToProps, mapActionsToProps)(
- LicenseModelCreationView
+ ToggledLicenseModelCreationView
);
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/creation/LicenseModelCreationReducer.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/creation/LicenseModelCreationReducer.js
index 7137230..5922a47 100644
--- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/creation/LicenseModelCreationReducer.js
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/creation/LicenseModelCreationReducer.js
@@ -40,7 +40,8 @@
errorText: '',
validations: [
{ type: 'required', data: true },
- { type: 'maxLength', data: 25 }
+ { type: 'maxLength', data: 25 },
+ { type: 'validateName', data: true }
]
}
}
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/creation/LicenseModelCreationViewWithFilter.jsx b/openecomp-ui/src/sdc-app/onboarding/licenseModel/creation/LicenseModelCreationViewWithFilter.jsx
new file mode 100644
index 0000000..8c5d966
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/creation/LicenseModelCreationViewWithFilter.jsx
@@ -0,0 +1,116 @@
+/*
+ * Copyright © 2016-2018 European Support Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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';
+import { LICENSE_MODEL_CREATION_FORM_NAME } from './LicenseModelCreationConstants.js';
+
+const LicenseModelPropType = PropTypes.shape({
+ id: PropTypes.string,
+ vendorName: PropTypes.string,
+ description: PropTypes.string
+});
+
+class LicenseModelCreationView extends React.Component {
+ static propTypes = {
+ data: LicenseModelPropType,
+ VLMNames: PropTypes.object,
+ usersList: PropTypes.array,
+ onDataChanged: PropTypes.func.isRequired,
+ onSubmit: PropTypes.func.isRequired,
+ onValidateForm: PropTypes.func.isRequired,
+ onCancel: PropTypes.func.isRequired
+ };
+
+ render() {
+ let { data = {}, onDataChanged, genericFieldInfo } = this.props;
+ let { vendorName, description } = data;
+ return (
+ <div>
+ {genericFieldInfo && (
+ <Form
+ ref="validationForm"
+ hasButtons={true}
+ onSubmit={() => this.submit()}
+ submitButtonText={i18n('Create')}
+ onReset={() => this.props.onCancel()}
+ labledButtons={true}
+ isValid={this.props.isFormValid}
+ formReady={this.props.formReady}
+ onValidateForm={() => this.validate()}>
+ <Input
+ value={vendorName}
+ label={i18n('Vendor Name')}
+ data-test-id="vendor-name"
+ onChange={vendorName =>
+ onDataChanged(
+ { vendorName },
+ LICENSE_MODEL_CREATION_FORM_NAME
+ )
+ }
+ onBlur={e =>
+ this.validateIsNameUnique(e.target.value)
+ }
+ isValid={genericFieldInfo.vendorName.isValid}
+ errorText={genericFieldInfo.vendorName.errorText}
+ type="text"
+ isRequired={true}
+ className="field-section"
+ />
+ <Input
+ isRequired={true}
+ value={description}
+ label={i18n('Description')}
+ data-test-id="vendor-description"
+ overlayPos="bottom"
+ onChange={description =>
+ onDataChanged(
+ { description },
+ LICENSE_MODEL_CREATION_FORM_NAME
+ )
+ }
+ isValid={genericFieldInfo.description.isValid}
+ errorText={genericFieldInfo.description.errorText}
+ type="textarea"
+ className="field-section"
+ />
+ </Form>
+ )}
+ </div>
+ );
+ }
+
+ submit() {
+ const { data: licenseModel, usersList } = this.props;
+ this.props.onSubmit(licenseModel, usersList);
+ }
+
+ validateIsNameUnique(value) {
+ this.props.isNameUnique(
+ value,
+ 'vendorName',
+ LICENSE_MODEL_CREATION_FORM_NAME
+ );
+ }
+
+ validate() {
+ this.props.onValidateForm(LICENSE_MODEL_CREATION_FORM_NAME);
+ }
+}
+
+export default LicenseModelCreationView;
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 d01b9d0..c0de0ee 100644
--- a/openecomp-ui/src/sdc-app/onboarding/onboard/CatalogItemDetails.stories.js
+++ b/openecomp-ui/src/sdc-app/onboarding/onboard/CatalogItemDetails.stories.js
@@ -2,11 +2,9 @@
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 { catalogItemTypes } from './onboardingCatalog/OnboardingCatalogConstants.js';
import { FinalizedLicenseModelFactory } from 'test-utils/factories/licenseModel/LicenseModelFactories.js';
+import { versionStatus } from 'sdc-app/common/helpers/ItemsHelperConstants.js';
const stories = storiesOf('CatalogTiles', module);
stories.addDecorator(withKnobs);
@@ -22,9 +20,9 @@
let vlm = {
...FinalizedLicenseModelFactory.build({ name: 'Test-VLM' }),
- itemStatus: catalogItemStatuses.DRAFT
+ itemStatus: versionStatus.DRAFT
};
-let certifiedVlm = { ...vlm, itemStatus: catalogItemStatuses.CERTIFIED };
+let certifiedVlm = { ...vlm, itemStatus: versionStatus.CERTIFIED };
stories.add('preview', () => (
<div className="catalog-view">
diff --git a/openecomp-ui/src/sdc-app/onboarding/onboard/DetailsCatalogView.jsx b/openecomp-ui/src/sdc-app/onboarding/onboard/DetailsCatalogView.jsx
index 771c0eb..b535595 100644
--- a/openecomp-ui/src/sdc-app/onboarding/onboard/DetailsCatalogView.jsx
+++ b/openecomp-ui/src/sdc-app/onboarding/onboard/DetailsCatalogView.jsx
@@ -13,6 +13,7 @@
* or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/
+import isEqual from 'lodash/isEqual.js';
import React from 'react';
import PropTypes from 'prop-types';
import { catalogItemTypes } from './onboardingCatalog/OnboardingCatalogConstants.js';
@@ -20,6 +21,28 @@
import CatalogList from './CatalogList.jsx';
import CatalogItemDetails from './CatalogItemDetails.jsx';
+function renderCatalogItems({
+ items,
+ type,
+ filter,
+ onSelect,
+ onMigrate,
+ users
+}) {
+ const filteredItems = items.length
+ ? filterCatalogItemsByType({ items, filter })
+ : [];
+ return filteredItems.map(item => (
+ <CatalogItemDetails
+ key={item.id}
+ catalogItemData={item}
+ catalogItemTypeClass={type}
+ onMigrate={onMigrate}
+ onSelect={() => onSelect(item, users)}
+ />
+ ));
+}
+
class DetailsCatalogView extends React.Component {
static propTypes = {
VLMList: PropTypes.array,
@@ -31,18 +54,14 @@
filter: PropTypes.string.isRequired
};
- 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)}
- />
- ));
+ shouldComponentUpdate(nextProps) {
+ const shouldUpdate =
+ isEqual(nextProps.VLMList, this.props.VLMList) &&
+ isEqual(nextProps.VSPList, this.props.VSPList) &&
+ isEqual(nextProps.users, this.props.users) &&
+ isEqual(nextProps.filter, this.props.filter);
+ return !shouldUpdate;
}
-
render() {
let {
VLMList,
@@ -57,7 +76,7 @@
} = this.props;
return (
<CatalogList onAddVLM={onAddVLM} onAddVSP={onAddVSP}>
- {this.renderCatalogItems({
+ {renderCatalogItems({
items: VLMList,
type: catalogItemTypes.LICENSE_MODEL,
filter,
@@ -65,7 +84,7 @@
onMigrate,
users
})}
- {this.renderCatalogItems({
+ {renderCatalogItems({
items: VSPList,
type: catalogItemTypes.SOFTWARE_PRODUCT,
filter,
diff --git a/openecomp-ui/src/sdc-app/onboarding/onboard/Onboard.js b/openecomp-ui/src/sdc-app/onboarding/onboard/Onboard.js
index a1e0018..ea70f9c 100644
--- a/openecomp-ui/src/sdc-app/onboarding/onboard/Onboard.js
+++ b/openecomp-ui/src/sdc-app/onboarding/onboard/Onboard.js
@@ -22,7 +22,7 @@
import SoftwareProductCreationActionHelper from '../softwareProduct/creation/SoftwareProductCreationActionHelper.js';
import sortByStringProperty from 'nfvo-utils/sortByStringProperty.js';
import { tabsMapping } from './onboardingCatalog/OnboardingCatalogConstants.js';
-import { itemsType } from './filter/FilterConstants.js';
+import { itemStatus } from 'sdc-app/common/helpers/ItemsHelperConstants.js';
export const mapStateToProps = ({
onboard: { onboardingCatalog, activeTab, searchValue, filter },
@@ -32,7 +32,8 @@
archivedSoftwareProductList,
finalizedLicenseModelList,
softwareProductList,
- finalizedSoftwareProductList
+ finalizedSoftwareProductList,
+ filteredItems
}) => {
const fullSoftwareProducts = softwareProductList
.filter(
@@ -50,6 +51,23 @@
return accum;
};
+ const reduceFilteredLicenseModelList = (accum, vlm) => {
+ let currentSoftwareProductList = sortByStringProperty(
+ filteredItems.vspList.filter(vsp => vsp.vendorId === vlm.id),
+ 'name'
+ );
+ accum.push({ ...vlm, softwareProductList: currentSoftwareProductList });
+ return accum;
+ };
+
+ const updatedFilteredItems = {
+ vspList: [...filteredItems.vspList],
+ vlmList: sortByStringProperty(
+ filteredItems.vlmList.reduce(reduceFilteredLicenseModelList, []),
+ 'name'
+ )
+ };
+
licenseModelList = sortByStringProperty(
licenseModelList.reduce(reduceLicenseModelList, []),
'name'
@@ -72,7 +90,7 @@
} = onboardingCatalog;
if (filter.byVendorView) {
catalogActiveTab = tabsMapping.BY_VENDOR;
- } else if (filter.itemsType && filter.itemsType === itemsType.ARCHIVED) {
+ } else if (filter.itemStatus && filter.itemStatus === itemStatus.ARCHIVED) {
catalogActiveTab = tabsMapping.ARCHIVE;
}
@@ -89,7 +107,8 @@
searchValue,
vspOverlay,
selectedVendor,
- users: users.usersList
+ users: users.usersList,
+ filteredItems: updatedFilteredItems
};
};
diff --git a/openecomp-ui/src/sdc-app/onboarding/onboard/OnboardActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/onboard/OnboardActionHelper.js
index 87ec2d1..2826e32 100644
--- a/openecomp-ui/src/sdc-app/onboarding/onboard/OnboardActionHelper.js
+++ b/openecomp-ui/src/sdc-app/onboarding/onboard/OnboardActionHelper.js
@@ -1,25 +1,30 @@
-/*!
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+/*
+ * Copyright © 2016-2018 European Support Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing
- * permissions and limitations under the License.
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
import { tabsMapping, actionTypes } from './OnboardConstants.js';
import ScreensHelper from 'sdc-app/common/helpers/ScreensHelper.js';
import { enums, screenTypes } from 'sdc-app/onboarding/OnboardingConstants.js';
import VersionsPageActionHelper from 'sdc-app/onboarding/versionsPage/VersionsPageActionHelper.js';
-import { catalogItemStatuses } from 'sdc-app/onboarding/onboard/onboardingCatalog/OnboardingCatalogConstants.js';
+
import { itemTypes } from 'sdc-app/onboarding/versionsPage/VersionsPageConstants.js';
import PermissionsActionHelper from 'sdc-app/onboarding/permissions/PermissionsActionHelper.js';
+import { actionTypes as filterActionTypes } from './filter/FilterConstants.js';
+import {
+ versionStatus,
+ itemStatus
+} from 'sdc-app/common/helpers/ItemsHelperConstants.js';
const OnboardActionHelper = {
resetOnboardStore(dispatch) {
@@ -33,6 +38,18 @@
type: actionTypes.CHANGE_ACTIVE_ONBOARD_TAB,
activeTab
});
+ dispatch({
+ type: filterActionTypes.FILTER_DATA_CHANGED,
+ deltaData:
+ activeTab === tabsMapping.WORKSPACE
+ ? {
+ versionStatus: versionStatus.DRAFT,
+ itemStatus: itemStatus.ACTIVE
+ }
+ : {
+ versionStatus: versionStatus.CERTIFIED
+ }
+ });
},
changeSearchValue(dispatch, searchValue) {
dispatch({
@@ -54,7 +71,7 @@
itemType: itemTypes.LICENSE_MODEL
}).then(({ results }) => {
results = results.filter(
- version => version.status === catalogItemStatuses.DRAFT
+ version => version.status === versionStatus.DRAFT
);
if (results.length !== 1) {
ScreensHelper.loadScreen(dispatch, {
@@ -104,7 +121,7 @@
itemType: itemTypes.SOFTWARE_PRODUCT
}).then(({ results }) => {
results = results.filter(
- version => version.status === catalogItemStatuses.DRAFT
+ version => version.status === versionStatus.DRAFT
);
if (results.length !== 1) {
ScreensHelper.loadScreen(dispatch, {
diff --git a/openecomp-ui/src/sdc-app/onboarding/onboard/OnboardView.jsx b/openecomp-ui/src/sdc-app/onboarding/onboard/OnboardView.jsx
index dcaeaa7..0fc64b3 100644
--- a/openecomp-ui/src/sdc-app/onboarding/onboard/OnboardView.jsx
+++ b/openecomp-ui/src/sdc-app/onboarding/onboard/OnboardView.jsx
@@ -16,7 +16,9 @@
import React from 'react';
import PropTypes from 'prop-types';
import OnboardingCatalogView from './onboardingCatalog/OnboardingCatalogView.jsx';
+import OnboardingCatalogViewWithFilter from './onboardingCatalog/OnboardingCatalogViewWithFilter.jsx';
import WorkspaceView from './workspace/WorkspaceView.jsx';
+import WorkspaceViewWithFilter from './workspace/WorkspaceViewWithFilter.jsx';
import { tabsMapping } from './OnboardConstants.js';
import i18n from 'nfvo-utils/i18n/i18n.js';
import classnames from 'classnames';
@@ -25,7 +27,8 @@
import { catalogItemTypes } from './onboardingCatalog/OnboardingCatalogConstants.js';
import NotificationsView from 'sdc-app/onboarding/userNotifications/NotificationsView.jsx';
import Filter from 'sdc-app/onboarding/onboard/filter/Filter.jsx';
-
+import featureToggle from 'sdc-app/features/featureToggle.js';
+import { featureToggleNames } from 'sdc-app/features/FeaturesConstants.js';
const OnboardHeaderTabs = ({ onTabClick, activeTab }) => (
<div className="onboard-header-tabs">
<div
@@ -47,6 +50,16 @@
</div>
);
+const ToggledOnboardingCatalogView = featureToggle(featureToggleNames.FILTER)({
+ OnComp: OnboardingCatalogViewWithFilter,
+ OffComp: OnboardingCatalogView
+});
+
+const ToggledWorkspaceView = featureToggle(featureToggleNames.FILTER)({
+ OnComp: WorkspaceViewWithFilter,
+ OffComp: WorkspaceView
+});
+
const OnboardHeader = ({ onSearch, activeTab, onTabClick, searchValue }) => (
<div className="onboard-header">
<OnboardHeaderTabs activeTab={activeTab} onTabClick={onTabClick} />
@@ -85,11 +98,11 @@
renderViewByTab(activeTab) {
switch (activeTab) {
case tabsMapping.WORKSPACE:
- return <WorkspaceView {...this.props} />;
+ return <ToggledWorkspaceView {...this.props} />;
case tabsMapping.CATALOG:
- return <OnboardingCatalogView {...this.props} />;
+ return <ToggledOnboardingCatalogView {...this.props} />;
default:
- return <WorkspaceView {...this.props} />;
+ return <ToggledWorkspaceView {...this.props} />;
}
}
diff --git a/openecomp-ui/src/sdc-app/onboarding/onboard/filter/Filter.jsx b/openecomp-ui/src/sdc-app/onboarding/onboard/filter/Filter.jsx
index c80232d..a00357c 100644
--- a/openecomp-ui/src/sdc-app/onboarding/onboard/filter/Filter.jsx
+++ b/openecomp-ui/src/sdc-app/onboarding/onboard/filter/Filter.jsx
@@ -17,14 +17,19 @@
import { connect } from 'react-redux';
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 Accordion from 'nfvo-components/accordion/Accordion.jsx';
-import { actionTypes } from './FilterConstants.js';
import featureToggle from 'sdc-app/features/featureToggle.js';
import { featureToggleNames } from 'sdc-app/features/FeaturesConstants.js';
import { tabsMapping as onboardTabsMapping } from '../OnboardConstants.js';
-import { itemsType as itemsTypeConstants } from './FilterConstants.js';
+import { actionTypes } from './FilterConstants.js';
+
+import Panel from 'sdc-ui/lib/react/Panel.js';
+import {
+ ItemStatus,
+ ByVendorView,
+ EntityType,
+ Permissions,
+ OnboardingProcedure
+} from './FilterComponents.jsx';
const mapStateToProps = ({ onboard: { filter, activeTab } }) => {
return {
@@ -35,145 +40,39 @@
const mapActionsToProps = dispatch => {
return {
- onDataChanged: deltaData =>
+ onDataChanged: deltaData => {
dispatch({
type: actionTypes.FILTER_DATA_CHANGED,
deltaData
- })
+ });
+ }
};
};
-const Filter = ({
- onDataChanged,
- data: {
- entityTypeVsp,
- entityTypeVlm,
- roleOwner,
- roleContributor,
- roleViewer,
- procedureNetwork,
- procedureManual,
- recentlyUpdated,
- byVendorView,
- itemsType
- },
- activeTab
-}) => (
- <div className="catalog-filter">
- {activeTab === onboardTabsMapping.CATALOG && (
- <Input
- type="select"
- className="catalog-filter-items-type"
- data-test-id="catalog-filter-items-type"
- disabled={byVendorView}
- value={itemsType}
- onChange={e => onDataChanged({ itemsType: e.target.value })}>
- <option
- key={itemsTypeConstants.ACTIVE}
- value={itemsTypeConstants.ACTIVE}>
- Active Items
- </option>
- <option
- key={itemsTypeConstants.ARCHIVED}
- value={itemsTypeConstants.ARCHIVED}>
- Archived Items
- </option>
- </Input>
- )}
- {activeTab === onboardTabsMapping.CATALOG && (
- <Input
- label={i18n('By Vendor View')}
- type="checkbox"
- disabled={itemsType === itemsTypeConstants.ARCHIVED}
- checked={byVendorView}
- onChange={byVendorView => onDataChanged({ byVendorView })}
- data-test-id="filter-by-vendor-view"
- value=""
- />
- )}
- <Input
- label={i18n('Recently Updated')}
- type="checkbox"
- checked={recentlyUpdated}
- onChange={recentlyUpdated => onDataChanged({ recentlyUpdated })}
- data-test-id="filter-recently-updated"
- value=""
- />
-
- <Accordion title={i18n('ENTITY TYPE')}>
- <Input
- label={i18n('VSP')}
- type="checkbox"
- checked={entityTypeVsp}
- onChange={entityTypeVsp => onDataChanged({ entityTypeVsp })}
- data-test-id="filter-type-vsp"
- value=""
- />
- <Input
- label={i18n('VLM')}
- type="checkbox"
- checked={entityTypeVlm}
- onChange={entityTypeVlm => onDataChanged({ entityTypeVlm })}
- data-test-id="filter-type-vlm"
- value=""
- />
- </Accordion>
-
- <Accordion title={i18n('ROLE')}>
- <Input
- label={i18n('Owner')}
- type="checkbox"
- checked={roleOwner}
- onChange={roleOwner => onDataChanged({ roleOwner })}
- data-test-id="filter-role-owner"
- value=""
- />
- <Input
- label={i18n('Contributer')}
- type="checkbox"
- checked={roleContributor}
- onChange={roleContributor => onDataChanged({ roleContributor })}
- data-test-id="filter-role-contributor"
- value=""
- />
- <Input
- label={i18n('Viewer')}
- type="checkbox"
- checked={roleViewer}
- onChange={roleViewer => onDataChanged({ roleViewer })}
- data-test-id="filter-role-viewr"
- value=""
- />
- </Accordion>
-
- <Accordion title={i18n('ONBOARDING PROCEDURE')}>
- <Input
- label={i18n('Network Package')}
- type="checkbox"
- checked={procedureNetwork}
- onChange={procedureNetwork =>
- onDataChanged({ procedureNetwork })
- }
- data-test-id="filter-procedure-network"
- value=""
- />
- <Input
- label={i18n('Manual')}
- type="checkbox"
- checked={procedureManual}
- onChange={procedureManual => onDataChanged({ procedureManual })}
- data-test-id="filter-procedure-manual"
- value=""
- />
- </Accordion>
- </div>
-);
+const Filter = ({ onDataChanged, data, activeTab }) => {
+ return (
+ <Panel className="catalog-filter">
+ <ItemStatus data={data} onDataChanged={onDataChanged} />
+ <EntityType data={data} onDataChanged={onDataChanged} />
+ <Permissions data={data} onDataChanged={onDataChanged} />
+ <OnboardingProcedure data={data} onDataChanged={onDataChanged} />
+ {activeTab === onboardTabsMapping.CATALOG && (
+ <ByVendorView data={data} onDataChanged={onDataChanged} />
+ )}
+ </Panel>
+ );
+};
Filter.PropTypes = {
onDataChanged: PropTypes.func,
- data: PropTypes.object
+ data: PropTypes.object,
+ activeTab: PropTypes.number
};
export default featureToggle(featureToggleNames.FILTER)(
connect(mapStateToProps, mapActionsToProps)(Filter)
);
+
+export const ConnectedFilter = connect(mapStateToProps, mapActionsToProps)(
+ Filter
+);
diff --git a/openecomp-ui/src/sdc-app/onboarding/onboard/filter/FilterActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/onboard/filter/FilterActionHelper.js
new file mode 100644
index 0000000..f8155df
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/onboard/filter/FilterActionHelper.js
@@ -0,0 +1,60 @@
+/*
+ * Copyright © 2016-2018 European Support Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { default as ItemsHelper } from 'sdc-app/common/helpers/ItemsHelper.js';
+import {
+ itemType,
+ versionStatus
+} from 'sdc-app/common/helpers/ItemsHelperConstants.js';
+import { actionTypes } from './FilterConstants.js';
+
+const FilterActionHelper = {
+ async updateFilteredItems(dispatch, filter) {
+ let permission = { ...filter.permission };
+ if (
+ filter.versionStatus === versionStatus.DRAFT &&
+ !permission.Owner &&
+ !permission.Contributor
+ ) {
+ permission.Owner = true;
+ permission.Contributor = true;
+ }
+ const items = await ItemsHelper.fetchItems({
+ ...filter,
+ permission
+ });
+ let vspList = [];
+ let vlmList = [];
+ items.results.map(item => {
+ if (item.type === itemType.VSP) {
+ const { properties, ...all } = item;
+ vspList.push({ ...all, ...properties });
+ } else {
+ vlmList.push(item);
+ }
+ });
+
+ dispatch({
+ type: actionTypes.UPDATE_FILTERED_LIST,
+ data: {
+ vspList,
+ vlmList
+ }
+ });
+ }
+};
+
+export default FilterActionHelper;
diff --git a/openecomp-ui/src/sdc-app/onboarding/onboard/filter/FilterComponents.jsx b/openecomp-ui/src/sdc-app/onboarding/onboard/filter/FilterComponents.jsx
new file mode 100644
index 0000000..65ec733
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/onboard/filter/FilterComponents.jsx
@@ -0,0 +1,145 @@
+/*
+ * Copyright © 2016-2018 European Support Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import React from 'react';
+import Input from 'nfvo-components/input/validation/Input.jsx';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import { itemStatus } from 'sdc-app/common/helpers/ItemsHelperConstants.js';
+import Accordion from 'sdc-ui/lib/react/Accordion.js';
+import Checklist from 'sdc-ui/lib/react/Checklist.js';
+import Checkbox from 'sdc-ui/lib/react/Checkbox.js';
+
+export const ItemStatus = ({ data, onDataChanged, byVendorView }) => (
+ <Input
+ type="select"
+ className="catalog-filter-items-type"
+ data-test-id="catalog-filter-items-type"
+ disabled={byVendorView}
+ value={data.itemStatus}
+ onChange={e => onDataChanged({ itemStatus: e.target.value }, data)}>
+ <option key={itemStatus.ACTIVE} value={itemStatus.ACTIVE}>
+ {i18n('Active Items')}
+ </option>
+ <option key={itemStatus.ARCHIVED} value={itemStatus.ARCHIVED}>
+ {i18n('Archived Items')}
+ </option>
+ </Input>
+);
+
+const FilterList = ({ title, items, groupKey, onDataChanged, data }) => {
+ let onChange = value => {
+ let obj = {};
+ obj[groupKey] = { ...data[groupKey], ...value };
+ onDataChanged(obj);
+ };
+ return (
+ <Accordion title={title}>
+ <Checklist items={items} onChange={onChange} />
+ </Accordion>
+ );
+};
+
+export const ByVendorView = ({ data, onDataChanged }) => (
+ <Checkbox
+ label={i18n('By Vendor View')}
+ className="catalog-filter-by-vendor-view"
+ disabled={data.itemsType === itemStatus.ARCHIVED}
+ checked={data.byVendorView}
+ onChange={byVendorView => onDataChanged({ byVendorView }, data)}
+ data-test-id="filter-by-vendor-view"
+ value=""
+ />
+);
+
+export const EntityType = ({ data, onDataChanged }) => {
+ const items = [
+ {
+ label: i18n('VSP'),
+ dataTestId: 'catalog-filter-type-vsp',
+ value: 'vsp',
+ checked: data.itemType && data.itemType.vsp
+ },
+ {
+ label: i18n('VLM'),
+ dataTestId: 'catalog-ilter-type-vlm',
+ value: 'vlm',
+ checked: data.itemType && data.itemType.vlm
+ }
+ ];
+ return (
+ <FilterList
+ title={i18n('ENTITY TYPE')}
+ items={items}
+ onDataChanged={onDataChanged}
+ data={data}
+ groupKey="itemType"
+ />
+ );
+};
+
+export const Permissions = ({ data, onDataChanged }) => {
+ const items = [
+ {
+ label: i18n('Owner'),
+ dataTestId: 'catalog-filter-permission-owner',
+ value: 'Owner',
+ checked: data.permission && data.permission.Owner
+ },
+ {
+ label: i18n('Contributor'),
+ dataTestId: 'catalog-filter-permission-contributor',
+ value: 'Contributor',
+ checked: data.permission && data.permission.Contributor
+ }
+ ];
+
+ return (
+ <FilterList
+ title={i18n('PERMISSIONS')}
+ items={items}
+ onDataChanged={onDataChanged}
+ data={data}
+ groupKey="permission"
+ />
+ );
+};
+
+export const OnboardingProcedure = ({ data, onDataChanged }) => {
+ const items = [
+ {
+ label: i18n('Network Package'),
+ dataTestId: 'catalog-filter-procedure-network',
+ value: 'NetworkPackage',
+ checked:
+ data.onboardingMethod && data.onboardingMethod.NetworkPackage
+ },
+ {
+ label: i18n('Manual'),
+ dataTestId: 'catalog-filter-procedure-manual',
+ value: 'Manual',
+ checked: data.onboardingMethod && data.onboardingMethod.Manual
+ }
+ ];
+
+ return (
+ <FilterList
+ title={i18n('ONBOARDING PROCEDURE')}
+ items={items}
+ onDataChanged={onDataChanged}
+ data={data}
+ groupKey="onboardingMethod"
+ />
+ );
+};
diff --git a/openecomp-ui/src/sdc-app/onboarding/onboard/filter/FilterConstants.js b/openecomp-ui/src/sdc-app/onboarding/onboard/filter/FilterConstants.js
index edfe592..9dce52d 100644
--- a/openecomp-ui/src/sdc-app/onboarding/onboard/filter/FilterConstants.js
+++ b/openecomp-ui/src/sdc-app/onboarding/onboard/filter/FilterConstants.js
@@ -17,10 +17,6 @@
import keyMirror from 'nfvo-utils/KeyMirror.js';
export const actionTypes = keyMirror({
- FILTER_DATA_CHANGED: null
+ FILTER_DATA_CHANGED: null,
+ UPDATE_FILTERED_LIST: null
});
-
-export const itemsType = {
- ACTIVE: '1',
- ARCHIVED: '2'
-};
diff --git a/openecomp-ui/src/sdc-app/onboarding/onboard/filter/FilterMiddleware.js b/openecomp-ui/src/sdc-app/onboarding/onboard/filter/FilterMiddleware.js
new file mode 100644
index 0000000..8490bfe
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/onboard/filter/FilterMiddleware.js
@@ -0,0 +1,32 @@
+/*
+ * Copyright © 2016-2018 European Support Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import FilterActionHelper from './FilterActionHelper.js';
+import { actionTypes } from './FilterConstants.js';
+
+const filterUpdater = store => next => action => {
+ if (action.type === actionTypes.FILTER_DATA_CHANGED) {
+ const filter = store.getState().onboard.filter;
+
+ FilterActionHelper.updateFilteredItems(store.dispatch, {
+ ...filter,
+ ...action.deltaData
+ });
+ }
+ return next(action);
+};
+
+export default filterUpdater;
diff --git a/openecomp-ui/src/sdc-app/onboarding/onboard/filter/FilterReducer.js b/openecomp-ui/src/sdc-app/onboarding/onboard/filter/FilterReducer.js
index f1e8574..28b3475 100644
--- a/openecomp-ui/src/sdc-app/onboarding/onboard/filter/FilterReducer.js
+++ b/openecomp-ui/src/sdc-app/onboarding/onboard/filter/FilterReducer.js
@@ -14,8 +14,19 @@
* limitations under the License.
*/
import { actionTypes } from './FilterConstants.js';
+import {
+ itemStatus,
+ versionStatus
+} from 'sdc-app/common/helpers/ItemsHelperConstants.js';
-export default (state = {}, action) => {
+const defaultState = {
+ itemStatus: itemStatus.ACTIVE,
+ versionStatus: versionStatus.DRAFT,
+ entityType: {},
+ permission: {},
+ onboardingMethod: {}
+};
+export default (state = defaultState, action) => {
switch (action.type) {
case actionTypes.FILTER_DATA_CHANGED:
return {
diff --git a/openecomp-ui/src/sdc-app/onboarding/onboard/filter/ItemsReducer.js b/openecomp-ui/src/sdc-app/onboarding/onboard/filter/ItemsReducer.js
new file mode 100644
index 0000000..fa1528d
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/onboard/filter/ItemsReducer.js
@@ -0,0 +1,24 @@
+/*
+ * Copyright © 2016-2018 European Support Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 './FilterConstants.js';
+export default (state = { vspList: [], vlmList: [] }, action) => {
+ switch (action.type) {
+ case actionTypes.UPDATE_FILTERED_LIST:
+ return action.data;
+ default:
+ return state;
+ }
+};
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 2cc32c2..a416d36 100644
--- a/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/OnboardingCatalogView.jsx
+++ b/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/OnboardingCatalogView.jsx
@@ -83,8 +83,8 @@
);
const FeaturedCatalogHeader = featureToggle(featureToggleNames.FILTER)({
- AComp: FilterCatalogHeader,
- BComp: CatalogHeader
+ OnComp: FilterCatalogHeader,
+ OffComp: CatalogHeader
});
class OnboardingCatalogView extends React.Component {
diff --git a/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/OnboardingCatalogViewWithFilter.jsx b/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/OnboardingCatalogViewWithFilter.jsx
new file mode 100644
index 0000000..86c437d
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/OnboardingCatalogViewWithFilter.jsx
@@ -0,0 +1,147 @@
+/*
+ * Copyright © 2016-2018 European Support Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 DetailsCatalogView from 'sdc-app/onboarding/onboard/DetailsCatalogView.jsx';
+import VendorCatalogView from './VendorCatalogView.jsx';
+import { tabsMapping } from './OnboardingCatalogConstants.js';
+import { tabsMapping as WCTabsMapping } from 'sdc-app/onboarding/onboard/OnboardConstants.js';
+
+const CatalogHeader = () => (
+ <div className="catalog-header">
+ <div className="catalog-header-tabs">
+ <div className="catalog-header-tab active">
+ {i18n('ONBOARD CATALOG')}
+ </div>
+ </div>
+ </div>
+);
+
+class OnboardingCatalogView extends React.Component {
+ renderViewByTab(activeTab) {
+ const {
+ users,
+ vspOverlay,
+ onSelectLicenseModel,
+ onSelectSoftwareProduct,
+ onAddLicenseModelClick,
+ onAddSoftwareProductClick,
+ onVspOverlayChange,
+ onVendorSelect,
+ selectedVendor,
+ searchValue,
+ onMigrate,
+ filteredItems
+ } = this.props;
+
+ const { vlmList, vspList } = filteredItems;
+
+ switch (activeTab) {
+ case tabsMapping.ARCHIVE:
+ return (
+ <DetailsCatalogView
+ VLMList={vlmList}
+ VSPList={vspList}
+ users={users}
+ onSelectVLM={(item, users) =>
+ onSelectLicenseModel(
+ item,
+ users,
+ WCTabsMapping.CATALOG
+ )
+ }
+ onSelectVSP={(item, users) =>
+ onSelectSoftwareProduct(
+ item,
+ users,
+ WCTabsMapping.CATALOG
+ )
+ }
+ filter={searchValue}
+ onMigrate={onMigrate}
+ />
+ );
+ case tabsMapping.ACTIVE:
+ return (
+ <DetailsCatalogView
+ VLMList={vlmList}
+ VSPList={vspList}
+ users={users}
+ onAddVLM={onAddLicenseModelClick}
+ onAddVSP={onAddSoftwareProductClick}
+ onSelectVLM={(item, users) =>
+ onSelectLicenseModel(
+ item,
+ users,
+ WCTabsMapping.CATALOG
+ )
+ }
+ onSelectVSP={(item, users) =>
+ onSelectSoftwareProduct(
+ item,
+ users,
+ WCTabsMapping.CATALOG
+ )
+ }
+ filter={searchValue}
+ onMigrate={onMigrate}
+ />
+ );
+ case tabsMapping.BY_VENDOR:
+ default:
+ return (
+ <VendorCatalogView
+ licenseModelList={vlmList}
+ users={users}
+ onAddVSP={onAddSoftwareProductClick}
+ onAddVLM={onAddLicenseModelClick}
+ onSelectVSP={(item, users) =>
+ onSelectSoftwareProduct(
+ item,
+ users,
+ WCTabsMapping.CATALOG
+ )
+ }
+ onSelectVLM={(item, users) =>
+ onSelectLicenseModel(
+ item,
+ users,
+ WCTabsMapping.CATALOG
+ )
+ }
+ vspOverlay={vspOverlay}
+ onVendorSelect={onVendorSelect}
+ selectedVendor={selectedVendor}
+ onVspOverlayChange={onVspOverlayChange}
+ onMigrate={onMigrate}
+ filter={searchValue}
+ />
+ );
+ }
+ }
+
+ render() {
+ const { selectedVendor, catalogActiveTab: activeTab } = this.props;
+ return (
+ <div className="catalog-wrapper">
+ {!selectedVendor && <CatalogHeader />}
+ {this.renderViewByTab(activeTab)}
+ </div>
+ );
+ }
+}
+
+export default OnboardingCatalogView;
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 bef47d5..12beff7 100644
--- a/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/VendorItem.jsx
+++ b/openecomp-ui/src/sdc-app/onboarding/onboard/onboardingCatalog/VendorItem.jsx
@@ -60,8 +60,8 @@
</TileInfoLine>
<TileInfoLine>
<Button
- btnType="outline-rounded"
- color="dark-gray"
+ btnType="secondary"
+ className="venodor-tile-btn"
onClick={e => this.handleVspCountClick(e)}
data-test-id="catalog-vsp-count"
disabled={!softwareProductList.length}>
diff --git a/openecomp-ui/src/sdc-app/onboarding/onboard/workspace/WorkspaceViewWithFilter.jsx b/openecomp-ui/src/sdc-app/onboarding/onboard/workspace/WorkspaceViewWithFilter.jsx
new file mode 100644
index 0000000..eec5962
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/onboard/workspace/WorkspaceViewWithFilter.jsx
@@ -0,0 +1,57 @@
+/*
+ * Copyright © 2016-2018 European Support Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import React from 'react';
+import DetailsCatalogView from '../DetailsCatalogView.jsx';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import { tabsMapping } from 'sdc-app/onboarding/onboard/OnboardConstants.js';
+
+const WorkspaceView = props => {
+ let {
+ onAddLicenseModelClick,
+ users,
+ onAddSoftwareProductClick,
+ onSelectLicenseModel,
+ onSelectSoftwareProduct,
+ searchValue,
+ onMigrate,
+ filteredItems: { vspList, vlmList }
+ } = props;
+
+ return (
+ <div className="catalog-wrapper workspace-view">
+ <div className="catalog-header workspace-header">
+ {i18n('WORKSPACE')}
+ </div>
+ <DetailsCatalogView
+ VLMList={vlmList}
+ VSPList={vspList}
+ users={users}
+ onAddVLM={onAddLicenseModelClick}
+ onAddVSP={onAddSoftwareProductClick}
+ onSelectVLM={(item, users) =>
+ onSelectLicenseModel(item, users, tabsMapping.WORKSPACE)
+ }
+ onSelectVSP={(item, users) =>
+ onSelectSoftwareProduct(item, users, tabsMapping.WORKSPACE)
+ }
+ onMigrate={onMigrate}
+ filter={searchValue}
+ />
+ </div>
+ );
+};
+
+export default WorkspaceView;
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductActionHelper.js
index 4a2d7a2..25bd32e 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductActionHelper.js
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductActionHelper.js
@@ -45,8 +45,11 @@
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';
+import {
+ itemStatus,
+ versionStatus
+} from 'sdc-app/common/helpers/ItemsHelperConstants.js';
function getLicensingData(licensingData = {}) {
const { licenseAgreement, featureGroups } = licensingData;
@@ -112,19 +115,17 @@
function fetchSoftwareProductList() {
return RestAPIUtil.fetch(
- `${baseUrl()}?versionFilter=${catalogItemStatuses.DRAFT}`
+ `${baseUrl()}?versionFilter=${versionStatus.DRAFT}`
);
}
function fetchArchivedSoftwareProductList() {
- return RestAPIUtil.fetch(
- `${baseUrl()}?Status=${catalogItemStatuses.ARCHIVED}`
- );
+ return RestAPIUtil.fetch(`${baseUrl()}?Status=${itemStatus.ARCHIVED}`);
}
function fetchFinalizedSoftwareProductList() {
return RestAPIUtil.fetch(
- `${baseUrl()}?versionFilter=${catalogItemStatuses.CERTIFIED}`
+ `${baseUrl()}?versionFilter=${versionStatus.CERTIFIED}`
);
}
@@ -664,9 +665,8 @@
version
}).then(({ inMerge, isDirty, updatedVersion }) => {
if (
- (updatedVersion.status === catalogItemStatuses.CERTIFIED ||
- updatedVersion.archivedStatus ===
- catalogItemStatuses.ARCHIVED) &&
+ (updatedVersion.status === versionStatus.CERTIFIED ||
+ updatedVersion.archivedStatus === itemStatus.ARCHIVED) &&
(action === VersionControllerActionsEnum.COMMIT ||
action === VersionControllerActionsEnum.SYNC)
) {
@@ -675,8 +675,7 @@
itemId: softwareProductId
});
const msg =
- updatedVersion.archivedStatus ===
- catalogItemStatuses.ARCHIVED
+ updatedVersion.archivedStatus === itemStatus.ARCHIVED
? i18n('Item was Archived')
: i18n('Item version already Certified');
dispatch({
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 41584d9..9a7d257 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreation.js
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreation.js
@@ -14,9 +14,11 @@
* permissions and limitations under the License.
*/
import { connect } from 'react-redux';
-
+import featureToggle from 'sdc-app/features/featureToggle.js';
+import { featureToggleNames } from 'sdc-app/features/FeaturesConstants.js';
import SoftwareProductCreationActionHelper from './SoftwareProductCreationActionHelper.js';
import SoftwareProductCreationView from './SoftwareProductCreationView.jsx';
+import SoftwareProductCreationViewWithFilter from './SoftwareProductCreationViewWithFilter.jsx';
import ValidationHelper from 'sdc-app/common/helpers/ValidationHelper.js';
import SoftwareProductActionHelper from '../SoftwareProductActionHelper.js';
import VersionsPageActionHelper from 'sdc-app/onboarding/versionsPage/VersionsPageActionHelper.js';
@@ -24,6 +26,16 @@
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';
+import UniqueTypesHelper from 'sdc-app/common/helpers/UniqueTypesHelper.js';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import { itemType } from 'sdc-app/common/helpers/ItemsHelperConstants.js';
+
+const ToggledSoftwareProductCreationView = featureToggle(
+ featureToggleNames.FILTER
+)({
+ OnComp: SoftwareProductCreationViewWithFilter,
+ OffComp: SoftwareProductCreationView
+});
export const mapStateToProps = ({
finalizedLicenseModelList,
@@ -33,7 +45,7 @@
finalizedSoftwareProductList,
softwareProduct: { softwareProductCreation, softwareProductCategories }
}) => {
- let { genericFieldInfo } = softwareProductCreation;
+ let { genericFieldInfo, vendorList = [] } = softwareProductCreation;
let isFormValid = ValidationHelper.checkFormValid(genericFieldInfo);
let VSPNames = {};
@@ -52,6 +64,7 @@
disableVendor: softwareProductCreation.disableVendor,
softwareProductCategories,
finalizedLicenseModelList,
+ vendorList,
isFormValid,
formReady: softwareProductCreation.formReady,
genericFieldInfo,
@@ -99,10 +112,22 @@
});
},
onValidateForm: formName =>
- ValidationHelper.validateForm(dispatch, formName)
+ ValidationHelper.validateForm(dispatch, formName),
+ isNameUnique: (value, name, formName) =>
+ UniqueTypesHelper.isNameUnique(dispatch, {
+ value,
+ name,
+ formName,
+ errorText: `${i18n(
+ 'Software product by the name'
+ )} ${value} ${i18n('already exists')}. ${i18n(
+ 'Software product name must be unique'
+ )}`,
+ itemType: itemType.VSP
+ })
};
};
export default connect(mapStateToProps, mapActionsToProps, null, {
withRef: true
-})(SoftwareProductCreationView);
+})(ToggledSoftwareProductCreationView);
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 1b1fd71..259b50b 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreationActionHelper.js
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreationActionHelper.js
@@ -24,7 +24,11 @@
import { modalContentMapper } from 'sdc-app/common/modal/ModalContentMapper.js';
import { actionTypes } from './SoftwareProductCreationConstants.js';
import i18n from 'nfvo-utils/i18n/i18n.js';
-
+import ItemsHelper from 'sdc-app/common/helpers/ItemsHelper.js';
+import {
+ itemStatus,
+ versionStatus
+} from 'sdc-app/common/helpers/ItemsHelperConstants.js';
function baseUrl() {
const restPrefix = Configuration.get('restPrefix');
return `${restPrefix}/v1.0/vendor-software-products/`;
@@ -45,7 +49,7 @@
type: actionTypes.OPEN,
selectedVendorId: vendorId
});
-
+ this.loadVendorList(dispatch);
dispatch({
type: modalActionTypes.GLOBAL_MODAL_SHOW,
data: {
@@ -78,6 +82,19 @@
});
return result;
});
+ },
+ async loadVendorList(dispatch) {
+ const { results } = await ItemsHelper.fetchItems({
+ itemStatus: itemStatus.ACTIVE,
+ versionStatus: versionStatus.CERTIFIED,
+ itemType: {
+ vlm: true
+ }
+ });
+ dispatch({
+ type: actionTypes.VENDOR_LIST_LOADED,
+ vendorList: results
+ });
}
};
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 ad10346..128b3ed 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreationConstants.js
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreationConstants.js
@@ -18,7 +18,8 @@
export const actionTypes = keyMirror({
OPEN: null,
RESET_DATA: null,
- SOFTWARE_PRODUCT_CREATED: null
+ SOFTWARE_PRODUCT_CREATED: null,
+ VENDOR_LIST_LOADED: null
});
export const SP_CREATION_FORM_NAME = 'SPCREATIONFORM';
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreationReducer.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreationReducer.js
index 5f70f18..b019248 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreationReducer.js
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreationReducer.js
@@ -74,6 +74,11 @@
},
showModal: true
};
+ case actionTypes.VENDOR_LIST_LOADED:
+ return {
+ ...state,
+ vendorList: action.vendorList
+ };
case actionTypes.RESET_DATA:
return {};
default:
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreationViewWithFilter.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreationViewWithFilter.jsx
new file mode 100644
index 0000000..810337d
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/creation/SoftwareProductCreationViewWithFilter.jsx
@@ -0,0 +1,329 @@
+/*!
+ * Copyright © 2016-2018 European Support Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 Validator from 'nfvo-utils/Validator.js';
+import Input from 'nfvo-components/input/validation/Input.jsx';
+import Form from 'nfvo-components/input/validation/Form.jsx';
+import GridSection from 'nfvo-components/grid/GridSection.jsx';
+import GridItem from 'nfvo-components/grid/GridItem.jsx';
+
+import { SP_CREATION_FORM_NAME } from './SoftwareProductCreationConstants.js';
+import sortByStringProperty from 'nfvo-utils/sortByStringProperty.js';
+
+import SoftwareProductCategoriesHelper from 'sdc-app/onboarding/softwareProduct/SoftwareProductCategoriesHelper.js';
+import { onboardingMethod as onboardingMethodConst } from '../SoftwareProductConstants.js';
+
+const SoftwareProductPropType = 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: PropTypes.array,
+ softwareProductCategories: PropTypes.array,
+ VSPNames: PropTypes.object,
+ usersList: PropTypes.array,
+ onDataChanged: PropTypes.func.isRequired,
+ onSubmit: PropTypes.func.isRequired,
+ onCancel: PropTypes.func.isRequired
+ };
+
+ render() {
+ let {
+ softwareProductCategories,
+ data = {},
+ onDataChanged,
+ onCancel,
+ genericFieldInfo,
+ disableVendor
+ } = this.props;
+ let {
+ name,
+ description,
+ vendorId,
+ subCategory,
+ onboardingMethod
+ } = data;
+
+ const vendorList = this.getVendorList();
+ return (
+ <div className="software-product-creation-page">
+ {genericFieldInfo && (
+ <Form
+ ref={validationForm =>
+ (this.validationForm = validationForm)
+ }
+ hasButtons={true}
+ onSubmit={() => this.submit()}
+ onReset={() => onCancel()}
+ labledButtons={true}
+ isValid={this.props.isFormValid}
+ submitButtonText={i18n('Create')}
+ formReady={this.props.formReady}
+ onValidateForm={() => this.validate()}>
+ <GridSection hasLastColSet>
+ <GridItem colSpan="2">
+ <Input
+ value={name}
+ label={i18n('Name')}
+ isRequired={true}
+ onChange={name =>
+ onDataChanged(
+ { name },
+ SP_CREATION_FORM_NAME
+ )
+ }
+ onBlur={this.validateIsNameUnique}
+ 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}
+ overlayPos="bottom"
+ 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>
+ </GridItem>
+ <GridItem colSpan="2" stretch lastColInRow>
+ <Input
+ value={description}
+ label={i18n('Description')}
+ isRequired={true}
+ overlayPos="bottom"
+ onChange={description =>
+ onDataChanged(
+ { description },
+ SP_CREATION_FORM_NAME
+ )
+ }
+ isValid={
+ genericFieldInfo.description.isValid
+ }
+ errorText={
+ genericFieldInfo.description.errorText
+ }
+ type="textarea"
+ className="field-section"
+ data-test-id="new-vsp-description"
+ />
+ </GridItem>
+ </GridSection>
+ <OnboardingProcedure
+ genericFieldInfo={genericFieldInfo}
+ onboardingMethod={onboardingMethod}
+ onDataChanged={onDataChanged}
+ />
+ </Form>
+ )}
+ </div>
+ );
+ }
+
+ getVendorList() {
+ let { vendorList } = this.props;
+
+ return [{ enum: '', title: i18n('please select...') }].concat(
+ sortByStringProperty(vendorList, 'name').map(vendor => {
+ return {
+ enum: vendor.id,
+ title: vendor.name
+ };
+ })
+ );
+ }
+
+ onSelectVendor(e) {
+ const selectedIndex = e.target.selectedIndex;
+ const vendorId = e.target.options[selectedIndex].value;
+ this.props.onDataChanged({ vendorId }, SP_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 }, SP_CREATION_FORM_NAME);
+ }
+
+ submit() {
+ let {
+ data: softwareProduct,
+ finalizedLicenseModelList,
+ usersList
+ } = this.props;
+ softwareProduct.vendorName = finalizedLicenseModelList.find(
+ vendor => vendor.id === softwareProduct.vendorId
+ ).name;
+ this.props.onSubmit(softwareProduct, usersList);
+ }
+
+ 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"
+ )
+ };
+ }
+
+ validateIsNameUnique = e => {
+ const value = e.target.value;
+ this.props.isNameUnique(value, 'name', SP_CREATION_FORM_NAME);
+ };
+
+ validate() {
+ this.props.onValidateForm(SP_CREATION_FORM_NAME);
+ }
+}
+
+const OnboardingProcedure = ({
+ onboardingMethod,
+ onDataChanged,
+ genericFieldInfo
+}) => {
+ return (
+ <GridSection title={i18n('Onboarding procedure')}>
+ <GridItem colSpan={4}>
+ <Input
+ label={i18n('Network Package')}
+ overlayPos="top"
+ isValid={genericFieldInfo.onboardingMethod.isValid}
+ checked={
+ onboardingMethod ===
+ onboardingMethodConst.NETWORK_PACKAGE
+ }
+ errorText={genericFieldInfo.onboardingMethod.errorText}
+ onChange={() =>
+ onDataChanged(
+ {
+ onboardingMethod:
+ onboardingMethodConst.NETWORK_PACKAGE
+ },
+ SP_CREATION_FORM_NAME
+ )
+ }
+ type="radio"
+ data-test-id="new-vsp-creation-procedure-heat"
+ />
+ </GridItem>
+ <GridItem colSpan={4}>
+ <Input
+ label={i18n('Manual')}
+ overlayPos="bottom"
+ checked={onboardingMethod === onboardingMethodConst.MANUAL}
+ isValid={genericFieldInfo.onboardingMethod.isValid}
+ errorText={genericFieldInfo.onboardingMethod.errorText}
+ onChange={() =>
+ onDataChanged(
+ { onboardingMethod: onboardingMethodConst.MANUAL },
+ SP_CREATION_FORM_NAME
+ )
+ }
+ type="radio"
+ data-test-id="new-vsp-creation-procedure-manual"
+ />
+ </GridItem>
+ </GridSection>
+ );
+};
+
+export default SoftwareProductCreationView;
diff --git a/openecomp-ui/test-utils/factories/common/ItemsHelperFactory.js b/openecomp-ui/test-utils/factories/common/ItemsHelperFactory.js
new file mode 100644
index 0000000..cdfd91b
--- /dev/null
+++ b/openecomp-ui/test-utils/factories/common/ItemsHelperFactory.js
@@ -0,0 +1,45 @@
+/*
+ * Copyright © 2016-2018 European Support Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 itemFactory = new Factory()
+ .extend(IdMixin)
+ .option('isArchived', false)
+ .attrs({
+ description: () => randomstring.generate(),
+ name: () => randomstring.generate(),
+ owner: () => randomstring.generate()
+ })
+ .attr('status', ['isArchived'], isArchived => {
+ return isArchived ? 'ARCHIVE' : 'ACTIVE';
+ });
+
+export const vspFactory = new Factory().extend(itemFactory).attrs({
+ type: 'vsp',
+ properties: {
+ onboardingMethod: 'NetworkPackage',
+ vendorId: randomstring.generate(33),
+ vendorName: randomstring.generate()
+ }
+});
+
+export const vlmFactory = new Factory().extend(itemFactory).attrs({
+ type: 'vlm',
+ properties: {}
+});
diff --git a/openecomp-ui/test-utils/factories/onboard/FilterFactories.js b/openecomp-ui/test-utils/factories/onboard/FilterFactories.js
new file mode 100644
index 0000000..a659c3d
--- /dev/null
+++ b/openecomp-ui/test-utils/factories/onboard/FilterFactories.js
@@ -0,0 +1,24 @@
+/*
+ * Copyright © 2016-2018 European Support Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { Factory } from 'rosie';
+
+export const FilterFactory = new Factory().attrs({
+ entityType: {},
+ itemStatus: 'ACTIVE',
+ onboardingMethod: {},
+ permission: {},
+ versionStatus: 'Draft'
+});
diff --git a/openecomp-ui/test-utils/factories/onboard/OnboardFactories.js b/openecomp-ui/test-utils/factories/onboard/OnboardFactories.js
index 3228694..92b1255 100644
--- a/openecomp-ui/test-utils/factories/onboard/OnboardFactories.js
+++ b/openecomp-ui/test-utils/factories/onboard/OnboardFactories.js
@@ -1,23 +1,22 @@
-/*!
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+/*
+ * Copyright © 2016-2018 European Support Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing
- * permissions and limitations under the License.
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
-import {Factory} from 'rosie';
-import {storeCreator} from 'sdc-app/AppStore.js';
+import { Factory } from 'rosie';
+import { storeCreator } from 'sdc-app/AppStore.js';
const store = storeCreator();
const defaultStore = store.getState();
-export const OnboardStoreFactory = new Factory()
- .attrs(defaultStore.onboard);
+export const OnboardStoreFactory = new Factory().attrs(defaultStore.onboard);
diff --git a/openecomp-ui/test/onboard/filter/filter.test.js b/openecomp-ui/test/onboard/filter/filter.test.js
new file mode 100644
index 0000000..1b89a30
--- /dev/null
+++ b/openecomp-ui/test/onboard/filter/filter.test.js
@@ -0,0 +1,146 @@
+/*
+ * Copyright © 2016-2018 European Support Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { storeCreator } from 'sdc-app/AppStore.js';
+import mockRest from 'test-utils/MockRest.js';
+import { cloneAndSet } from 'test-utils/Util.js';
+import { actionTypes } from 'sdc-app/onboarding/onboard/filter/FilterConstants.js';
+import {
+ vspFactory,
+ vlmFactory
+} from 'test-utils/factories/common/ItemsHelperFactory.js';
+import { FilterFactory } from 'test-utils/factories/onboard/FilterFactories.js';
+import {
+ itemStatus,
+ versionStatus
+} from 'sdc-app/common/helpers/ItemsHelperConstants.js';
+import OnboardActionHelper from 'sdc-app/onboarding/onboard/OnboardActionHelper.js';
+import { tabsMapping } from 'sdc-app/onboarding/onboard/OnboardConstants.js';
+
+const vsps = vspFactory.buildList(1);
+const vlms = vlmFactory.buildList(1);
+
+const timeoutPromise = new Promise(resolve => {
+ setTimeout(function() {
+ resolve();
+ }, 100);
+});
+
+describe('Onboard Filter Tests', () => {
+ it('basic test', done => {
+ const store = storeCreator();
+
+ mockRest.addHandler('fetch', ({ data, options, baseUrl }) => {
+ expect(baseUrl).toEqual(
+ `/onboarding-api/v1.0/items?&itemStatus=${
+ itemStatus.ACTIVE
+ }&versionStatus=${versionStatus.DRAFT}`
+ );
+ expect(data).toEqual(undefined);
+ expect(options).toEqual(undefined);
+ return { results: [] };
+ });
+ const expectedStore = store.getState();
+ store.dispatch({
+ type: actionTypes.FILTER_DATA_CHANGED,
+ deltaData: {}
+ });
+ return timeoutPromise.then(function() {
+ expect(store.getState()).toEqual(expectedStore);
+ done();
+ });
+ });
+ /**
+ * TODO Turn ON when FILTER TOGGLE Will BE REMOVED
+ */
+ /*
+ it('load certifed data', done => {
+ const store = storeCreator();
+
+ mockRest.addHandler('fetch', ({ data, options, baseUrl }) => {
+ expect(baseUrl).toEqual(
+ `/onboarding-api/v1.0/items?&itemStatus=${
+ itemStatus.ACTIVE
+ }&versionStatus=${versionStatus.CERTIFIED}`
+ );
+ expect(data).toEqual(undefined);
+ expect(options).toEqual(undefined);
+ return {
+ results: [...vsps, ...vlms]
+ };
+ });
+
+ const expectedStore = cloneAndSet(
+ store.getState(),
+ 'onboard.filter',
+ FilterFactory.build({ versionStatus: versionStatus.CERTIFIED })
+ );
+
+ const expectedFilteredItems = {
+ vspList: [
+ ...vsps.map(({ properties, ...other }) => ({
+ ...other,
+ ...properties
+ }))
+ ],
+ vlmList: [...vlms]
+ };
+ const expectedStoreWithFilteredLists = cloneAndSet(
+ expectedStore,
+ 'filteredItems',
+ expectedFilteredItems
+ );
+ store.dispatch({
+ type: actionTypes.FILTER_DATA_CHANGED,
+ deltaData: { versionStatus: versionStatus.CERTIFIED }
+ });
+
+ return timeoutPromise.then(function() {
+ expect(store.getState()).toEqual(expectedStoreWithFilteredLists);
+ done();
+ });
+ });
+ */
+ it('onboarding tabs switching filter updates', done => {
+ const store = storeCreator();
+
+ mockRest.addHandler('fetch', ({ data, options, baseUrl }) => {
+ expect(baseUrl).toEqual(
+ `/onboarding-api/v1.0/items?&itemStatus=${
+ itemStatus.ACTIVE
+ }&versionStatus=${versionStatus.CERTIFIED}`
+ );
+ expect(data).toEqual(undefined);
+ expect(options).toEqual(undefined);
+ return { results: [] };
+ });
+
+ expect(store.getState().onboard.filter.versionStatus).toEqual(
+ versionStatus.DRAFT
+ );
+
+ OnboardActionHelper.changeActiveTab(
+ store.dispatch,
+ tabsMapping.CATALOG
+ );
+
+ return timeoutPromise.then(() => {
+ expect(store.getState().onboard.filter.versionStatus).toEqual(
+ versionStatus.CERTIFIED
+ );
+ done();
+ });
+ });
+});
diff --git a/openecomp-ui/test/onboard/filter/filterView.test.js b/openecomp-ui/test/onboard/filter/filterView.test.js
new file mode 100644
index 0000000..536f02c
--- /dev/null
+++ b/openecomp-ui/test/onboard/filter/filterView.test.js
@@ -0,0 +1,34 @@
+/*
+ * Copyright © 2016-2018 European Support Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import React from 'react';
+import { mount } from 'enzyme';
+import { Provider } from 'react-redux';
+import { storeCreator } from 'sdc-app/AppStore.js';
+import { ConnectedFilter } from 'sdc-app/onboarding//onboard//filter/Filter.jsx';
+
+describe('Filter component view Tests', () => {
+ it('simple jsx test', () => {
+ const store = storeCreator();
+ const wrapper = mount(
+ <Provider store={store}>
+ <ConnectedFilter />
+ </Provider>
+ );
+ const filter = wrapper.find('.catalog-filter');
+ expect(filter.hasClass('catalog-filter')).toBeTruthy();
+ });
+});
diff --git a/openecomp-ui/test/onboard/test.js b/openecomp-ui/test/onboard/test.js
index 232c561..a75070b 100644
--- a/openecomp-ui/test/onboard/test.js
+++ b/openecomp-ui/test/onboard/test.js
@@ -13,50 +13,64 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-import {storeCreator} from 'sdc-app/AppStore.js';
-import {OnboardStoreFactory} from 'test-utils/factories/onboard/OnboardFactories.js';
+import { storeCreator } from 'sdc-app/AppStore.js';
+import { OnboardStoreFactory } from 'test-utils/factories/onboard/OnboardFactories.js';
import OnboardActionHelper from 'sdc-app/onboarding/onboard/OnboardActionHelper.js';
import OnboardingCatalogActionHelper from 'sdc-app/onboarding/onboard/onboardingCatalog/OnboardingCatalogActionHelper.js';
-import {tabsMapping as onboardTabsMapping} from 'sdc-app/onboarding/onboard/OnboardConstants.js';
-import {tabsMapping as onboardCatalogTabsMapping} from 'sdc-app/onboarding/onboard/onboardingCatalog/OnboardingCatalogConstants.js';
+import { tabsMapping as onboardTabsMapping } from 'sdc-app/onboarding/onboard/OnboardConstants.js';
+import { tabsMapping as onboardCatalogTabsMapping } from 'sdc-app/onboarding/onboard/onboardingCatalog/OnboardingCatalogConstants.js';
+import { FilterFactory } from 'test-utils/factories/onboard/FilterFactories.js';
describe('Onboard Module Tests', () => {
- it('should return default state', () => {
- const store = storeCreator();
- const expectedStore = OnboardStoreFactory.build();
- expect(store.getState().onboard).toEqual(expectedStore);
- });
+ it('should return default state', () => {
+ const store = storeCreator();
+ const expectedStore = OnboardStoreFactory.build();
+ expect(store.getState().onboard).toEqual(expectedStore);
+ });
- it('should change active tab to Catalog', () => {
- const store = storeCreator();
- const expectedStore = OnboardStoreFactory.build({activeTab: onboardTabsMapping.CATALOG});
- OnboardActionHelper.changeActiveTab(store.dispatch, onboardTabsMapping.CATALOG);
- expect(store.getState().onboard).toEqual(expectedStore);
- });
+ it('should change active tab to Catalog', () => {
+ const store = storeCreator();
+ const expectedStore = OnboardStoreFactory.build({
+ activeTab: onboardTabsMapping.CATALOG,
+ filter: FilterFactory.build({ versionStatus: 'Certified' })
+ });
+ OnboardActionHelper.changeActiveTab(
+ store.dispatch,
+ onboardTabsMapping.CATALOG
+ );
+ expect(store.getState().onboard).toEqual(expectedStore);
+ });
- it('should change searchValue', () => {
- const store = storeCreator();
- const expectedStore = OnboardStoreFactory.build({searchValue: 'hello'});
- OnboardActionHelper.changeSearchValue(store.dispatch, 'hello');
- expect(store.getState().onboard).toEqual(expectedStore);
- });
+ it('should change searchValue', () => {
+ const store = storeCreator();
+ const expectedStore = OnboardStoreFactory.build({
+ searchValue: 'hello'
+ });
+ OnboardActionHelper.changeSearchValue(store.dispatch, 'hello');
+ expect(store.getState().onboard).toEqual(expectedStore);
+ });
- it('should clear searchValue', () => {
- const store = storeCreator();
- const expectedStore = OnboardStoreFactory.build();
- OnboardActionHelper.changeSearchValue(store.dispatch, 'hello');
- OnboardActionHelper.clearSearchValue(store.dispatch);
- expect(store.getState().onboard).toEqual(expectedStore);
- });
+ it('should clear searchValue', () => {
+ const store = storeCreator();
+ const expectedStore = OnboardStoreFactory.build();
+ OnboardActionHelper.changeSearchValue(store.dispatch, 'hello');
+ OnboardActionHelper.clearSearchValue(store.dispatch);
+ expect(store.getState().onboard).toEqual(expectedStore);
+ });
- it('should reset store', () => {
- const store = storeCreator();
- const expectedStore = OnboardStoreFactory.build();
- OnboardActionHelper.changeSearchValue(store.dispatch, 'hello');
- OnboardActionHelper.changeActiveTab(store.dispatch, onboardTabsMapping.CATALOG);
- OnboardingCatalogActionHelper.changeActiveTab(store.dispatch, onboardCatalogTabsMapping.ACTIVE);
- OnboardActionHelper.resetOnboardStore(store.dispatch, 'hello');
- expect(store.getState().onboard).toEqual(expectedStore);
- });
-
+ it('should reset store', () => {
+ const store = storeCreator();
+ const expectedStore = OnboardStoreFactory.build();
+ OnboardActionHelper.changeSearchValue(store.dispatch, 'hello');
+ OnboardActionHelper.changeActiveTab(
+ store.dispatch,
+ onboardTabsMapping.CATALOG
+ );
+ OnboardingCatalogActionHelper.changeActiveTab(
+ store.dispatch,
+ onboardCatalogTabsMapping.ACTIVE
+ );
+ OnboardActionHelper.resetOnboardStore(store.dispatch, 'hello');
+ expect(store.getState().onboard).toEqual(expectedStore);
+ });
});
diff --git a/openecomp-ui/yarn.lock b/openecomp-ui/yarn.lock
index e7b68d1..ac8d757 100644
--- a/openecomp-ui/yarn.lock
+++ b/openecomp-ui/yarn.lock
@@ -9459,9 +9459,9 @@
js-base64 "^2.1.8"
source-map "^0.4.2"
-sdc-ui@1.6.24:
- version "1.6.24"
- resolved "https://registry.yarnpkg.com/sdc-ui/-/sdc-ui-1.6.24.tgz#059b0fe6fdc36c962b65853a8012885aa38e78a7"
+sdc-ui@1.6.27:
+ version "1.6.27"
+ resolved "https://registry.yarnpkg.com/sdc-ui/-/sdc-ui-1.6.27.tgz#d4ade66b5792355fe5758e2b7231a11c1d4c137f"
dependencies:
"@angular/common" "~2.4.8"
"@angular/core" "~2.4.8"