summaryrefslogtreecommitdiffstats
path: root/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools
diff options
context:
space:
mode:
Diffstat (limited to 'openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools')
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsActionHelper.js149
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsConfirmationModal.jsx51
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsConstants.js112
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsEditor.js53
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsEditorReducer.js44
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsEditorView.jsx167
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsListEditor.js53
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsListEditorView.jsx132
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsListReducer.js36
9 files changed, 797 insertions, 0 deletions
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsActionHelper.js
new file mode 100644
index 0000000000..631597a5b0
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsActionHelper.js
@@ -0,0 +1,149 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import RestAPIUtil from 'nfvo-utils/RestAPIUtil.js';
+import Configuration from 'sdc-app/config/Configuration.js';
+import {actionTypes as entitlementPoolsActionTypes } from './EntitlementPoolsConstants.js';
+import LicenseModelActionHelper from 'sdc-app/onboarding/licenseModel/LicenseModelActionHelper.js';
+
+function baseUrl(licenseModelId) {
+ const restPrefix = Configuration.get('restPrefix');
+ return `${restPrefix}/v1.0/vendor-license-models/${licenseModelId}/entitlement-pools`;
+}
+
+function fetchEntitlementPoolsList(licenseModelId, version) {
+ let versionQuery = version ? `?version=${version}` : '';
+ return RestAPIUtil.fetch(`${baseUrl(licenseModelId)}${versionQuery}`);
+}
+
+function postEntitlementPool(licenseModelId, entitlementPool) {
+ return RestAPIUtil.create(baseUrl(licenseModelId), {
+ name: entitlementPool.name,
+ description: entitlementPool.description,
+ thresholdValue: entitlementPool.thresholdValue,
+ thresholdUnits: entitlementPool.thresholdUnits,
+ entitlementMetric: entitlementPool.entitlementMetric,
+ increments: entitlementPool.increments,
+ aggregationFunction: entitlementPool.aggregationFunction,
+ operationalScope: entitlementPool.operationalScope,
+ time: entitlementPool.time,
+ manufacturerReferenceNumber: entitlementPool.manufacturerReferenceNumber
+ });
+}
+
+
+function putEntitlementPool(licenseModelId, previousEntitlementPool, entitlementPool) {
+ return RestAPIUtil.save(`${baseUrl(licenseModelId)}/${entitlementPool.id}`, {
+ name: entitlementPool.name,
+ description: entitlementPool.description,
+ thresholdValue: entitlementPool.thresholdValue,
+ thresholdUnits: entitlementPool.thresholdUnits,
+ entitlementMetric: entitlementPool.entitlementMetric,
+ increments: entitlementPool.increments,
+ aggregationFunction: entitlementPool.aggregationFunction,
+ operationalScope: entitlementPool.operationalScope,
+ time: entitlementPool.time,
+ manufacturerReferenceNumber: entitlementPool.manufacturerReferenceNumber
+ });
+}
+
+function deleteEntitlementPool(licenseModelId, entitlementPoolId) {
+ return RestAPIUtil.destroy(`${baseUrl(licenseModelId)}/${entitlementPoolId}`);
+}
+
+
+export default {
+ fetchEntitlementPoolsList(dispatch, {licenseModelId, version}) {
+ return fetchEntitlementPoolsList(licenseModelId, version).then(response => dispatch({
+ type: entitlementPoolsActionTypes.ENTITLEMENT_POOLS_LIST_LOADED,
+ response
+ }));
+ },
+
+ openEntitlementPoolsEditor(dispatch, {entitlementPool} = {}) {
+ dispatch({
+ type: entitlementPoolsActionTypes.entitlementPoolsEditor.OPEN,
+ entitlementPool
+ });
+ },
+
+ deleteEntitlementPool(dispatch, {licenseModelId, entitlementPoolId}) {
+ return deleteEntitlementPool(licenseModelId, entitlementPoolId).then(() => {
+ dispatch({
+ type: entitlementPoolsActionTypes.DELETE_ENTITLEMENT_POOL,
+ entitlementPoolId
+ });
+ });
+ },
+
+ entitlementPoolsEditorDataChanged(dispatch, {deltaData}) {
+ dispatch({
+ type: entitlementPoolsActionTypes.entitlementPoolsEditor.DATA_CHANGED,
+ deltaData
+ });
+ },
+
+ closeEntitlementPoolsEditor(dispatch) {
+ dispatch({
+ type: entitlementPoolsActionTypes.entitlementPoolsEditor.CLOSE
+ });
+ },
+
+ saveEntitlementPool(dispatch, {licenseModelId, previousEntitlementPool, entitlementPool}) {
+ if (previousEntitlementPool) {
+ return putEntitlementPool(licenseModelId, previousEntitlementPool, entitlementPool).then(() => {
+ dispatch({
+ type: entitlementPoolsActionTypes.EDIT_ENTITLEMENT_POOL,
+ entitlementPool
+ });
+ });
+ }
+ else {
+ return postEntitlementPool(licenseModelId, entitlementPool).then(response => {
+ dispatch({
+ type: entitlementPoolsActionTypes.ADD_ENTITLEMENT_POOL,
+ entitlementPool: {
+ ...entitlementPool,
+ id: response.value
+ }
+ });
+ });
+ }
+ },
+
+ hideDeleteConfirm(dispatch) {
+ dispatch({
+ type: entitlementPoolsActionTypes.ENTITLEMENT_POOLS_DELETE_CONFIRM,
+ entitlementPoolToDelete: false
+ });
+ },
+ openDeleteEntitlementPoolConfirm(dispatch, {entitlementPool}) {
+ dispatch({
+ type: entitlementPoolsActionTypes.ENTITLEMENT_POOLS_DELETE_CONFIRM,
+ entitlementPoolToDelete: entitlementPool
+ });
+ },
+
+ switchVersion(dispatch, {licenseModelId, version}) {
+ LicenseModelActionHelper.fetchLicenseModelById(dispatch, {licenseModelId, version}).then(() => {
+ this.fetchEntitlementPoolsList(dispatch, {licenseModelId, version});
+ });
+ }
+};
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsConfirmationModal.jsx b/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsConfirmationModal.jsx
new file mode 100644
index 0000000000..04f038f5f0
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsConfirmationModal.jsx
@@ -0,0 +1,51 @@
+import React from 'react';
+import {connect} from 'react-redux';
+import ConfirmationModalView from 'nfvo-components/confirmations/ConfirmationModalView.jsx';
+import EntitlementPoolsActionHelper from './EntitlementPoolsActionHelper.js';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+
+function renderMsg(entitlementPoolToDelete) {
+ let poolName = entitlementPoolToDelete ? entitlementPoolToDelete.name : '';
+ let msg = i18n('Are you sure you want to delete "{poolName}"?', {poolName});
+ let subMsg = entitlementPoolToDelete
+ && entitlementPoolToDelete.referencingFeatureGroups
+ && entitlementPoolToDelete.referencingFeatureGroups.length > 0 ?
+ i18n('This entitlement pool is associated with one or more feature groups') :
+ '';
+ return (
+ <div>
+ <p>{msg}</p>
+ <p>{subMsg}</p>
+ </div>
+ );
+};
+
+const mapStateToProps = ({licenseModel: {entitlementPool}}, {licenseModelId}) => {
+ let {entitlementPoolToDelete} = entitlementPool;
+ const show = entitlementPoolToDelete !== false;
+ return {
+ show,
+ title: 'Warning!',
+ type: 'warning',
+ msg: renderMsg(entitlementPoolToDelete),
+ confirmationDetails: {entitlementPoolToDelete, licenseModelId}
+ };
+};
+
+const mapActionsToProps = (dispatch) => {
+ return {
+ onConfirmed: ({entitlementPoolToDelete, licenseModelId}) => {
+ EntitlementPoolsActionHelper.deleteEntitlementPool(dispatch, {
+ licenseModelId,
+ entitlementPoolId: entitlementPoolToDelete.id
+ });
+ EntitlementPoolsActionHelper.hideDeleteConfirm(dispatch);
+ },
+ onDeclined: () => {
+ EntitlementPoolsActionHelper.hideDeleteConfirm(dispatch);
+ }
+ };
+};
+
+export default connect(mapStateToProps, mapActionsToProps)(ConfirmationModalView);
+
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsConstants.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsConstants.js
new file mode 100644
index 0000000000..8a855076f3
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsConstants.js
@@ -0,0 +1,112 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import keyMirror from 'nfvo-utils/KeyMirror.js';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+
+export const actionTypes = keyMirror({
+
+ ENTITLEMENT_POOLS_LIST_LOADED: null,
+ ADD_ENTITLEMENT_POOL: null,
+ EDIT_ENTITLEMENT_POOL: null,
+ DELETE_ENTITLEMENT_POOL: null,
+ ENTITLEMENT_POOLS_DELETE_CONFIRM: null,
+
+ entitlementPoolsEditor: {
+ OPEN: null,
+ CLOSE: null,
+ DATA_CHANGED: null,
+ }
+
+});
+
+export const enums = keyMirror({
+ SELECTED_FEATURE_GROUP_TAB: {
+ GENERAL: 1,
+ ENTITLEMENT_POOLS: 2,
+ LICENCE_KEY_GROUPS: 3
+ },
+ SELECTED_ENTITLEMENT_POOLS_BUTTONTAB: {
+ ASSOCIATED_ENTITLEMENT_POOLS: 1,
+ AVAILABLE_ENTITLEMENT_POOLS: 2
+ }
+});
+
+export const defaultState = {
+ ENTITLEMENT_POOLS_EDITOR_DATA: {
+ entitlementMetric: {choice: '', other: ''},
+ aggregationFunction: {choice: '', other: ''},
+ operationalScope: {choices: [], other: ''},
+ time: {choice: '', other: ''}
+ }
+};
+
+export const thresholdUnitType = {
+ ABSOLUTE: 'Absolute',
+ PERCENTAGE: 'Percentage'
+};
+
+export const optionsInputValues = {
+ OPERATIONAL_SCOPE: [
+ {enum: '', title: i18n('please select…')},
+ {enum: 'Network_Wide', title: 'Network Wide'},
+ {enum: 'Availability_Zone', title: 'Availability Zone'},
+ {enum: 'Data_Center', title: 'Data Center'},
+ {enum: 'Tenant', title: 'Tenant'},
+ {enum: 'VM', title: 'VM'},
+ {enum: 'CPU', title: 'CPU'},
+ {enum: 'Core', title: 'Core'}
+ ],
+ TIME: [
+ {enum: '', title: i18n('please select…')},
+ {enum: 'Hour', title: 'Hour'},
+ {enum: 'Day', title: 'Day'},
+ {enum: 'Month', title: 'Month'}
+ ],
+ AGGREGATE_FUNCTION: [
+ {enum: '', title: i18n('please select…')},
+ {enum: 'Peak', title: 'Peak'},
+ {enum: 'Average', title: 'Average'}
+ ],
+ ENTITLEMENT_METRIC: [
+ {enum: '', title: i18n('please select…')},
+ {enum: 'Software_Instances_Count', title: 'Software Instances'},
+ {enum: 'Core', title: 'Core'},
+ {enum: 'CPU', title: 'CPU'},
+ {enum: 'Trunks', title: 'Trunks'},
+ {enum: 'User', title: 'User'},
+ {enum: 'Subscribers', title: 'Subscribers'},
+ {enum: 'Tenants', title: 'Tenants'},
+ {enum: 'Tokens', title: 'Tokens'},
+ {enum: 'Seats', title: 'Seats'},
+ {enum: 'Units_TB', title: 'Units-TB'},
+ {enum: 'Units_GB', title: 'Units-GB'},
+ {enum: 'Units_MB', title: 'Units-MB'}
+ ],
+ THRESHOLD_UNITS: [
+ {enum: '', title: i18n('please select…')},
+ {enum: thresholdUnitType.ABSOLUTE, title: 'Absolute'},
+ {enum: thresholdUnitType.PERCENTAGE, title: '%'}
+ ]
+};
+
+
+
+
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsEditor.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsEditor.js
new file mode 100644
index 0000000000..d5bd07e929
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsEditor.js
@@ -0,0 +1,53 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import {connect} from 'react-redux';
+import EntitlementPoolsActionHelper from './EntitlementPoolsActionHelper.js';
+import EntitlementPoolsEditorView from './EntitlementPoolsEditorView.jsx';
+
+const mapStateToProps = ({licenseModel: {entitlementPool}}) => {
+
+
+ let {data} = entitlementPool.entitlementPoolEditor;
+
+ let previousData;
+ const entitlementPoolId = data ? data.id : null;
+ if(entitlementPoolId) {
+ previousData = entitlementPool.entitlementPoolsList.find(entitlementPool => entitlementPool.id === entitlementPoolId);
+ }
+
+ return {
+ data,
+ previousData
+ };
+};
+
+const mapActionsToProps = (dispatch, {licenseModelId}) => {
+ return {
+ onDataChanged: deltaData => EntitlementPoolsActionHelper.entitlementPoolsEditorDataChanged(dispatch, {deltaData}),
+ onCancel: () => EntitlementPoolsActionHelper.closeEntitlementPoolsEditor(dispatch),
+ onSubmit: ({previousEntitlementPool, entitlementPool}) => {
+ EntitlementPoolsActionHelper.closeEntitlementPoolsEditor(dispatch);
+ EntitlementPoolsActionHelper.saveEntitlementPool(dispatch, {licenseModelId, previousEntitlementPool, entitlementPool});
+ }
+ };
+};
+
+export default connect(mapStateToProps, mapActionsToProps)(EntitlementPoolsEditorView);
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsEditorReducer.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsEditorReducer.js
new file mode 100644
index 0000000000..86e97ecf8d
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsEditorReducer.js
@@ -0,0 +1,44 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import {actionTypes, defaultState} from './EntitlementPoolsConstants.js';
+
+export default (state = {}, action) => {
+ switch (action.type) {
+ case actionTypes.entitlementPoolsEditor.OPEN:
+ return {
+ ...state,
+ data: action.entitlementPool ? {...action.entitlementPool} : defaultState.ENTITLEMENT_POOLS_EDITOR_DATA
+ };
+ case actionTypes.entitlementPoolsEditor.DATA_CHANGED:
+ return {
+ ...state,
+ data: {
+ ...state.data,
+ ...action.deltaData
+ }
+ };
+ case actionTypes.entitlementPoolsEditor.CLOSE:
+ return {};
+ default:
+ return state;
+ }
+
+};
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsEditorView.jsx b/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsEditorView.jsx
new file mode 100644
index 0000000000..77c5a12e03
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsEditorView.jsx
@@ -0,0 +1,167 @@
+import React from 'react';
+
+
+import i18n from 'nfvo-utils/i18n/i18n.js';
+
+import ValidationForm from 'nfvo-components/input/validation/ValidationForm.jsx';
+import ValidationInput from 'nfvo-components/input/validation/ValidationInput.jsx';
+import {optionsInputValues as EntitlementPoolsOptionsInputValues, thresholdUnitType} from './EntitlementPoolsConstants.js';
+import {other as optionInputOther} from 'nfvo-components/input/inputOptions/InputOptions.jsx';
+
+
+const EntitlementPoolPropType = React.PropTypes.shape({
+ id: React.PropTypes.string,
+ name: React.PropTypes.string,
+ description: React.PropTypes.string,
+ manufacturerReferenceNumber: React.PropTypes.string,
+ operationalScope: React.PropTypes.shape({
+ choices: React.PropTypes.array,
+ other: React.PropTypes.string
+ }),
+ aggregationFunction: React.PropTypes.shape({
+ choice: React.PropTypes.string,
+ other: React.PropTypes.string
+ }),
+ increments: React.PropTypes.string,
+ time: React.PropTypes.shape({
+ choice: React.PropTypes.string,
+ other: React.PropTypes.string
+ }),
+ entitlementMetric: React.PropTypes.shape({
+ choice: React.PropTypes.string,
+ other: React.PropTypes.string
+ })
+});
+
+class EntitlementPoolsEditorView extends React.Component {
+
+ static propTypes = {
+ data: EntitlementPoolPropType,
+ previousData: EntitlementPoolPropType,
+ isReadOnlyMode: React.PropTypes.bool,
+ onDataChanged: React.PropTypes.func.isRequired,
+ onSubmit: React.PropTypes.func.isRequired,
+ onCancel: React.PropTypes.func.isRequired
+ };
+
+ static defaultProps = {
+ data: {}
+ };
+
+ render() {
+ let {data = {}, onDataChanged, isReadOnlyMode} = this.props;
+ let {
+ name, description, manufacturerReferenceNumber, operationalScope, aggregationFunction, thresholdUnits, thresholdValue,
+ increments, time, entitlementMetric} = data;
+ let thresholdValueValidation = thresholdUnits === thresholdUnitType.PERCENTAGE ? {numeric: true, required: true, maxValue: 100} : {numeric: true, required: true};
+ let timeValidation = time && time.choice === optionInputOther.OTHER ? {numeric: true, required: true} : {required: true};
+
+ return (
+ <ValidationForm
+ ref='validationForm'
+ hasButtons={true}
+ onSubmit={ () => this.submit() }
+ onReset={ () => this.props.onCancel() }
+ labledButtons={true}
+ isReadOnlyMode={isReadOnlyMode}
+ className='entitlement-pools-form'>
+ <div className='entitlement-pools-form-row'>
+ <ValidationInput
+ onChange={name => onDataChanged({name})}
+ label={i18n('Name')}
+ value={name}
+ validations={{maxLength: 120, required: true}}
+ type='text'/>
+
+ <ValidationInput
+ isMultiSelect={true}
+ onEnumChange={operationalScope => onDataChanged({operationalScope:{choices: operationalScope, other: ''}})}
+ onOtherChange={operationalScope => onDataChanged({operationalScope:{choices: [optionInputOther.OTHER], other: operationalScope}})}
+ multiSelectedEnum={operationalScope && operationalScope.choices}
+ label={i18n('Operational Scope')}
+ otherValue={operationalScope && operationalScope.other}
+ validations={{required: true}}
+ values={EntitlementPoolsOptionsInputValues.OPERATIONAL_SCOPE}/>
+
+ </div>
+ <div className='entitlement-pools-form-row'>
+ <ValidationInput
+ onChange={description => onDataChanged({description})}
+ label={i18n('Description')}
+ value={description}
+ validations={{maxLength: 1000, required: true}}
+ type='textarea'/>
+ <div className='entitlement-pools-form-row-group'>
+ <div className='entitlement-pools-form-row'>
+ <ValidationInput
+ onEnumChange={thresholdUnits => onDataChanged({thresholdUnits})}
+ selectedEnum={thresholdUnits}
+ label={i18n('Threshold Value')}
+ type='select'
+ values={EntitlementPoolsOptionsInputValues.THRESHOLD_UNITS}
+ validations={{required: true}}/>
+ <ValidationInput
+ className='entitlement-pools-form-row-threshold-value'
+ onChange={thresholdValue => onDataChanged({thresholdValue})}
+ value={thresholdValue}
+ validations={thresholdValueValidation}
+ type='text'/>
+ </div>
+
+ <ValidationInput
+ onEnumChange={entitlementMetric => onDataChanged({entitlementMetric:{choice: entitlementMetric, other: ''}})}
+ onOtherChange={entitlementMetric => onDataChanged({entitlementMetric:{choice: optionInputOther.OTHER, other: entitlementMetric}})}
+ selectedEnum={entitlementMetric && entitlementMetric.choice}
+ otherValue={entitlementMetric && entitlementMetric.other}
+ label={i18n('Entitlement Metric')}
+ validations={{required: true}}
+ values={EntitlementPoolsOptionsInputValues.ENTITLEMENT_METRIC}/>
+ <ValidationInput
+ onEnumChange={aggregationFunction => onDataChanged({aggregationFunction:{choice: aggregationFunction, other: ''}})}
+ onOtherChange={aggregationFunction => onDataChanged({aggregationFunction:{choice: optionInputOther.OTHER, other: aggregationFunction}})}
+ selectedEnum={aggregationFunction && aggregationFunction.choice}
+ otherValue={aggregationFunction && aggregationFunction.other}
+ validations={{required: true}}
+ label={i18n('Aggregate Function')}
+ values={EntitlementPoolsOptionsInputValues.AGGREGATE_FUNCTION}/>
+
+ </div>
+ </div>
+ <div className='entitlement-pools-form-row'>
+
+ <ValidationInput
+ onChange={manufacturerReferenceNumber => onDataChanged({manufacturerReferenceNumber})}
+ label={i18n('Manufacturer Reference Number')}
+ value={manufacturerReferenceNumber}
+ validations={{maxLength: 100, required: true}}
+ type='text'/>
+
+ <ValidationInput
+ onEnumChange={time => onDataChanged({time:{choice: time, other: ''}})}
+ onOtherChange={time => onDataChanged({time:{choice: optionInputOther.OTHER, other: time}})}
+ selectedEnum={time && time.choice}
+ otherValue={time && time.other}
+ validations={timeValidation}
+ label={i18n('Time')}
+ values={EntitlementPoolsOptionsInputValues.TIME}/>
+ </div>
+ <div className='entitlement-pools-form-row'>
+ <ValidationInput
+ onChange={increments => onDataChanged({increments})}
+ label={i18n('Increments')}
+ value={increments}
+ validations={{maxLength: 120}}
+ type='text'/>
+
+ </div>
+ </ValidationForm>
+ );
+ }
+
+ submit() {
+ const {data: entitlementPool, previousData: previousEntitlementPool} = this.props;
+ this.props.onSubmit({entitlementPool, previousEntitlementPool});
+ }
+}
+
+export default EntitlementPoolsEditorView;
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsListEditor.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsListEditor.js
new file mode 100644
index 0000000000..4b21a2fea8
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsListEditor.js
@@ -0,0 +1,53 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import {connect} from 'react-redux';
+import EntitlementPoolsActionHelper from './EntitlementPoolsActionHelper.js';
+import EntitlementPoolsListEditorView from './EntitlementPoolsListEditorView.jsx';
+import VersionControllerUtils from 'nfvo-components/panel/versionController/VersionControllerUtils.js';
+
+const mapStateToProps = ({licenseModel: {entitlementPool, licenseModelEditor}}) => {
+ let {entitlementPoolsList} = entitlementPool;
+ let {data} = entitlementPool.entitlementPoolEditor;
+
+ let {vendorName} = licenseModelEditor.data;
+ let isReadOnlyMode = VersionControllerUtils.isReadOnly(licenseModelEditor.data);
+
+ return {
+ vendorName,
+ entitlementPoolsList,
+ isReadOnlyMode,
+ isDisplayModal: Boolean(data),
+ isModalInEditMode: Boolean(data && data.id),
+ };
+};
+
+const mapActionsToProps = (dispatch, {licenseModelId}) => {
+ return {
+ onAddEntitlementPoolClick: () => EntitlementPoolsActionHelper.openEntitlementPoolsEditor(dispatch),
+ onEditEntitlementPoolClick: entitlementPool => EntitlementPoolsActionHelper.openEntitlementPoolsEditor(dispatch, {entitlementPool}),
+ onDeleteEntitlementPool: entitlementPool => EntitlementPoolsActionHelper.openDeleteEntitlementPoolConfirm(dispatch, {
+ licenseModelId,
+ entitlementPool
+ })
+ };
+};
+
+export default connect(mapStateToProps, mapActionsToProps)(EntitlementPoolsListEditorView);
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsListEditorView.jsx b/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsListEditorView.jsx
new file mode 100644
index 0000000000..52df102503
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsListEditorView.jsx
@@ -0,0 +1,132 @@
+import React from 'react';
+
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import Modal from 'nfvo-components/modal/Modal.jsx';
+import ListEditorView from 'nfvo-components/listEditor/ListEditorView.jsx';
+import ListEditorItemView from 'nfvo-components/listEditor/ListEditorItemView.jsx';
+
+import EntitlementPoolsEditor from './EntitlementPoolsEditor.js';
+import InputOptions, {other as optionInputOther} from 'nfvo-components/input/inputOptions/InputOptions.jsx';
+import {optionsInputValues} from './EntitlementPoolsConstants';
+import EntitlementPoolsConfirmationModal from './EntitlementPoolsConfirmationModal.jsx';
+
+
+class EntitlementPoolsListEditorView extends React.Component {
+ static propTypes = {
+ vendorName: React.PropTypes.string,
+ licenseModelId: React.PropTypes.string.isRequired,
+ entitlementPoolsList: React.PropTypes.array,
+ isReadOnlyMode: React.PropTypes.bool.isRequired,
+ isDisplayModal: React.PropTypes.bool,
+ isModalInEditMode: React.PropTypes.bool,
+ onAddEntitlementPoolClick: React.PropTypes.func,
+ onEditEntitlementPoolClick: React.PropTypes.func,
+ onDeleteEntitlementPool: React.PropTypes.func,
+ };
+
+ static defaultProps = {
+ entitlementPoolsList: []
+ };
+
+ state = {
+ localFilter: ''
+ };
+
+ render() {
+ let {licenseModelId, vendorName, isReadOnlyMode, isDisplayModal, isModalInEditMode} = this.props;
+ let {onAddEntitlementPoolClick} = this.props;
+ const {localFilter} = this.state;
+
+ return (
+ <div className='entitlement-pools-list-editor'>
+ <ListEditorView
+ title={i18n('Entitlement Pools for {vendorName} License Model', {vendorName})}
+ plusButtonTitle={i18n('Add Entitlement Pool')}
+ onAdd={onAddEntitlementPoolClick}
+ filterValue={localFilter}
+ onFilter={filter => this.setState({localFilter: filter})}
+ isReadOnlyMode={isReadOnlyMode}>
+ {this.filterList().map(entitlementPool => this.renderEntitlementPoolListItem(entitlementPool, isReadOnlyMode))}
+ </ListEditorView>
+ <Modal show={isDisplayModal} bsSize='large' animation={true} className='entitlement-pools-modal'>
+ <Modal.Header>
+ <Modal.Title>{`${isModalInEditMode ? i18n('Edit Entitlement Pool') : i18n('Create New Entitlement Pool')}`}</Modal.Title>
+ </Modal.Header>
+ <Modal.Body>
+ {
+ isDisplayModal && (
+ <EntitlementPoolsEditor licenseModelId={licenseModelId} isReadOnlyMode={isReadOnlyMode}/>
+ )
+ }
+ </Modal.Body>
+ </Modal>
+
+ <EntitlementPoolsConfirmationModal licenseModelId={licenseModelId}/>
+ </div>
+ );
+ }
+
+ filterList() {
+ let {entitlementPoolsList} = this.props;
+ let {localFilter} = this.state;
+ if(localFilter.trim()) {
+ const filter = new RegExp(escape(localFilter), 'i');
+ return entitlementPoolsList.filter(({name = '', description = ''}) => {
+ return escape(name).match(filter) || escape(description).match(filter);
+ });
+ }
+ else {
+ return entitlementPoolsList;
+ }
+ }
+
+ renderEntitlementPoolListItem(entitlementPool, isReadOnlyMode) {
+ let {id, name, description, thresholdValue, thresholdUnits, entitlementMetric, aggregationFunction,
+ manufacturerReferenceNumber, time} = entitlementPool;
+ let {onEditEntitlementPoolClick, onDeleteEntitlementPool} = this.props;
+ return (
+ <ListEditorItemView
+ key={id}
+ onSelect={() => onEditEntitlementPoolClick(entitlementPool)}
+ onDelete={() => onDeleteEntitlementPool(entitlementPool)}
+ className='list-editor-item-view'
+ isReadOnlyMode={isReadOnlyMode}>
+ <div className='list-editor-item-view-field'>
+ <div className='title'>{i18n('Name')}</div>
+ <div className='text name'>{name}</div>
+ </div>
+
+ <div className='list-editor-item-view-field'>
+ <div className='title'>{i18n('Entitlement')}</div>
+ <div className='entitlement-parameters'>{`${this.extractValue(aggregationFunction)} ${this.extractValue(entitlementMetric)} per ${this.extractValue(time)}`}</div>
+ <div className='entitlement-pools-count'>{`${thresholdValue ? thresholdValue : ''} ${this.extractUnits(thresholdUnits)}`}</div>
+ </div>
+
+ <div className='list-editor-item-view-field'>
+ <div className='title'>{i18n('Manufacturer Reference Number')}</div>
+ <div className='text contract-number'>{manufacturerReferenceNumber}</div>
+ </div>
+
+ <div className='list-editor-item-view-field'>
+ <div className='title'>{i18n('Description')}</div>
+ <div className='text description'>{description}</div>
+ </div>
+ </ListEditorItemView>
+ );
+ }
+
+
+
+ extractUnits(units) {
+ if (units === undefined) {return '';} //TODO fix it later
+ return units === 'Absolute' ? '' : '%';
+ }
+
+ extractValue(item) {
+ if (item === undefined) {return '';} //TODO fix it later
+
+ return item ? item.choice === optionInputOther.OTHER ? item.other : InputOptions.getTitleByName(optionsInputValues, item.choice) : '';
+ }
+}
+
+export default EntitlementPoolsListEditorView;
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsListReducer.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsListReducer.js
new file mode 100644
index 0000000000..63e351fce7
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsListReducer.js
@@ -0,0 +1,36 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import {actionTypes} from './EntitlementPoolsConstants';
+export default (state = [], action) => {
+ switch (action.type) {
+ case actionTypes.ENTITLEMENT_POOLS_LIST_LOADED:
+ return [...action.response.results];
+ case actionTypes.ADD_ENTITLEMENT_POOL:
+ return [...state, action.entitlementPool];
+ case actionTypes.EDIT_ENTITLEMENT_POOL:
+ const indexForEdit = state.findIndex(entitlementPool => entitlementPool.id === action.entitlementPool.id);
+ return [...state.slice(0, indexForEdit), action.entitlementPool, ...state.slice(indexForEdit + 1)];
+ case actionTypes.DELETE_ENTITLEMENT_POOL:
+ return state.filter(entitlementPool => entitlementPool.id !== action.entitlementPoolId);
+ default:
+ return state;
+ }
+};