diff options
Diffstat (limited to 'openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups')
8 files changed, 413 insertions, 72 deletions
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsActionHelper.js index dd2a5c6003..f5017f6d7a 100644 --- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsActionHelper.js +++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsActionHelper.js @@ -17,6 +17,8 @@ import RestAPIUtil from 'nfvo-utils/RestAPIUtil.js'; import Configuration from 'sdc-app/config/Configuration.js'; import {actionTypes as licenseKeyGroupsConstants} from './LicenseKeyGroupsConstants.js'; import LicenseModelActionHelper from 'sdc-app/onboarding/licenseModel/LicenseModelActionHelper.js'; +import {actionTypes as limitEditorActions} from 'sdc-app/onboarding/licenseModel/limits/LimitEditorConstants.js'; +import getValue from 'nfvo-utils/getValue.js'; function baseUrl(licenseModelId, version) { const restPrefix = Configuration.get('restPrefix'); @@ -36,8 +38,13 @@ function postLicenseKeyGroup(licenseModelId, licenseKeyGroup, version) { return RestAPIUtil.post(baseUrl(licenseModelId, version), { name: licenseKeyGroup.name, description: licenseKeyGroup.description, - operationalScope: licenseKeyGroup.operationalScope, - type: licenseKeyGroup.type + operationalScope: getValue(licenseKeyGroup.operationalScope), + type: licenseKeyGroup.type, + increments: licenseKeyGroup.increments, + thresholdValue: licenseKeyGroup.thresholdValue, + thresholdUnits: getValue(licenseKeyGroup.thresholdUnits), + startDate: licenseKeyGroup.startDate, + expiryDate: licenseKeyGroup.expiryDate }); } @@ -45,11 +52,50 @@ function putLicenseKeyGroup(licenseModelId, licenseKeyGroup, version) { return RestAPIUtil.put(`${baseUrl(licenseModelId, version)}/${licenseKeyGroup.id}`, { name: licenseKeyGroup.name, description: licenseKeyGroup.description, - operationalScope: licenseKeyGroup.operationalScope, - type: licenseKeyGroup.type + operationalScope: getValue(licenseKeyGroup.operationalScope), + type: licenseKeyGroup.type, + increments: licenseKeyGroup.increments, + thresholdValue: licenseKeyGroup.thresholdValue, + thresholdUnits: getValue(licenseKeyGroup.thresholdUnits), + startDate: licenseKeyGroup.startDate, + expiryDate: licenseKeyGroup.expiryDate }); } +function fetchLimitsList(licenseModelId, licenseKeyGroupId, version) { + return RestAPIUtil.fetch(`${baseUrl(licenseModelId, version)}/${licenseKeyGroupId}/limits`); +} + +function deleteLimit(licenseModelId, licenseKeyGroupId, version, limitId) { + return RestAPIUtil.destroy(`${baseUrl(licenseModelId, version)}/${licenseKeyGroupId}/limits/${limitId}`); +} + +function postLimit(licenseModelId, licenseKeyGroupId, version, limit) { + return RestAPIUtil.post(`${baseUrl(licenseModelId, version)}/${licenseKeyGroupId}/limits`, { + name: limit.name, + type: limit.type, + description: limit.description, + metric: limit.metric, + value: limit.value, + unit: limit.unit, + aggregationFunction: getValue(limit.aggregationFunction), + time: getValue(limit.time) + }); +} + +function putLimit(licenseModelId, licenseKeyGroupId, version, limit) { + + return RestAPIUtil.put(`${baseUrl(licenseModelId, version)}/${licenseKeyGroupId}/limits/${limit.id}`, { + name: limit.name, + type: limit.type, + description: limit.description, + metric: limit.metric, + value: limit.value, + unit: limit.unit, + aggregationFunction: getValue(limit.aggregationFunction), + time: getValue(limit.time) + }); +} export default { fetchLicenseKeyGroupsList(dispatch, {licenseModelId, version}) { @@ -59,7 +105,10 @@ export default { })); }, - openLicenseKeyGroupsEditor(dispatch, {licenseKeyGroup} = {}) { + openLicenseKeyGroupsEditor(dispatch, {licenseKeyGroup, licenseModelId, version} = {}) { + if (licenseModelId && version) { + this.fetchLimits(dispatch, {licenseModelId, version, licenseKeyGroup}); + } dispatch({ type: licenseKeyGroupsConstants.licenseKeyGroupsEditor.OPEN, licenseKeyGroup @@ -124,5 +173,34 @@ export default { LicenseModelActionHelper.fetchLicenseModelById(dispatch, {licenseModelId, version}).then(() => { this.fetchLicenseKeyGroupsList(dispatch, {licenseModelId, version}); }); + }, + + + fetchLimits(dispatch, {licenseModelId, version, licenseKeyGroup}) { + return fetchLimitsList(licenseModelId, licenseKeyGroup.id, version).then(response => { + dispatch({ + type: licenseKeyGroupsConstants.licenseKeyGroupsEditor.LIMITS_LIST_LOADED, + response + }); + }); + }, + + submitLimit(dispatch, {licenseModelId, version, licenseKeyGroup, limit}) { + const promise = limit.id ? putLimit(licenseModelId,licenseKeyGroup.id, version, limit) : + postLimit(licenseModelId,licenseKeyGroup.id, version, limit); + return promise.then(() => { + dispatch({ + type: limitEditorActions.CLOSE + }); + this.fetchLimits(dispatch, {licenseModelId, version, licenseKeyGroup}); + }); + }, + + deleteLimit(dispatch, {licenseModelId, version, licenseKeyGroup, limit}) { + return deleteLimit(licenseModelId,licenseKeyGroup.id, version, limit.id).then(() => { + this.fetchLimits(dispatch, {licenseModelId, version, licenseKeyGroup}); + }); } + + }; diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsConstants.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsConstants.js index 50d1fe8625..c376cb3fbc 100644 --- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsConstants.js +++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsConstants.js @@ -15,7 +15,7 @@ */ import keyMirror from 'nfvo-utils/KeyMirror.js'; import i18n from 'nfvo-utils/i18n/i18n.js'; -import InputOptions, {other as optionInputOther} from 'nfvo-components/input/inputOptions/InputOptions.jsx'; +import InputOptions, {other as optionInputOther} from 'nfvo-components/input/validation/InputOptions.jsx'; export const actionTypes = keyMirror({ @@ -28,6 +28,7 @@ export const actionTypes = keyMirror({ OPEN: null, CLOSE: null, DATA_CHANGED: null, + LIMITS_LIST_LOADED: null } }); @@ -77,3 +78,10 @@ export const getOperationalScopes = (operationalScope) => { return allOpScopes; } }; + +export const tabIds = { + GENERAL: 'GENERAL', + SP_LIMITS: 'SP_LIMITS', + VENDOR_LIMITS: 'VENDOR_LIMITS', + ADD_LIMIT_BUTTON: 'ADD_LIMIT_BUTTON' +}; diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsEditor.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsEditor.js index aef1532dc1..028fa9d3e4 100644 --- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsEditor.js +++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsEditor.js @@ -16,12 +16,13 @@ import {connect} from 'react-redux'; import LicenseKeyGroupsActionHelper from './LicenseKeyGroupsActionHelper.js'; import LicenseKeyGroupsEditorView from './LicenseKeyGroupsEditorView.jsx'; +import LimitEditorActionHelper from '../limits/LimitEditorActionHelper.js'; import ValidationHelper from 'sdc-app/common/helpers/ValidationHelper.js'; const mapStateToProps = ({licenseModel: {licenseKeyGroup}}) => { - let {data, genericFieldInfo, formReady} = licenseKeyGroup.licenseKeyGroupsEditor; + let {data, genericFieldInfo, formReady, limitsList} = licenseKeyGroup.licenseKeyGroupsEditor; let previousData, LKGNames = {}; const licenseKeyGroupId = data ? data.id : null; @@ -33,7 +34,7 @@ const mapStateToProps = ({licenseModel: {licenseKeyGroup}}) => { const list = licenseKeyGroup.licenseKeyGroupsList; for (let i = 0; i < list.length; i++) { - LKGNames[list[i].name] = list[i].id; + LKGNames[list[i].name.toLowerCase()] = list[i].id; } return { @@ -42,7 +43,8 @@ const mapStateToProps = ({licenseModel: {licenseKeyGroup}}) => { genericFieldInfo, isFormValid, formReady, - LKGNames + LKGNames, + limitsList }; }; @@ -50,11 +52,13 @@ const mapActionsToProps = (dispatch, {licenseModelId, version}) => { return { onDataChanged: (deltaData, formName, customValidations) => ValidationHelper.dataChanged(dispatch, {deltaData, formName, customValidations}), onCancel: () => LicenseKeyGroupsActionHelper.closeLicenseKeyGroupEditor(dispatch), - onSubmit: ({previousLicenseKeyGroup, licenseKeyGroup}) => { - LicenseKeyGroupsActionHelper.closeLicenseKeyGroupEditor(dispatch); + onSubmit: ({previousLicenseKeyGroup, licenseKeyGroup, keepOpen}) => { + if (!keepOpen) {LicenseKeyGroupsActionHelper.closeLicenseKeyGroupEditor(dispatch);} LicenseKeyGroupsActionHelper.saveLicenseKeyGroup(dispatch, {licenseModelId, previousLicenseKeyGroup, licenseKeyGroup, version}); }, - onValidateForm: (formName) => ValidationHelper.validateForm(dispatch, formName) + onValidateForm: (formName) => ValidationHelper.validateForm(dispatch, formName), + onCloseLimitEditor: () => LimitEditorActionHelper.closeLimitsEditor(dispatch), + onOpenLimitEditor: (limit) => LimitEditorActionHelper.openLimitsEditor(dispatch, {limit}) }; }; diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsEditorReducer.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsEditorReducer.js index 090c971c65..b1a22f3d9a 100644 --- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsEditorReducer.js +++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsEditorReducer.js @@ -14,20 +14,30 @@ * permissions and limitations under the License. */ import {actionTypes, defaultState, LKG_FORM_NAME} from './LicenseKeyGroupsConstants.js'; +import moment from 'moment'; +import {DATE_FORMAT} from 'sdc-app/onboarding/OnboardingConstants.js'; export default (state = {}, action) => { switch (action.type) { case actionTypes.licenseKeyGroupsEditor.OPEN: + let licenseKeyGroupData = {...action.licenseKeyGroup}; + let {startDate, expiryDate} = licenseKeyGroupData; + if (startDate) { + licenseKeyGroupData.startDate = moment(startDate, DATE_FORMAT).format(DATE_FORMAT); + } + if (expiryDate) { + licenseKeyGroupData.expiryDate = moment(expiryDate, DATE_FORMAT).format(DATE_FORMAT); + } return { ...state, - data: action.licenseKeyGroup ? {...action.licenseKeyGroup} : defaultState.licenseKeyGroupsEditor, + data: action.licenseKeyGroup ? licenseKeyGroupData : defaultState.licenseKeyGroupsEditor, formReady: null, formName: LKG_FORM_NAME, genericFieldInfo: { 'description' : { isValid: true, errorText: '', - validations: [{type: 'required', data: true}, {type: 'maxLength', data: 1000}] + validations: [{type: 'maxLength', data: 1000}] }, 'name' : { isValid: true, @@ -43,9 +53,39 @@ export default (state = {}, action) => { isValid: true, errorText: '', validations: [] + }, + 'thresholdUnits' : { + isValid: true, + errorText: '', + validations: [] + }, + 'thresholdValue' : { + isValid: true, + errorText: '', + validations: [] + }, + 'increments' : { + isValid: true, + errorText: '', + validations: [{type: 'maxLength', data: 120}] + }, + 'startDate': { + isValid: true, + errorText: '', + validations: [] + }, + 'expiryDate': { + isValid: true, + errorText: '', + validations: [] } } }; + case actionTypes.licenseKeyGroupsEditor.LIMITS_LIST_LOADED: + return { + ...state, + limitsList: action.response.results + }; case actionTypes.licenseKeyGroupsEditor.CLOSE: return {}; default: diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsEditorView.jsx b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsEditorView.jsx index b95efd0f9c..647e205cb5 100644 --- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsEditorView.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsEditorView.jsx @@ -17,27 +17,43 @@ import React from 'react'; import i18n from 'nfvo-utils/i18n/i18n.js'; import Validator from 'nfvo-utils/Validator.js'; +import Tabs from 'sdc-ui/lib/react/Tabs.js'; +import Tab from 'sdc-ui/lib/react/Tab.js'; + +import Button from 'sdc-ui/lib/react/Button.js'; import Form from 'nfvo-components/input/validation/Form.jsx'; import Input from 'nfvo-components/input/validation/Input.jsx'; import GridSection from 'nfvo-components/grid/GridSection.jsx'; import GridItem from 'nfvo-components/grid/GridItem.jsx'; -import {optionsInputValues as licenseKeyGroupOptionsInputValues, LKG_FORM_NAME} from './LicenseKeyGroupsConstants.js'; +import {optionsInputValues as licenseKeyGroupOptionsInputValues, LKG_FORM_NAME, tabIds} from './LicenseKeyGroupsConstants.js'; +import {optionsInputValues as LicenseModelOptionsInputValues} from '../LicenseModelConstants.js'; +import {validateStartDate, thresholdValueValidation} from '../LicenseModelValidations.js'; import {other as optionInputOther} from 'nfvo-components/input/validation/InputOptions.jsx'; import InputOptions from 'nfvo-components/input/validation/InputOptions.jsx'; -const LicenseKeyGroupPropType = React.PropTypes.shape({ +import {DATE_FORMAT} from 'sdc-app/onboarding/OnboardingConstants.js'; + +import LicenseKeyGroupsLimits from './LicenseKeyGroupsLimits.js'; +import {limitType, NEW_LIMIT_TEMP_ID} from '../limits/LimitEditorConstants.js'; + + const LicenseKeyGroupPropType = React.PropTypes.shape({ id: React.PropTypes.string, name: React.PropTypes.string, description: React.PropTypes.string, + increments: React.PropTypes.string, operationalScope: React.PropTypes.shape({ choices: React.PropTypes.array, other: React.PropTypes.string }), - type: React.PropTypes.string + type: React.PropTypes.string, + thresholdUnits: React.PropTypes.string, + thresholdValue: React.PropTypes.number, + startDate: React.PropTypes.string, + expiryDate: React.PropTypes.string }); -const LicenseKeyGroupFormContent = ({data, onDataChanged, genericFieldInfo, validateName, validateOperationalScope}) => { - let {name, description, operationalScope, type} = data; +const LicenseKeyGroupFormContent = ({data, onDataChanged, genericFieldInfo, validateName, validateStartDate, thresholdValueValidation}) => { + let {name, description, increments, operationalScope, type, thresholdUnits, thresholdValue, startDate, expiryDate} = data; return ( <GridSection> <GridItem colSpan={2}> @@ -55,11 +71,10 @@ const LicenseKeyGroupFormContent = ({data, onDataChanged, genericFieldInfo, vali <InputOptions onInputChange={()=>{}} isMultiSelect={true} - isRequired={true} onEnumChange={operationalScope => onDataChanged({operationalScope:{choices: operationalScope, other: ''}}, - LKG_FORM_NAME, {operationalScope: validateOperationalScope})} + LKG_FORM_NAME)} onOtherChange={operationalScope => onDataChanged({operationalScope:{choices: [optionInputOther.OTHER], - other: operationalScope}}, LKG_FORM_NAME, {operationalScope: validateOperationalScope})} + other: operationalScope}}, LKG_FORM_NAME)} label={i18n('Operational Scope')} data-test-id='create-lkg-operational-scope' type='select' @@ -77,7 +92,6 @@ const LicenseKeyGroupFormContent = ({data, onDataChanged, genericFieldInfo, vali value={description} isValid={genericFieldInfo.description.isValid} errorText={genericFieldInfo.description.errorText} - isRequired={true} type='textarea' overlayPos='bottom' /> </GridItem> @@ -101,6 +115,82 @@ const LicenseKeyGroupFormContent = ({data, onDataChanged, genericFieldInfo, vali } </Input> </GridItem> + <GridItem> + <Input + onChange={e => { + // setting the unit to the correct value + const selectedIndex = e.target.selectedIndex; + const val = e.target.options[selectedIndex].value; + onDataChanged({thresholdUnits: val}, LKG_FORM_NAME); + // TODO make sure that the value is valid too + onDataChanged({thresholdValue: thresholdValue}, LKG_FORM_NAME,{thresholdValue : thresholdValueValidation});} + + } + value={thresholdUnits} + label={i18n('Threshold Units')} + data-test-id='create-ep-threshold-units' + isValid={genericFieldInfo.thresholdUnits.isValid} + errorText={genericFieldInfo.thresholdUnits.errorText} + groupClassName='bootstrap-input-options' + className='input-options-select' + type='select' > + {LicenseModelOptionsInputValues.THRESHOLD_UNITS.map(mtype => + <option key={mtype.enum} value={mtype.enum}>{`${mtype.title}`}</option>)} + </Input> + </GridItem> + <GridItem> + <Input + className='entitlement-pools-form-row-threshold-value' + onChange={thresholdValue => onDataChanged({thresholdValue}, LKG_FORM_NAME, + {thresholdValue : thresholdValueValidation})} + label={i18n('Threshold Value')} + isValid={genericFieldInfo.thresholdValue.isValid} + errorText={genericFieldInfo.thresholdValue.errorText} + data-test-id='create-ep-threshold-value' + value={thresholdValue} + type='text'/> + </GridItem> + <GridItem> + <Input + type='date' + label={i18n('Start Date')} + value={startDate} + dateFormat={DATE_FORMAT} + startDate={startDate} + endDate={expiryDate} + onChange={startDate => onDataChanged( + {startDate: startDate ? startDate.format(DATE_FORMAT) : ''}, + LKG_FORM_NAME, + {startDate: validateStartDate} + )} + isValid={genericFieldInfo.startDate.isValid} + errorText={genericFieldInfo.startDate.errorText} + selectsStart/> + </GridItem> + <GridItem> + <Input + type='date' + label={i18n('Expiry Date')} + value={expiryDate} + dateFormat={DATE_FORMAT} + startDate={startDate} + endDate={expiryDate} + onChange={expiryDate => { + onDataChanged({expiryDate: expiryDate ? expiryDate.format(DATE_FORMAT) : ''}, LKG_FORM_NAME); + onDataChanged({startDate}, LKG_FORM_NAME, {startDate: validateStartDate}); + }} + isValid={genericFieldInfo.expiryDate.isValid} + errorText={genericFieldInfo.expiryDate.errorText} + selectsEnd/> + </GridItem> + <GridItem colSpan={2}> + <Input + onChange={increments => onDataChanged({increments}, LKG_FORM_NAME)} + label={i18n('Increments')} + value={increments} + data-test-id='create-ep-increments' + type='text'/> + </GridItem> </GridSection> ); }; @@ -120,36 +210,100 @@ class LicenseKeyGroupsEditorView extends React.Component { data: {} }; + componentDidUpdate(prevProps) { + if (this.props.formReady && this.props.formReady !== prevProps.formReady) { // if form validation succeeded -> continue with submit + this.submit(); + } + } + + state = { + localFeatureGroupsListFilter: '', + selectedTab: tabIds.GENERAL, + selectedLimit: '' + }; + render() { - let {data = {}, onDataChanged, isReadOnlyMode, genericFieldInfo} = this.props; + let {data = {}, onDataChanged, isReadOnlyMode, onCloseLimitEditor, genericFieldInfo, limitsList = []} = this.props; + let {selectedTab} = this.state; + const isTabsDisabled = !data.id || !this.props.isFormValid; return ( - <div> - { genericFieldInfo && - <Form - ref='validationForm' - hasButtons={true} - onSubmit={ () => this.submit() } - onReset={ () => this.props.onCancel() } - isValid={this.props.isFormValid} - formReady={this.props.formReady} - onValidateForm={() => this.props.onValidateForm(LKG_FORM_NAME) } - labledButtons={true} - isReadOnlyMode={isReadOnlyMode} - className='license-key-groups-form'> - <LicenseKeyGroupFormContent - data={data} - onDataChanged={onDataChanged} - genericFieldInfo={genericFieldInfo} - validateName={(value)=> this.validateName(value)} - validateOperationalScope={this.validateOperationalScope}/> - </Form>} + <div className='license-keygroup-editor'> + <Tabs + type='menu' + activeTab={selectedTab} + onTabClick={(tabIndex)=>{ + if (tabIndex === tabIds.ADD_LIMIT_BUTTON) { + this.onAddLimit(); + } else { + this.setState({selectedTab: tabIndex}); + onCloseLimitEditor(); + this.setState({selectedLimit: ''}); + } + }} + invalidTabs={[]}> + <Tab tabId={tabIds.GENERAL} data-test-id='general-tab' title={i18n('General')}> + { genericFieldInfo && + <Form + ref='validationForm' + hasButtons={false} + isValid={this.props.isFormValid} + formReady={this.props.formReady} + onValidateForm={() => this.props.onValidateForm(LKG_FORM_NAME) } + labledButtons={true} + isReadOnlyMode={isReadOnlyMode} + className='license-model-form license-key-groups-form'> + <LicenseKeyGroupFormContent + data={data} + onDataChanged={onDataChanged} + genericFieldInfo={genericFieldInfo} + validateName={(value)=> this.validateName(value)} + validateStartDate={(value, state)=> validateStartDate(value, state)} + thresholdValueValidation={(value, state) => thresholdValueValidation(value, state)}/> + </Form>} + + </Tab> + <Tab tabId={tabIds.SP_LIMITS} disabled={isTabsDisabled} data-test-id='general-tab' title={i18n('SP Limits')}> + {selectedTab === tabIds.SP_LIMITS && + <LicenseKeyGroupsLimits + limitType={limitType.SERVICE_PROVIDER} + limitsList={limitsList.filter(item => item.type === limitType.SERVICE_PROVIDER)} + selectedLimit={this.state.selectedLimit} + onCloseLimitEditor={() => this.onCloseLimitEditor()} + onSelectLimit={limit => this.onSelectLimit(limit)}/>} + </Tab> + <Tab tabId={tabIds.VENDOR_LIMITS} disabled={isTabsDisabled} data-test-id='general-tab' title={i18n('Vendor Limits')}> + {selectedTab === tabIds.VENDOR_LIMITS && + <LicenseKeyGroupsLimits + limitType={limitType.VENDOR} + limitsList={limitsList.filter(item => item.type === limitType.VENDOR)} + selectedLimit={this.state.selectedLimit} + onCloseLimitEditor={() => this.onCloseLimitEditor()} + onSelectLimit={limit => this.onSelectLimit(limit)}/>} + </Tab> + {selectedTab !== tabIds.GENERAL ? + <Button disabled={this.state.selectedLimit} className='add-limit-button' tabId={tabIds.ADD_LIMIT_BUTTON} btnType='link' iconName='plus'>{i18n('Add Limit')}</Button> : + <div></div> // Render empty div to not break tabs + } + </Tabs> + + <GridSection className='license-model-modal-buttons license-key-group-editor-buttons'> + {!this.state.selectedLimit && <Button btnType='default' disabled={!this.props.isFormValid} onClick={() => this.submit()} type='reset'>{i18n('Save')}</Button>} + <Button btnType={this.state.selectedLimit ? 'default' : 'outline'} onClick={() => this.props.onCancel()} type='reset'> + {i18n('Cancel')} + </Button> + </GridSection> </div> + ); } submit() { - const {data: licenseKeyGroup, previousData: previousLicenseKeyGroup} = this.props; - this.props.onSubmit({licenseKeyGroup, previousLicenseKeyGroup}); + const {data: licenseKeyGroup, previousData: previousLicenseKeyGroup, formReady, onValidateForm, onSubmit} = this.props; + if (!formReady) { + onValidateForm(LKG_FORM_NAME); + } else { + onSubmit({licenseKeyGroup, previousLicenseKeyGroup}); + } } validateName(value) { @@ -160,27 +314,23 @@ class LicenseKeyGroupsEditorView extends React.Component { {isValid: false, errorText: i18n('License key group by the name \'' + value + '\' already exists. License key group name must be unique')}; } - validateOperationalScope(value) { - if (value && value.choices && value.choices.length > 0) { - if (value.choices[0] !== optionInputOther.OTHER) - { - return { - isValid: true, - errorText: '' - }; - } else { - if ( value.other ) { - return { - isValid: true, - errorText: '' - }; - } - } + onSelectLimit(limit) { + if (limit.id === this.state.selectedLimit) { + this.setState({selectedLimit: ''}); + return; } - return { - isValid: false, - errorText: 'Field is required' - }; + this.setState({selectedLimit: limit.id}); + this.props.onOpenLimitEditor(limit); + } + + onCloseLimitEditor() { + this.setState({selectedLimit: ''}); + this.props.onCloseLimitEditor(); + } + + onAddLimit() { + this.setState({selectedLimit: NEW_LIMIT_TEMP_ID}); + this.props.onOpenLimitEditor(); } } diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsLimits.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsLimits.js new file mode 100644 index 0000000000..7745a12fec --- /dev/null +++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsLimits.js @@ -0,0 +1,57 @@ +/*! + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ +import {connect} from 'react-redux'; +import i18n from 'nfvo-utils/i18n/i18n.js'; +import {actionTypes as globalModalActionTypes} from 'nfvo-components/modal/GlobalModalConstants.js'; +import ValidationHelper from 'sdc-app/common/helpers/ValidationHelper.js'; +import Limits from 'sdc-app/onboarding/licenseModel/limits/Limits.jsx'; + +import LicenseKeyGroupsActionHelper from './LicenseKeyGroupsActionHelper.js'; + +const mapStateToProps = ({licenseModel: {licenseKeyGroup: {licenseKeyGroupsEditor: {data}}, limitEditor}, currentScreen}) => { + let {props: {licenseModelId, version}} = currentScreen; + return { + parent: data, + limitEditor, + licenseModelId, + version + }; +}; + +const mapActionsToProps = (dispatch) => { + return { + onDataChanged: (deltaData, formName, customValidations) => ValidationHelper.dataChanged(dispatch, {deltaData, formName, customValidations}), + onSubmit: (limit, licenseKeyGroup, licenseModelId, version) => LicenseKeyGroupsActionHelper.submitLimit(dispatch, + { + limit, + licenseKeyGroup, + licenseModelId, + version}), + onDelete: ({limit, parent, licenseModelId, version, onCloseLimitEditor, selectedLimit}) => dispatch({ + type: globalModalActionTypes.GLOBAL_MODAL_WARNING, + data:{ + msg: i18n(`Are you sure you want to delete ${limit.name}?`), + confirmationButtonText: i18n('Delete'), + title: i18n('Warning'), + onConfirmed: ()=> LicenseKeyGroupsActionHelper.deleteLimit(dispatch, {limit, licenseKeyGroup: parent, licenseModelId, version}).then(() => + selectedLimit === limit.id && onCloseLimitEditor() + ) + } + }) + }; +}; + +export default connect(mapStateToProps, mapActionsToProps)(Limits);
\ No newline at end of file diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsListEditor.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsListEditor.js index e2c6c30e21..a8cf1eb0a1 100644 --- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsListEditor.js +++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsListEditor.js @@ -38,7 +38,7 @@ const mapStateToProps = ({licenseModel: {licenseKeyGroup, licenseModelEditor}}) const mapActionsToProps = (dispatch, {licenseModelId, version}) => { return { onAddLicenseKeyGroupClick: () => LicenseKeyGroupsActionHelper.openLicenseKeyGroupsEditor(dispatch), - onEditLicenseKeyGroupClick: licenseKeyGroup => LicenseKeyGroupsActionHelper.openLicenseKeyGroupsEditor(dispatch, {licenseKeyGroup}), + onEditLicenseKeyGroupClick: licenseKeyGroup => LicenseKeyGroupsActionHelper.openLicenseKeyGroupsEditor(dispatch, {licenseKeyGroup, licenseModelId, version}), onDeleteLicenseKeyGroupClick: licenseKeyGroup => dispatch({ type: globalMoadlActions.GLOBAL_MODAL_WARNING, data:{ diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsListEditorView.jsx b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsListEditorView.jsx index b8ccd68bce..1a7f2b0b5b 100644 --- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsListEditorView.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsListEditorView.jsx @@ -21,7 +21,7 @@ import ListEditorView from 'nfvo-components/listEditor/ListEditorView.jsx'; import ListEditorItemView from 'nfvo-components/listEditor/ListEditorItemView.jsx'; import LicenseKeyGroupsEditor from './LicenseKeyGroupsEditor.js'; -import InputOptions, {other as optionInputOther} from 'nfvo-components/input/inputOptions/InputOptions.jsx'; +import InputOptions, {other as optionInputOther} from 'nfvo-components/input/validation/InputOptions.jsx'; import {optionsInputValues} from './LicenseKeyGroupsConstants'; class LicenseKeyGroupsListEditorView extends React.Component { @@ -61,7 +61,7 @@ class LicenseKeyGroupsListEditorView extends React.Component { isReadOnlyMode={isReadOnlyMode}> {this.filterList().map(licenseKeyGroup => (this.renderLicenseKeyGroupListItem(licenseKeyGroup, isReadOnlyMode)))} </ListEditorView> - <Modal show={isDisplayModal} bsSize='large' animation={true} className='onborading-modal license-key-groups-modal'> + <Modal show={isDisplayModal} bsSize='large' animation={true} className='onborading-modal license-model-modal license-key-groups-modal'> <Modal.Header> <Modal.Title>{`${isModalInEditMode ? i18n('Edit License Key Group') : i18n('Create New License Key Group')}`}</Modal.Title> </Modal.Header> @@ -122,16 +122,20 @@ class LicenseKeyGroupsListEditorView extends React.Component { } getOperationalScopes(operationalScope) { - if(operationalScope.choices.toString() === i18n(optionInputOther.OTHER) && operationalScope.other !== '') { + + if(operationalScope.choices && operationalScope.choices.toString() === i18n(optionInputOther.OTHER)) { return operationalScope.other; } - else { + else if (operationalScope.choices) { let allOpScopes = ''; for (let opScope of operationalScope.choices) { allOpScopes += allOpScopes === '' ? InputOptions.getTitleByName(optionsInputValues, opScope) : `, ${InputOptions.getTitleByName(optionsInputValues, opScope)}`; } return allOpScopes; - } + } + else { + return ''; + } } extractValue(item) { |