diff options
Diffstat (limited to 'openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementEditorView.jsx')
-rw-r--r-- | openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementEditorView.jsx | 326 |
1 files changed, 138 insertions, 188 deletions
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementEditorView.jsx b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementEditorView.jsx index b21f943fed..67a3333a3a 100644 --- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementEditorView.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseAgreement/LicenseAgreementEditorView.jsx @@ -1,17 +1,36 @@ +/*! + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ import React from 'react'; -import ButtonGroup from 'react-bootstrap/lib/ButtonGroup.js'; -import Button from 'react-bootstrap/lib/Button.js'; -import ValidationForm from 'nfvo-components/input/validation/ValidationForm.jsx'; -import ValidationTabs from 'nfvo-components/input/validation/ValidationTabs.jsx'; -import ValidationTab from 'nfvo-components/input/validation/ValidationTab.jsx'; -import ValidationInput from 'nfvo-components/input/validation/ValidationInput.jsx'; + +import GridSection from 'nfvo-components/grid/GridSection.jsx'; +import GridItem from 'nfvo-components/grid/GridItem.jsx'; +import Form from 'nfvo-components/input/validation/Form.jsx'; +import Tabs from 'nfvo-components/input/validation/Tabs.jsx'; +import Tab from 'react-bootstrap/lib/Tab.js'; +import Input from 'nfvo-components/input/validation/Input.jsx'; import DualListboxView from 'nfvo-components/input/dualListbox/DualListboxView.jsx'; -import ListEditorView from 'nfvo-components/listEditor/ListEditorView.jsx'; -import ListEditorViewItem from 'nfvo-components/listEditor/ListEditorItemView.jsx'; import i18n from 'nfvo-utils/i18n/i18n.js'; +import Validator from 'nfvo-utils/Validator.js'; -import {enums as LicenseAgreementEnums, optionsInputValues as LicenseAgreementOptionsInputValues} from './LicenseAgreementConstants.js'; +import {enums as LicenseAgreementEnums, optionsInputValues as LicenseAgreementOptionsInputValues, LA_EDITOR_FORM} from './LicenseAgreementConstants.js'; +const dualBoxFilterTitle = { + left: i18n('Available Feature Groups'), + right: i18n('Selected Feature Groups') +}; const LicenseAgreementPropType = React.PropTypes.shape({ id: React.PropTypes.string, @@ -19,14 +38,77 @@ const LicenseAgreementPropType = React.PropTypes.shape({ description: React.PropTypes.string, requirementsAndConstrains: React.PropTypes.string, licenseTerm: React.PropTypes.object, - featureGroupsIds: React.PropTypes.arrayOf(React.PropTypes.string) + featureGroupsIds: React.PropTypes.arrayOf(React.PropTypes.string), + version: React.PropTypes.object }); + +const GeneralTabContent = ({data, genericFieldInfo, onDataChanged, validateName, validateLTChoice}) => { + let {name, description, requirementsAndConstrains, licenseTerm} = data; + return ( + <GridSection> + <GridItem colSpan={2}> + <Input + isValid={genericFieldInfo.name.isValid} + errorText={genericFieldInfo.name.errorText} + onChange={name => onDataChanged({name}, LA_EDITOR_FORM, { name: validateName })} + label={i18n('Name')} + value={name} + data-test-id='create-la-name' + name='license-agreement-name' + isRequired={true} + type='text'/> + <Input + isValid={genericFieldInfo.requirementsAndConstrains.isValid} + errorText={genericFieldInfo.requirementsAndConstrains.errorText} + onChange={requirementsAndConstrains => onDataChanged({requirementsAndConstrains}, LA_EDITOR_FORM)} + label={i18n('Requirements and Constraints')} + value={requirementsAndConstrains} + data-test-id='create-la-requirements-constants' + name='license-agreement-requirements-and-constraints' + type='textarea'/> + <Input + label={i18n('License Term')} + type='select' + value={licenseTerm && licenseTerm.choice} + isRequired={true} + onChange={e => { + const selectedIndex = e.target.selectedIndex; + const licenseTerm = e.target.options[selectedIndex].value; + onDataChanged({licenseTerm:{choice: licenseTerm, other: ''}}, LA_EDITOR_FORM, { licenseTerm: validateLTChoice }); + }} + isValid={genericFieldInfo.licenseTerm.isValid} + errorText={genericFieldInfo.licenseTerm.errorText} + className='input-options-select' + groupClassName='bootstrap-input-options' + data-test-id='create-la-license-term' > + {LicenseAgreementOptionsInputValues.LICENSE_MODEL_TYPE.map(mtype => + <option key={mtype.enum} value={mtype.enum}>{`${mtype.title}`}</option>)} + </Input> + </GridItem> + <GridItem colSpan={2} stretch> + <Input + isValid={genericFieldInfo.description.isValid} + errorText={genericFieldInfo.description.errorText} + onChange={description => onDataChanged({description}, LA_EDITOR_FORM)} + label={i18n('Description')} + value={description} + overlayPos='bottom' + data-test-id='create-la-description' + name='license-agreement-description' + isRequired={true} + type='textarea'/> + </GridItem> + </GridSection> + ); +}; + class LicenseAgreementEditorView extends React.Component { static propTypes = { data: LicenseAgreementPropType, previousData: LicenseAgreementPropType, + LANames: React.PropTypes.object, isReadOnlyMode: React.PropTypes.bool, onDataChanged: React.PropTypes.func.isRequired, onSubmit: React.PropTypes.func.isRequired, @@ -42,7 +124,6 @@ class LicenseAgreementEditorView extends React.Component { static defaultProps = { selectedTab: LicenseAgreementEnums.SELECTED_LICENSE_AGREEMENT_TAB.GENERAL, - selectedFeatureGroupsButtonTab: LicenseAgreementEnums.SELECTED_FEATURE_GROUPS_BUTTONTAB.AVAILABLE_FEATURE_GROUPS, data: {} }; @@ -51,21 +132,44 @@ class LicenseAgreementEditorView extends React.Component { }; render() { - let {selectedTab, onTabSelect, isReadOnlyMode} = this.props; + let {selectedTab, onTabSelect, isReadOnlyMode, featureGroupsList, data, onDataChanged, genericFieldInfo} = this.props; return ( - <ValidationForm - ref='validationForm' - hasButtons={true} - onSubmit={ () => this.submit() } - onReset={ () => this.props.onCancel() } - labledButtons={true} - isReadOnlyMode={isReadOnlyMode} - className='license-agreement-form'> - <ValidationTabs activeKey={onTabSelect ? selectedTab : undefined} onSelect={onTabSelect}> - {this.renderGeneralTab()} - {this.renderFeatureGroupsTab()} - </ValidationTabs> - </ValidationForm> + <div> + {genericFieldInfo && <Form + ref='validationForm' + hasButtons={true} + onSubmit={ () => this.submit() } + onReset={ () => this.props.onCancel() } + labledButtons={true} + isReadOnlyMode={isReadOnlyMode} + isValid={this.props.isFormValid} + formReady={this.props.formReady} + onValidateForm={() => this.props.onValidateForm(LA_EDITOR_FORM) } + className='license-agreement-form'> + <Tabs activeKey={onTabSelect ? selectedTab : undefined} onSelect={onTabSelect} invalidTabs={this.props.invalidTabs} > + <Tab + eventKey={LicenseAgreementEnums.SELECTED_LICENSE_AGREEMENT_TAB.GENERAL} + data-test-id='general-tab' + title={i18n('General')}> + <GeneralTabContent data={data} genericFieldInfo={genericFieldInfo} onDataChanged={onDataChanged} validateLTChoice={(value)=>this.validateLTChoice(value)} + validateName={(value)=>this.validateName(value)}/> + </Tab> + <Tab + eventKey={LicenseAgreementEnums.SELECTED_LICENSE_AGREEMENT_TAB.FEATURE_GROUPS} + data-test-id='feature-group-tab' + title={i18n('Feature Groups')}> + {featureGroupsList.length > 0 ? + <DualListboxView + isReadOnlyMode={isReadOnlyMode} + filterTitle={dualBoxFilterTitle} + selectedValuesList={data.featureGroupsIds} + availableList={featureGroupsList} + onChange={ selectedValuesList => onDataChanged( { featureGroupsIds: selectedValuesList }, LA_EDITOR_FORM )}/> : + <p>{i18n('There is no available feature groups')}</p>} + </Tab> + </Tabs> + </Form>} + </div> ); } @@ -74,173 +178,19 @@ class LicenseAgreementEditorView extends React.Component { this.props.onSubmit({licenseAgreement, previousLicenseAgreement}); } - renderGeneralTab() { - let {data = {}, onDataChanged} = this.props; - let {name, description, requirementsAndConstrains, licenseTerm} = data; - return ( - <ValidationTab - eventKey={LicenseAgreementEnums.SELECTED_LICENSE_AGREEMENT_TAB.GENERAL} - title={i18n('General')}> - <div className='license-agreement-form-row'> - <div className='license-agreement-form-col'> - <ValidationInput - onChange={name => onDataChanged({name})} - label={i18n('Name')} - value={name} - name='license-agreement-name' - validations={{maxLength: 25, required: true}} - type='text'/> - <ValidationInput - onChange={requirementsAndConstrains => onDataChanged({requirementsAndConstrains})} - label={i18n('Requirements and Constraints')} - value={requirementsAndConstrains} - name='license-agreement-requirements-and-constraints' - validations={{maxLength: 1000}} - type='textarea'/> - </div> - <ValidationInput - onChange={description => onDataChanged({description})} - label={i18n('Description')} - value={description} - name='license-agreement-description' - validations={{maxLength: 1000, required: true}} - type='textarea'/> - </div> - <div className='license-agreement-form-row'> - <ValidationInput - onEnumChange={licenseTerm => onDataChanged({licenseTerm:{choice: licenseTerm, other: ''}})} - selectedEnum={licenseTerm && licenseTerm.choice} - validations={{required: true}} - type='select' - label={i18n('License Term')} - values={LicenseAgreementOptionsInputValues.LICENSE_MODEL_TYPE}/> - </div> - </ValidationTab> - ); - } - - renderFeatureGroupsTab() { - let {onFeatureGroupsButtonTabSelect, selectedFeatureGroupsButtonTab, featureGroupsList} = this.props; - if (featureGroupsList.length > 0) { - return ( - <ValidationTab - eventKey={LicenseAgreementEnums.SELECTED_LICENSE_AGREEMENT_TAB.FEATURE_GROUPS} - title={i18n('Feature Groups')}> - <ButtonGroup> - { - this.renderFeatureGroupsButtonTab( - LicenseAgreementEnums.SELECTED_FEATURE_GROUPS_BUTTONTAB.ASSOCIATED_FEATURE_GROUPS, - selectedFeatureGroupsButtonTab, - i18n('Associated Feature Groups'), - onFeatureGroupsButtonTabSelect - ) - } - { - this.renderFeatureGroupsButtonTab( - LicenseAgreementEnums.SELECTED_FEATURE_GROUPS_BUTTONTAB.AVAILABLE_FEATURE_GROUPS, - selectedFeatureGroupsButtonTab, - i18n('Available Feature Groups'), - onFeatureGroupsButtonTabSelect - ) - } - </ButtonGroup> - {this.renderFeatureGroupsButtonTabContent(selectedFeatureGroupsButtonTab)} - </ValidationTab> - ); - } else { - return ( - <ValidationTab - eventKey={LicenseAgreementEnums.SELECTED_LICENSE_AGREEMENT_TAB.FEATURE_GROUPS} - title={i18n('Feature Groups')}> - <p>{i18n('There is no available feature groups')}</p> - </ValidationTab> - ); + validateLTChoice(value) { + if (!value.choice) { + return {isValid: false, errorText: i18n('Field is required')}; } + return {isValid: true, errorText: ''}; } - renderFeatureGroupsButtonTabContent(selectedFeatureGroupsButtonTab) { - const {featureGroupsList = [], data: {featureGroupsIds = []}} = this.props; - const {localFeatureGroupsListFilter} = this.state; - let selectedFeatureGroups = featureGroupsIds.map(featureGroupId => featureGroupsList.find(featureGroup => featureGroup.id === featureGroupId)); - - const dualBoxFilterTitle = { - left: i18n('Available Feature Groups'), - right: i18n('Selected Feature Groups') - }; - - switch (selectedFeatureGroupsButtonTab) { - case LicenseAgreementEnums.SELECTED_FEATURE_GROUPS_BUTTONTAB.ASSOCIATED_FEATURE_GROUPS: - if (!selectedFeatureGroups.length) { - return ( - <div className='no-items-msg'> - {i18n('There are currently no feature groups associated with this license agreement. Click "Available Feature Groups" to associate.')} - </div> - ); - } - if (featureGroupsList.length) { - return ( - <ListEditorView - className='thinner-list' - filterValue={localFeatureGroupsListFilter} - onFilter={localFeatureGroupsListFilter => this.setState({localFeatureGroupsListFilter})}> - {this.filterAssociatedFeatureGroupsList(selectedFeatureGroups).map(featureGroup => this.renderAssociatedFeatureGroupListItem(featureGroup))} - </ListEditorView> - ); - } - return; - case LicenseAgreementEnums.SELECTED_FEATURE_GROUPS_BUTTONTAB.AVAILABLE_FEATURE_GROUPS: - return ( - <DualListboxView - filterTitle={dualBoxFilterTitle} - selectedValuesList={this.props.data.featureGroupsIds} - availableList={this.props.featureGroupsList} - onChange={ selectedValuesList => this.props.onDataChanged( { featureGroupsIds: selectedValuesList } )}/> - ); - } - } + validateName(value) { + const {data: {id}, LANames} = this.props; + const isExists = Validator.isItemNameAlreadyExistsInList({itemId: id, itemName: value, list: LANames}); - renderFeatureGroupsButtonTab(buttonTab, selectedButtonTab, title, onClick) { - const isSelected = buttonTab === selectedButtonTab; - return ( - <Button - className='button-tab' - active={isSelected} - onClick={() => !isSelected && onClick(buttonTab)}> - { title } - </Button> - ); - } - - renderAssociatedFeatureGroupListItem({id, name, entitlementPoolsIds = [], licenseKeyGroupsIds = []}) { - const {onDataChanged, data: {featureGroupsIds}, isReadOnlyMode} = this.props; - return ( - <ListEditorViewItem - key={id} - onDelete={() => onDataChanged({featureGroupsIds: featureGroupsIds.filter(featureGroupId => featureGroupId !== id)})} - isReadOnlyMode={isReadOnlyMode}> - <div className='name'>{name}</div> - <div className='inner-objects-count'>{ - i18n( - 'Entitlement Pools({entitlementPoolsCounter}), License Key Groups({licenseKeyGroupsCount})', - { - entitlementPoolsCounter: entitlementPoolsIds.length, - licenseKeyGroupsCount: licenseKeyGroupsIds.length - } - ) - }</div> - </ListEditorViewItem> - ); - } - - filterAssociatedFeatureGroupsList(featureGroupsList) { - let {localFeatureGroupsListFilter} = this.state; - if (localFeatureGroupsListFilter) { - const filter = new RegExp(escape(localFeatureGroupsListFilter), 'i'); - return featureGroupsList.filter(({name}) => name.match(filter)); - } - else { - return featureGroupsList; - } + return !isExists ? {isValid: true, errorText: ''} : + {isValid: false, errorText: i18n('License Agreement by the name \'' + value + '\' already exists. License agreement name must be unique')}; } } |