diff options
author | Einav Weiss Keidar <einavw@amdocs.com> | 2018-03-20 14:45:40 +0200 |
---|---|---|
committer | Avi Gaffa <avi.gaffa@amdocs.com> | 2018-03-20 13:52:31 +0000 |
commit | 7fdf733a64670fceefc3ded35cfa581e1c458179 (patch) | |
tree | b3623ac9a331473830cb0167c0b487f2a176427c /openecomp-ui/src/sdc-app/onboarding/softwareProduct/details | |
parent | c7916a4e5955ccc5f0f5252307363b791ec5c7b9 (diff) |
Adding Prettier and fixing up eslint version
Issue-ID: SDC-1094
Change-Id: Ie83ad95a03899345dd90235daf0323cbe3bc6afd
Signed-off-by: Einav Weiss Keidar <einavw@amdocs.com>
Diffstat (limited to 'openecomp-ui/src/sdc-app/onboarding/softwareProduct/details')
4 files changed, 850 insertions, 548 deletions
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/details/SoftwareProductDetails.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/details/SoftwareProductDetails.js index 0973537d43..8a3279a02c 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/details/SoftwareProductDetails.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/details/SoftwareProductDetails.js @@ -13,80 +13,140 @@ * or implied. See the License for the specific language governing * permissions and limitations under the License. */ -import {connect} from 'react-redux'; +import { connect } from 'react-redux'; import i18n from 'nfvo-utils/i18n/i18n.js'; import SoftwareProductActionHelper from 'sdc-app/onboarding/softwareProduct/SoftwareProductActionHelper.js'; import SoftwareProductDetailsView from './SoftwareProductDetailsView.jsx'; import ValidationHelper from 'sdc-app/common/helpers/ValidationHelper.js'; -import {PRODUCT_QUESTIONNAIRE} from 'sdc-app/onboarding/softwareProduct/SoftwareProductConstants.js'; -import {actionTypes as modalActionTypes, modalSizes} from 'nfvo-components/modal/GlobalModalConstants.js'; -import {modalContentMapper} from 'sdc-app/common/modal/ModalContentMapper.js'; -import {forms} from 'sdc-app/onboarding/softwareProduct/SoftwareProductConstants.js'; +import { PRODUCT_QUESTIONNAIRE } from 'sdc-app/onboarding/softwareProduct/SoftwareProductConstants.js'; +import { + actionTypes as modalActionTypes, + modalSizes +} from 'nfvo-components/modal/GlobalModalConstants.js'; +import { modalContentMapper } from 'sdc-app/common/modal/ModalContentMapper.js'; +import { forms } from 'sdc-app/onboarding/softwareProduct/SoftwareProductConstants.js'; export const mapStateToProps = ({ - finalizedLicenseModelList, - archivedLicenseModelList, - softwareProduct, - licenseModel: {licenseAgreement, featureGroup} + finalizedLicenseModelList, + archivedLicenseModelList, + softwareProduct, + licenseModel: { licenseAgreement, featureGroup } }) => { + let { + softwareProductEditor: { + data: currentSoftwareProduct, + licensingVersionsList = [], + genericFieldInfo + }, + softwareProductCategories, + softwareProductQuestionnaire + } = softwareProduct; + let { licensingData = {}, licensingVersion } = currentSoftwareProduct; + let licenseAgreementList = [], + filteredFeatureGroupsList = []; + licenseAgreementList = licensingVersion + ? licenseAgreement.licenseAgreementList + : []; + if (licensingVersion && licensingData && licensingData.licenseAgreement) { + let selectedLicenseAgreement = licenseAgreementList.find( + la => la.id === licensingData.licenseAgreement + ); + if (selectedLicenseAgreement) { + let featureGroupsList = featureGroup.featureGroupsList.filter( + ({ referencingLicenseAgreements }) => + referencingLicenseAgreements.includes( + selectedLicenseAgreement.id + ) + ); + if (featureGroupsList.length) { + filteredFeatureGroupsList = featureGroupsList.map( + featureGroup => ({ + enum: featureGroup.id, + title: featureGroup.name + }) + ); + } + } + } + let { + qdata, + qgenericFieldInfo: qGenericFieldInfo, + dataMap + } = softwareProductQuestionnaire; - let {softwareProductEditor: {data: currentSoftwareProduct, licensingVersionsList = [], genericFieldInfo}, softwareProductCategories, softwareProductQuestionnaire} = softwareProduct; - let {licensingData = {}, licensingVersion} = currentSoftwareProduct; - let licenseAgreementList = [], filteredFeatureGroupsList = []; - licenseAgreementList = licensingVersion ? - licenseAgreement.licenseAgreementList : []; - if(licensingVersion && licensingData && licensingData.licenseAgreement) { - let selectedLicenseAgreement = licenseAgreementList.find(la => la.id === licensingData.licenseAgreement); - if (selectedLicenseAgreement) { - let featureGroupsList = featureGroup.featureGroupsList.filter(({referencingLicenseAgreements}) => referencingLicenseAgreements.includes(selectedLicenseAgreement.id)); - if (featureGroupsList.length) { - filteredFeatureGroupsList = featureGroupsList.map(featureGroup => ({enum: featureGroup.id, title: featureGroup.name})); - } - } - } - let {qdata, qgenericFieldInfo : qGenericFieldInfo, dataMap} = softwareProductQuestionnaire; - - let isFormValid = ValidationHelper.checkFormValid(genericFieldInfo); - const isVendorArchived = archivedLicenseModelList.find(item => item.id === currentSoftwareProduct.vendorId); - return { - currentSoftwareProduct, - softwareProductCategories, - licenseAgreementList, - licensingVersionsList, - featureGroupsList: filteredFeatureGroupsList, - finalizedLicenseModelList, - qdata, - isFormValid, - genericFieldInfo, - qGenericFieldInfo, - dataMap, - isVendorArchived: !!isVendorArchived - }; - + let isFormValid = ValidationHelper.checkFormValid(genericFieldInfo); + const isVendorArchived = archivedLicenseModelList.find( + item => item.id === currentSoftwareProduct.vendorId + ); + return { + currentSoftwareProduct, + softwareProductCategories, + licenseAgreementList, + licensingVersionsList, + featureGroupsList: filteredFeatureGroupsList, + finalizedLicenseModelList, + qdata, + isFormValid, + genericFieldInfo, + qGenericFieldInfo, + dataMap, + isVendorArchived: !!isVendorArchived + }; }; -export const mapActionsToProps = (dispatch, {version}) => { - return { - onDataChanged: (deltaData, formName) => ValidationHelper.dataChanged(dispatch, {deltaData, formName}), - onVendorParamChanged: (deltaData, formName) => SoftwareProductActionHelper.softwareProductEditorVendorChanged(dispatch, {deltaData, formName}), - onQDataChanged: (deltaData) => ValidationHelper.qDataChanged(dispatch, {deltaData, qName: PRODUCT_QUESTIONNAIRE}), - onValidityChanged: isValidityData => SoftwareProductActionHelper.setIsValidityData(dispatch, {isValidityData}), - onSubmit: (softwareProduct, qdata) => SoftwareProductActionHelper.updateSoftwareProduct(dispatch, {softwareProduct, qdata, version}), - onArchivedVendorRemove: ({onVendorParamChanged, finalizedLicenseModelList, vendorName}) => dispatch({ - type: modalActionTypes.GLOBAL_MODAL_SHOW, - data:{ - title: i18n('Change Archived VLM'), - modalComponentName: modalContentMapper.VENDOR_SELECTOR, - modalComponentProps: { - size: modalSizes.MEDIUM, - finalizedLicenseModelList, - vendorName, - onClose: () => dispatch({type: modalActionTypes.GLOBAL_MODAL_CLOSE}), - onConfirm: (vendorId) => onVendorParamChanged({vendorId}, forms.VENDOR_SOFTWARE_PRODUCT_DETAILS) - } - } - }) - }; +export const mapActionsToProps = (dispatch, { version }) => { + return { + onDataChanged: (deltaData, formName) => + ValidationHelper.dataChanged(dispatch, { deltaData, formName }), + onVendorParamChanged: (deltaData, formName) => + SoftwareProductActionHelper.softwareProductEditorVendorChanged( + dispatch, + { deltaData, formName } + ), + onQDataChanged: deltaData => + ValidationHelper.qDataChanged(dispatch, { + deltaData, + qName: PRODUCT_QUESTIONNAIRE + }), + onValidityChanged: isValidityData => + SoftwareProductActionHelper.setIsValidityData(dispatch, { + isValidityData + }), + onSubmit: (softwareProduct, qdata) => + SoftwareProductActionHelper.updateSoftwareProduct(dispatch, { + softwareProduct, + qdata, + version + }), + onArchivedVendorRemove: ({ + onVendorParamChanged, + finalizedLicenseModelList, + vendorName + }) => + dispatch({ + type: modalActionTypes.GLOBAL_MODAL_SHOW, + data: { + title: i18n('Change Archived VLM'), + modalComponentName: modalContentMapper.VENDOR_SELECTOR, + modalComponentProps: { + size: modalSizes.MEDIUM, + finalizedLicenseModelList, + vendorName, + onClose: () => + dispatch({ + type: modalActionTypes.GLOBAL_MODAL_CLOSE + }), + onConfirm: vendorId => + onVendorParamChanged( + { vendorId }, + forms.VENDOR_SOFTWARE_PRODUCT_DETAILS + ) + } + } + }) + }; }; -export default connect(mapStateToProps, mapActionsToProps, null, {withRef: true})(SoftwareProductDetailsView); +export default connect(mapStateToProps, mapActionsToProps, null, { + withRef: true +})(SoftwareProductDetailsView); diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/details/SoftwareProductDetailsReducer.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/details/SoftwareProductDetailsReducer.js index 1a293264c3..1e4a0df787 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/details/SoftwareProductDetailsReducer.js +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/details/SoftwareProductDetailsReducer.js @@ -13,49 +13,56 @@ * or implied. See the License for the specific language governing * permissions and limitations under the License. */ -import {actionTypes, forms} from 'sdc-app/onboarding/softwareProduct/SoftwareProductConstants.js'; +import { + actionTypes, + forms +} from 'sdc-app/onboarding/softwareProduct/SoftwareProductConstants.js'; export default (state = {}, action) => { - switch (action.type) { - case actionTypes.softwareProductEditor.IS_VALIDITY_DATA_CHANGED: - return { - ...state, - isValidityData: action.isValidityData - }; - case actionTypes.SOFTWARE_PRODUCT_LOADED: - return { - ...state, - formName: forms.VENDOR_SOFTWARE_PRODUCT_DETAILS, - genericFieldInfo: { - 'name' : { - isValid: true, - errorText: '', - validations: [{type: 'validateName', data: true}, {type: 'maxLength', data: 25}, {type: 'required', data: true}] - }, - 'description' : { - isValid: true, - errorText: '', - validations: [{type: 'required', data: true}] - } - }, - data: action.response - }; - case actionTypes.TOGGLE_NAVIGATION_ITEM: - return { - ...state, - mapOfExpandedIds: action.mapOfExpandedIds - }; - case actionTypes.LOAD_LICENSING_VERSIONS_LIST: - return { - ...state, - licensingVersionsList: action.licensingVersionsList - }; - case actionTypes.CANDIDATE_IN_PROCESS: - return { - ...state, - data: {...state.data, candidateOnboardingOrigin: true} - }; - default: - return state; - } + switch (action.type) { + case actionTypes.softwareProductEditor.IS_VALIDITY_DATA_CHANGED: + return { + ...state, + isValidityData: action.isValidityData + }; + case actionTypes.SOFTWARE_PRODUCT_LOADED: + return { + ...state, + formName: forms.VENDOR_SOFTWARE_PRODUCT_DETAILS, + genericFieldInfo: { + name: { + isValid: true, + errorText: '', + validations: [ + { type: 'validateName', data: true }, + { type: 'maxLength', data: 25 }, + { type: 'required', data: true } + ] + }, + description: { + isValid: true, + errorText: '', + validations: [{ type: 'required', data: true }] + } + }, + data: action.response + }; + case actionTypes.TOGGLE_NAVIGATION_ITEM: + return { + ...state, + mapOfExpandedIds: action.mapOfExpandedIds + }; + case actionTypes.LOAD_LICENSING_VERSIONS_LIST: + return { + ...state, + licensingVersionsList: action.licensingVersionsList + }; + case actionTypes.CANDIDATE_IN_PROCESS: + return { + ...state, + data: { ...state.data, candidateOnboardingOrigin: true } + }; + default: + return state; + } }; diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/details/SoftwareProductDetailsVendorSelector.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/details/SoftwareProductDetailsVendorSelector.jsx index c2a3e0bd02..9c20723689 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/details/SoftwareProductDetailsVendorSelector.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/details/SoftwareProductDetailsVendorSelector.jsx @@ -22,57 +22,77 @@ import Input from 'nfvo-components/input/validation/Input.jsx'; import sortByStringProperty from 'nfvo-utils/sortByStringProperty.js'; class VendorSelector extends React.Component { - static propTypes = { - finalizedLicenseModelList: PropTypes.array, - vendorName: PropTypes.string, - onClose: PropTypes.func.isRequired, - onConfirm: PropTypes.func.isRequired - } - constructor(props){ - super(props); - const selectedValue = props.finalizedLicenseModelList.length ? props.finalizedLicenseModelList[0].id : ''; - this.state = { - selectedValue - }; - } - submit() { - const vendor = this.props.finalizedLicenseModelList.find(item => item.id === this.state.selectedValue); - this.props.onConfirm(vendor.id); - this.props.onClose(); - } - render() { - const {finalizedLicenseModelList, vendorName, onClose} = this.props; - const {selectedValue} = this.state; - return ( - <div className='vsp-details-vendor-select'> - <Form - onSubmit={() => this.submit()} - onReset={() => onClose()} - isValid = {!!selectedValue} - submitButtonText={i18n('Save')} - hasButtons={true}> - <div className='vendor-selector-modal-title'>{`${i18n('The VLM')} '${vendorName}' ${i18n('assigned to this VSP is archived')}.`}</div> - <div className='vendor-selector-modal-additional-text'>{i18n('If you select a different VLM you will not be able to reselect the archived VLM.')}</div> - <Input - data-test-id='vsp-vendor-name-select' - label={i18n('Vendor')} - type='select' - onChange={e => {this.setState({ - selectedValue: e.target.options[e.target.selectedIndex].value - });}} - value={selectedValue}> - <option key='emtyVendor' value=''>{i18n('please select...')}</option> - {sortByStringProperty( - finalizedLicenseModelList, - 'name' - ).map(lm => <option key={lm.id} value={lm.id}>{lm.name}</option>) - } - </Input> - </Form> - </div> - ); - } + static propTypes = { + finalizedLicenseModelList: PropTypes.array, + vendorName: PropTypes.string, + onClose: PropTypes.func.isRequired, + onConfirm: PropTypes.func.isRequired + }; + constructor(props) { + super(props); + const selectedValue = props.finalizedLicenseModelList.length + ? props.finalizedLicenseModelList[0].id + : ''; + this.state = { + selectedValue + }; + } + submit() { + const vendor = this.props.finalizedLicenseModelList.find( + item => item.id === this.state.selectedValue + ); + this.props.onConfirm(vendor.id); + this.props.onClose(); + } + render() { + const { finalizedLicenseModelList, vendorName, onClose } = this.props; + const { selectedValue } = this.state; + return ( + <div className="vsp-details-vendor-select"> + <Form + onSubmit={() => this.submit()} + onReset={() => onClose()} + isValid={!!selectedValue} + submitButtonText={i18n('Save')} + hasButtons={true}> + <div className="vendor-selector-modal-title">{`${i18n( + 'The VLM' + )} '${vendorName}' ${i18n( + 'assigned to this VSP is archived' + )}.`}</div> + <div className="vendor-selector-modal-additional-text"> + {i18n( + 'If you select a different VLM you will not be able to reselect the archived VLM.' + )} + </div> + <Input + data-test-id="vsp-vendor-name-select" + label={i18n('Vendor')} + type="select" + onChange={e => { + this.setState({ + selectedValue: + e.target.options[e.target.selectedIndex] + .value + }); + }} + value={selectedValue}> + <option key="emtyVendor" value=""> + {i18n('please select...')} + </option> + {sortByStringProperty( + finalizedLicenseModelList, + 'name' + ).map(lm => ( + <option key={lm.id} value={lm.id}> + {lm.name} + </option> + ))} + </Input> + </Form> + </div> + ); + } } export default VendorSelector; - diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/details/SoftwareProductDetailsView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/details/SoftwareProductDetailsView.jsx index 24aa319c24..12b1eadc86 100644 --- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/details/SoftwareProductDetailsView.jsx +++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/details/SoftwareProductDetailsView.jsx @@ -13,7 +13,7 @@ * or implied. See the License for the specific language governing * permissions and limitations under the License. */ -import React, {Component} from 'react'; +import React, { Component } from 'react'; import PropTypes from 'prop-types'; import i18n from 'nfvo-utils/i18n/i18n.js'; @@ -24,427 +24,642 @@ import InputOptions from 'nfvo-components/input/validation/InputOptions.jsx'; import GridSection from 'nfvo-components/grid/GridSection.jsx'; import GridItem from 'nfvo-components/grid/GridItem.jsx'; import SoftwareProductCategoriesHelper from 'sdc-app/onboarding/softwareProduct/SoftwareProductCategoriesHelper.js'; -import {forms} from 'sdc-app/onboarding/softwareProduct/SoftwareProductConstants.js'; +import { forms } from 'sdc-app/onboarding/softwareProduct/SoftwareProductConstants.js'; -const DeprecatedVlmInfo = ({vendorName, onVendorRemove}) => { - return ( - <div className='depricated-vlm-info'> - <Input - data-test-id='vsp-vendor-name' - isRequired={true} - onClick={() => onVendorRemove()} - label={i18n('Vendor')} - type='select' - value={`${vendorName} (Archived)`}> - <option key={vendorName} value={`${vendorName} (Archived)`}>{`${vendorName} (Archived)`}</option> - </Input> - </div> - ); +const DeprecatedVlmInfo = ({ vendorName, onVendorRemove }) => { + return ( + <div className="depricated-vlm-info"> + <Input + data-test-id="vsp-vendor-name" + isRequired={true} + onClick={() => onVendorRemove()} + label={i18n('Vendor')} + type="select" + value={`${vendorName} (Archived)`}> + <option + key={vendorName} + value={`${vendorName} (Archived)`}>{`${vendorName} (Archived)`}</option> + </Input> + </div> + ); }; class GeneralSection extends React.Component { - static propTypes = { - vendorId: PropTypes.string, - name: PropTypes.string, - description: PropTypes.string, - subCategory: PropTypes.string, - softwareProductCategories: PropTypes.array, - finalizedLicenseModelList: PropTypes.array, - onDataChanged: PropTypes.func.isRequired, - onVendorParamChanged: PropTypes.func.isRequired, - onSelectSubCategory: PropTypes.func.isRequired, - isVendorArchived: PropTypes.bool, - onArchivedVendorRemove: PropTypes.func - }; + static propTypes = { + vendorId: PropTypes.string, + name: PropTypes.string, + description: PropTypes.string, + subCategory: PropTypes.string, + softwareProductCategories: PropTypes.array, + finalizedLicenseModelList: PropTypes.array, + onDataChanged: PropTypes.func.isRequired, + onVendorParamChanged: PropTypes.func.isRequired, + onSelectSubCategory: PropTypes.func.isRequired, + isVendorArchived: PropTypes.bool, + onArchivedVendorRemove: PropTypes.func + }; - onVendorParamChanged(e) { - const selectedIndex = e.target.selectedIndex; - const vendorId = e.target.options[selectedIndex].value; - this.props.onVendorParamChanged({vendorId}, forms.VENDOR_SOFTWARE_PRODUCT_DETAILS); + onVendorParamChanged(e) { + const selectedIndex = e.target.selectedIndex; + const vendorId = e.target.options[selectedIndex].value; + this.props.onVendorParamChanged( + { vendorId }, + forms.VENDOR_SOFTWARE_PRODUCT_DETAILS + ); + } - } + onSelectSubCategory(e) { + const selectedIndex = e.target.selectedIndex; + const subCategory = e.target.options[selectedIndex].value; + this.props.onSelectSubCategory(subCategory); + } + onVendorRemove() { + const { + finalizedLicenseModelList, + vendorName, + onVendorParamChanged + } = this.props; + this.props.onArchivedVendorRemove({ + finalizedLicenseModelList, + onVendorParamChanged, + vendorName + }); + } - onSelectSubCategory(e) { - const selectedIndex = e.target.selectedIndex; - const subCategory = e.target.options[selectedIndex].value; - this.props.onSelectSubCategory(subCategory); - } - onVendorRemove() { - const {finalizedLicenseModelList, vendorName, onVendorParamChanged} = this.props; - this.props.onArchivedVendorRemove({finalizedLicenseModelList, onVendorParamChanged, vendorName}); - } - - render (){ - let {genericFieldInfo} = this.props; - return ( - <div> - {genericFieldInfo && <GridSection title={i18n('General')} className='grid-section-general'> - <GridItem> - <Input - data-test-id='vsp-name' - label={i18n('Name')} - type='text' - value={this.props.name} - isRequired={true} - errorText={genericFieldInfo.name.errorText} - isValid={genericFieldInfo.name.isValid} - onChange={name => name.length <= 25 && this.props.onDataChanged({name}, forms.VENDOR_SOFTWARE_PRODUCT_DETAILS)}/> - {this.props.isVendorArchived ? - <DeprecatedVlmInfo onVendorRemove={()=>this.onVendorRemove()} vendorName={this.props.vendorName} /> : - <Input - data-test-id='vsp-vendor-name' - label={i18n('Vendor')} - type='select' - value={this.props.vendorId} - onChange={e => this.onVendorParamChanged(e)}> - {sortByStringProperty( - this.props.finalizedLicenseModelList, - 'name' - ).map(lm => <option key={lm.id} value={lm.id}>{lm.name}</option>) - } - </Input> - } - <Input - data-test-id='vsp-category-name' - label={i18n('Category')} - type='select' - value={this.props.subCategory} - onChange={e => this.onSelectSubCategory(e)}> - { - this.props.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> - <Input - data-test-id='vsp-description' - label={i18n('Description')} - type='textarea' - isRequired={true} - isValid={genericFieldInfo.description.isValid} - errorText={genericFieldInfo.description.errorText} - value={this.props.description} - onChange={description => this.props.onDataChanged({description}, forms.VENDOR_SOFTWARE_PRODUCT_DETAILS)}/> - </GridItem> - </GridSection>} - </div>); - } + render() { + let { genericFieldInfo } = this.props; + return ( + <div> + {genericFieldInfo && ( + <GridSection + title={i18n('General')} + className="grid-section-general"> + <GridItem> + <Input + data-test-id="vsp-name" + label={i18n('Name')} + type="text" + value={this.props.name} + isRequired={true} + errorText={genericFieldInfo.name.errorText} + isValid={genericFieldInfo.name.isValid} + onChange={name => + name.length <= 25 && + this.props.onDataChanged( + { name }, + forms.VENDOR_SOFTWARE_PRODUCT_DETAILS + ) + } + /> + {this.props.isVendorArchived ? ( + <DeprecatedVlmInfo + onVendorRemove={() => this.onVendorRemove()} + vendorName={this.props.vendorName} + /> + ) : ( + <Input + data-test-id="vsp-vendor-name" + label={i18n('Vendor')} + type="select" + value={this.props.vendorId} + onChange={e => + this.onVendorParamChanged(e) + }> + {sortByStringProperty( + this.props.finalizedLicenseModelList, + 'name' + ).map(lm => ( + <option key={lm.id} value={lm.id}> + {lm.name} + </option> + ))} + </Input> + )} + <Input + data-test-id="vsp-category-name" + label={i18n('Category')} + type="select" + value={this.props.subCategory} + onChange={e => this.onSelectSubCategory(e)}> + {this.props.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> + <Input + data-test-id="vsp-description" + label={i18n('Description')} + type="textarea" + isRequired={true} + isValid={genericFieldInfo.description.isValid} + errorText={ + genericFieldInfo.description.errorText + } + value={this.props.description} + onChange={description => + this.props.onDataChanged( + { description }, + forms.VENDOR_SOFTWARE_PRODUCT_DETAILS + ) + } + /> + </GridItem> + </GridSection> + )} + </div> + ); + } } class LicensesSection extends React.Component { - static propTypes = { - onVendorParamChanged: PropTypes.func.isRequired, - vendorId: PropTypes.string, - licensingVersion: PropTypes.string, - licensingVersionsList: PropTypes.array, - licensingData: PropTypes.shape({ - licenceAgreement: PropTypes.string, - featureGroups: PropTypes.array - }), - onFeatureGroupsChanged: PropTypes.func.isRequired, - onLicensingDataChanged: PropTypes.func.isRequired, - featureGroupsList: PropTypes.array, - licenseAgreementList: PropTypes.array, - isVendorArchived: PropTypes.bool - }; + static propTypes = { + onVendorParamChanged: PropTypes.func.isRequired, + vendorId: PropTypes.string, + licensingVersion: PropTypes.string, + licensingVersionsList: PropTypes.array, + licensingData: PropTypes.shape({ + licenceAgreement: PropTypes.string, + featureGroups: PropTypes.array + }), + onFeatureGroupsChanged: PropTypes.func.isRequired, + onLicensingDataChanged: PropTypes.func.isRequired, + featureGroupsList: PropTypes.array, + licenseAgreementList: PropTypes.array, + isVendorArchived: PropTypes.bool + }; - onVendorParamChanged(e) { - const selectedIndex = e.target.selectedIndex; - const licensingVersion = e.target.options[selectedIndex].value; - this.props.onVendorParamChanged({vendorId: this.props.vendorId, licensingVersion}, forms.VENDOR_SOFTWARE_PRODUCT_DETAILS); - } + onVendorParamChanged(e) { + const selectedIndex = e.target.selectedIndex; + const licensingVersion = e.target.options[selectedIndex].value; + this.props.onVendorParamChanged( + { vendorId: this.props.vendorId, licensingVersion }, + forms.VENDOR_SOFTWARE_PRODUCT_DETAILS + ); + } - onLicensingDataChanged(e) { - const selectedIndex = e.target.selectedIndex; - const licenseAgreement = e.target.options[selectedIndex].value; - this.props.onLicensingDataChanged({licenseAgreement, featureGroups: []}); - } + onLicensingDataChanged(e) { + const selectedIndex = e.target.selectedIndex; + const licenseAgreement = e.target.options[selectedIndex].value; + this.props.onLicensingDataChanged({ + licenseAgreement, + featureGroups: [] + }); + } - render(){ - return ( - <GridSection title={i18n('Licenses')}> - <GridItem> - <Input - data-test-id='vsp-licensing-version' - onChange={e => this.onVendorParamChanged(e)} - value={this.props.licensingVersion || ''} - label={i18n('Licensing Version')} - disabled={this.props.isVendorArchived} - type='select'> - {this.props.licensingVersionsList.map(version => - <option - key={version.enum} - value={version.enum}>{version.title} - </option> - )} - </Input> - </GridItem> - <GridItem> - <Input - data-test-id='vsp-license-agreement' - label={i18n('License Agreement')} - type='select' - disabled={this.props.isVendorArchived} - value={this.props.licensingData.licenseAgreement ? this.props.licensingData.licenseAgreement : '' } - onChange={(e) => this.onLicensingDataChanged(e)}> - <option key='placeholder' value=''>{i18n('Select...')}</option> - {this.props.licenseAgreementList.map(la => <option value={la.id} key={la.id}>{la.name}</option>)} - </Input> - </GridItem> - <GridItem> - {this.props.licensingData.licenseAgreement && ( - <InputOptions - data-test-id='vsp-feature-group' - type='select' - isMultiSelect={true} - onInputChange={()=>{}} - disabled={this.props.isVendorArchived} - onEnumChange={featureGroups => this.props.onFeatureGroupsChanged({featureGroups})} - multiSelectedEnum={this.props.licensingData.featureGroups} - name='feature-groups' - label={i18n('Feature Groups')} - clearable={false} - values={this.props.featureGroupsList}/>) - } - </GridItem> - </GridSection> - ); - } + render() { + return ( + <GridSection title={i18n('Licenses')}> + <GridItem> + <Input + data-test-id="vsp-licensing-version" + onChange={e => this.onVendorParamChanged(e)} + value={this.props.licensingVersion || ''} + label={i18n('Licensing Version')} + disabled={this.props.isVendorArchived} + type="select"> + {this.props.licensingVersionsList.map(version => ( + <option key={version.enum} value={version.enum}> + {version.title} + </option> + ))} + </Input> + </GridItem> + <GridItem> + <Input + data-test-id="vsp-license-agreement" + label={i18n('License Agreement')} + type="select" + disabled={this.props.isVendorArchived} + value={ + this.props.licensingData.licenseAgreement + ? this.props.licensingData.licenseAgreement + : '' + } + onChange={e => this.onLicensingDataChanged(e)}> + <option key="placeholder" value=""> + {i18n('Select...')} + </option> + {this.props.licenseAgreementList.map(la => ( + <option value={la.id} key={la.id}> + {la.name} + </option> + ))} + </Input> + </GridItem> + <GridItem> + {this.props.licensingData.licenseAgreement && ( + <InputOptions + data-test-id="vsp-feature-group" + type="select" + isMultiSelect={true} + onInputChange={() => {}} + disabled={this.props.isVendorArchived} + onEnumChange={featureGroups => + this.props.onFeatureGroupsChanged({ + featureGroups + }) + } + multiSelectedEnum={ + this.props.licensingData.featureGroups + } + name="feature-groups" + label={i18n('Feature Groups')} + clearable={false} + values={this.props.featureGroupsList} + /> + )} + </GridItem> + </GridSection> + ); + } } -const AvailabilitySection = (props) => ( - <GridSection title={i18n('Availability')}> - <GridItem colSpan={2}> - <Input - data-test-id='vsp-use-availability-zone' - label={i18n('Use Availability Zones for High Availability')} - type='checkbox' - checked={props.dataMap['general/availability/useAvailabilityZonesForHighAvailability']} - value={props.dataMap['general/availability/useAvailabilityZonesForHighAvailability']} - onChange={(aZone) => props.onQDataChanged({'general/availability/useAvailabilityZonesForHighAvailability' : aZone})} /> - </GridItem> - </GridSection> +const AvailabilitySection = props => ( + <GridSection title={i18n('Availability')}> + <GridItem colSpan={2}> + <Input + data-test-id="vsp-use-availability-zone" + label={i18n('Use Availability Zones for High Availability')} + type="checkbox" + checked={ + props.dataMap[ + 'general/availability/useAvailabilityZonesForHighAvailability' + ] + } + value={ + props.dataMap[ + 'general/availability/useAvailabilityZonesForHighAvailability' + ] + } + onChange={aZone => + props.onQDataChanged({ + 'general/availability/useAvailabilityZonesForHighAvailability': aZone + }) + } + /> + </GridItem> + </GridSection> ); -const RegionsSection = (props) => ( - <GridSection title={i18n('Regions')}> - <GridItem> - <InputOptions - data-test-id='vsp-regions' - type='select' - isMultiSelect={true} - onInputChange={()=>{}} - onEnumChange={(regions) => props.onQDataChanged({'general/regionsData/regions' : regions})} - multiSelectedEnum={props.dataMap['general/regionsData/regions']} - name='vsp-regions' - clearable={false} - values={props.genericFieldInfo['general/regionsData/regions'].enum} /> - </GridItem> - </GridSection> +const RegionsSection = props => ( + <GridSection title={i18n('Regions')}> + <GridItem> + <InputOptions + data-test-id="vsp-regions" + type="select" + isMultiSelect={true} + onInputChange={() => {}} + onEnumChange={regions => + props.onQDataChanged({ + 'general/regionsData/regions': regions + }) + } + multiSelectedEnum={props.dataMap['general/regionsData/regions']} + name="vsp-regions" + clearable={false} + values={ + props.genericFieldInfo['general/regionsData/regions'].enum + } + /> + </GridItem> + </GridSection> ); -const StorageDataReplicationSection = (props) => ( - <GridSection title={i18n('Storage Data Replication')}> - <GridItem> - <Input - data-test-id='vsp-storage-rep-size' - label={i18n('Storage Replication Size (GB)')} - type='number' - isValid={props.genericFieldInfo['general/storageDataReplication/storageReplicationSize'].isValid} - errorText={props.genericFieldInfo['general/storageDataReplication/storageReplicationSize'].errorText} - value={props.dataMap['general/storageDataReplication/storageReplicationSize']} - onChange={(sRep) => props.onQDataChanged({'general/storageDataReplication/storageReplicationSize' : sRep})} /> - </GridItem> - <GridItem> - <Input - data-test-id='vsp-storage-rep-source' - label={i18n('Storage Replication Source')} - type='text' - isValid={props.genericFieldInfo['general/storageDataReplication/storageReplicationSource'].isValid} - errorText={props.genericFieldInfo['general/storageDataReplication/storageReplicationSource'].errorText} - value={props.dataMap['general/storageDataReplication/storageReplicationSource']} - onChange={(sRepSource) => props.onQDataChanged({'general/storageDataReplication/storageReplicationSource' : sRepSource})} /> - </GridItem> - <GridItem> - <Input - data-test-id='vsp-storage-rep-freq' - label={i18n('Storage Replication Freq. (min)')} - type='number' - isValid={props.genericFieldInfo['general/storageDataReplication/storageReplicationFrequency'].isValid} - errorText={props.genericFieldInfo['general/storageDataReplication/storageReplicationFrequency'].errorText} - value={props.dataMap['general/storageDataReplication/storageReplicationFrequency']} - onChange={(sRepFreq) => props.onQDataChanged({'general/storageDataReplication/storageReplicationFrequency' : sRepFreq})} /> - </GridItem> - <GridItem> - <Input - data-test-id='vsp-storage-rep-dest' - label={i18n('Storage Replication Destination')} - type='text' - isValid={props.genericFieldInfo['general/storageDataReplication/storageReplicationDestination'].isValid} - errorText={props.genericFieldInfo['general/storageDataReplication/storageReplicationDestination'].errorText} - value={props.dataMap['general/storageDataReplication/storageReplicationDestination']} - onChange={(sRepDest) => props.onQDataChanged({'general/storageDataReplication/storageReplicationDestination' : sRepDest})} /> - </GridItem> - </GridSection> +const StorageDataReplicationSection = props => ( + <GridSection title={i18n('Storage Data Replication')}> + <GridItem> + <Input + data-test-id="vsp-storage-rep-size" + label={i18n('Storage Replication Size (GB)')} + type="number" + isValid={ + props.genericFieldInfo[ + 'general/storageDataReplication/storageReplicationSize' + ].isValid + } + errorText={ + props.genericFieldInfo[ + 'general/storageDataReplication/storageReplicationSize' + ].errorText + } + value={ + props.dataMap[ + 'general/storageDataReplication/storageReplicationSize' + ] + } + onChange={sRep => + props.onQDataChanged({ + 'general/storageDataReplication/storageReplicationSize': sRep + }) + } + /> + </GridItem> + <GridItem> + <Input + data-test-id="vsp-storage-rep-source" + label={i18n('Storage Replication Source')} + type="text" + isValid={ + props.genericFieldInfo[ + 'general/storageDataReplication/storageReplicationSource' + ].isValid + } + errorText={ + props.genericFieldInfo[ + 'general/storageDataReplication/storageReplicationSource' + ].errorText + } + value={ + props.dataMap[ + 'general/storageDataReplication/storageReplicationSource' + ] + } + onChange={sRepSource => + props.onQDataChanged({ + 'general/storageDataReplication/storageReplicationSource': sRepSource + }) + } + /> + </GridItem> + <GridItem> + <Input + data-test-id="vsp-storage-rep-freq" + label={i18n('Storage Replication Freq. (min)')} + type="number" + isValid={ + props.genericFieldInfo[ + 'general/storageDataReplication/storageReplicationFrequency' + ].isValid + } + errorText={ + props.genericFieldInfo[ + 'general/storageDataReplication/storageReplicationFrequency' + ].errorText + } + value={ + props.dataMap[ + 'general/storageDataReplication/storageReplicationFrequency' + ] + } + onChange={sRepFreq => + props.onQDataChanged({ + 'general/storageDataReplication/storageReplicationFrequency': sRepFreq + }) + } + /> + </GridItem> + <GridItem> + <Input + data-test-id="vsp-storage-rep-dest" + label={i18n('Storage Replication Destination')} + type="text" + isValid={ + props.genericFieldInfo[ + 'general/storageDataReplication/storageReplicationDestination' + ].isValid + } + errorText={ + props.genericFieldInfo[ + 'general/storageDataReplication/storageReplicationDestination' + ].errorText + } + value={ + props.dataMap[ + 'general/storageDataReplication/storageReplicationDestination' + ] + } + onChange={sRepDest => + props.onQDataChanged({ + 'general/storageDataReplication/storageReplicationDestination': sRepDest + }) + } + /> + </GridItem> + </GridSection> ); class SoftwareProductDetails extends Component { + static propTypes = { + vendorName: PropTypes.string, + currentSoftwareProduct: PropTypes.shape({ + id: PropTypes.string, + name: PropTypes.string, + description: PropTypes.string, + category: PropTypes.string, + subCategory: PropTypes.string, + vendorId: PropTypes.string, + vendorName: PropTypes.string, + licensingVersion: PropTypes.string, + licensingData: PropTypes.shape({ + licenceAgreement: PropTypes.string, + featureGroups: PropTypes.array + }) + }), + softwareProductCategories: PropTypes.array, + finalizedLicenseModelList: PropTypes.array, + licenseAgreementList: PropTypes.array, + featureGroupsList: PropTypes.array, + onSubmit: PropTypes.func.isRequired, + onDataChanged: PropTypes.func.isRequired, + onValidityChanged: PropTypes.func.isRequired, + qdata: PropTypes.object.isRequired, + onQDataChanged: PropTypes.func.isRequired, + onVendorParamChanged: PropTypes.func.isRequired + }; - static propTypes = { - vendorName: PropTypes.string, - currentSoftwareProduct: PropTypes.shape({ - id: PropTypes.string, - name: PropTypes.string, - description: PropTypes.string, - category: PropTypes.string, - subCategory: PropTypes.string, - vendorId: PropTypes.string, - vendorName: PropTypes.string, - licensingVersion: PropTypes.string, - licensingData: PropTypes.shape({ - licenceAgreement: PropTypes.string, - featureGroups: PropTypes.array - }) - }), - softwareProductCategories: PropTypes.array, - finalizedLicenseModelList: PropTypes.array, - licenseAgreementList: PropTypes.array, - featureGroupsList: PropTypes.array, - onSubmit: PropTypes.func.isRequired, - onDataChanged: PropTypes.func.isRequired, - onValidityChanged: PropTypes.func.isRequired, - qdata: PropTypes.object.isRequired, - onQDataChanged: PropTypes.func.isRequired, - onVendorParamChanged: PropTypes.func.isRequired - }; - - prepareDataForGeneralSection(){ - let {softwareProductCategories, finalizedLicenseModelList, onDataChanged, currentSoftwareProduct, genericFieldInfo, isVendorArchived, onArchivedVendorRemove} = this.props; - let {name, description, vendorId, subCategory, vendorName} = currentSoftwareProduct; - return { - name, - description, - vendorId, - subCategory, - softwareProductCategories, - finalizedLicenseModelList, - onDataChanged, - onVendorParamChanged: args => this.onVendorParamChanged(args), - onSelectSubCategory: args => this.onSelectSubCategory(args), - genericFieldInfo, - vendorName, - isVendorArchived, - onArchivedVendorRemove - }; - - } + prepareDataForGeneralSection() { + let { + softwareProductCategories, + finalizedLicenseModelList, + onDataChanged, + currentSoftwareProduct, + genericFieldInfo, + isVendorArchived, + onArchivedVendorRemove + } = this.props; + let { + name, + description, + vendorId, + subCategory, + vendorName + } = currentSoftwareProduct; + return { + name, + description, + vendorId, + subCategory, + softwareProductCategories, + finalizedLicenseModelList, + onDataChanged, + onVendorParamChanged: args => this.onVendorParamChanged(args), + onSelectSubCategory: args => this.onSelectSubCategory(args), + genericFieldInfo, + vendorName, + isVendorArchived, + onArchivedVendorRemove + }; + } - prepareDataForLicensesSection(){ - let { featureGroupsList, licenseAgreementList, currentSoftwareProduct, isVendorArchived} = this.props; - let {vendorId, licensingVersion, licensingData = {}} = currentSoftwareProduct; - return { - onVendorParamChanged: args => this.onVendorParamChanged(args), - vendorId, - licensingVersion, - licensingVersionsList: this.buildLicensingVersionsListItems(), - licensingData, - onFeatureGroupsChanged: args => this.onFeatureGroupsChanged(args), - onLicensingDataChanged: args => this.onLicensingDataChanged(args), - featureGroupsList, - licenseAgreementList, - isVendorArchived - }; + prepareDataForLicensesSection() { + let { + featureGroupsList, + licenseAgreementList, + currentSoftwareProduct, + isVendorArchived + } = this.props; + let { + vendorId, + licensingVersion, + licensingData = {} + } = currentSoftwareProduct; + return { + onVendorParamChanged: args => this.onVendorParamChanged(args), + vendorId, + licensingVersion, + licensingVersionsList: this.buildLicensingVersionsListItems(), + licensingData, + onFeatureGroupsChanged: args => this.onFeatureGroupsChanged(args), + onLicensingDataChanged: args => this.onLicensingDataChanged(args), + featureGroupsList, + licenseAgreementList, + isVendorArchived + }; + } - } + render() { + let { currentSoftwareProduct } = this.props; + let { qdata, onQDataChanged, dataMap, qGenericFieldInfo } = this.props; + let { isReadOnlyMode } = this.props; - render() { - let {currentSoftwareProduct} = this.props; - let {qdata, onQDataChanged, dataMap, qGenericFieldInfo} = this.props; - let {isReadOnlyMode} = this.props; + return ( + <div className="vsp-details-page"> + <Form + ref={validationForm => + (this.validationForm = validationForm) + } + className="vsp-general-tab" + hasButtons={false} + formReady={null} + isValid={this.props.isFormValid} + onSubmit={() => + this.props.onSubmit(currentSoftwareProduct, qdata) + } + onValidityChanged={isValidityData => + this.props.onValidityChanged(isValidityData) + } + isReadOnlyMode={isReadOnlyMode}> + <GeneralSection {...this.prepareDataForGeneralSection()} /> + <LicensesSection + {...this.prepareDataForLicensesSection()} + /> + <AvailabilitySection + onQDataChanged={onQDataChanged} + dataMap={dataMap} + /> + <RegionsSection + onQDataChanged={onQDataChanged} + dataMap={dataMap} + genericFieldInfo={qGenericFieldInfo} + /> + <StorageDataReplicationSection + onQDataChanged={onQDataChanged} + dataMap={dataMap} + genericFieldInfo={qGenericFieldInfo} + /> + </Form> + </div> + ); + } - return ( - <div className='vsp-details-page'> - <Form - ref={(validationForm) => this.validationForm = validationForm} - className='vsp-general-tab' - hasButtons={false} - formReady={null} - isValid={this.props.isFormValid} - onSubmit={() => this.props.onSubmit(currentSoftwareProduct, qdata)} - onValidityChanged={(isValidityData) => this.props.onValidityChanged(isValidityData)} - isReadOnlyMode={isReadOnlyMode}> - <GeneralSection {...this.prepareDataForGeneralSection()}/> - <LicensesSection {...this.prepareDataForLicensesSection()}/> - <AvailabilitySection onQDataChanged={onQDataChanged} dataMap={dataMap} /> - <RegionsSection onQDataChanged={onQDataChanged} dataMap={dataMap} genericFieldInfo={qGenericFieldInfo} /> - <StorageDataReplicationSection onQDataChanged={onQDataChanged} dataMap={dataMap} genericFieldInfo={qGenericFieldInfo} /> - </Form> - </div> - ); - } + onVendorParamChanged({ vendorId, licensingVersion }) { + let { finalizedLicenseModelList, onVendorParamChanged } = this.props; + if (!licensingVersion) { + const licensingVersionsList = this.buildLicensingVersionsListItems(); + licensingVersion = licensingVersionsList[0].enum; + } - onVendorParamChanged({vendorId, licensingVersion}) { - - let {finalizedLicenseModelList, onVendorParamChanged} = this.props; - if(!licensingVersion) { - const licensingVersionsList = this.buildLicensingVersionsListItems(); - licensingVersion = licensingVersionsList[0].enum; - } - - if (!vendorId) { - vendorId = finalizedLicenseModelList[0].id; - } - - let vendorName = finalizedLicenseModelList.find(licenseModelItem => licenseModelItem.id === vendorId).name || ''; - let deltaData = { - vendorId, - vendorName, - licensingVersion, - licensingData: {} - }; + if (!vendorId) { + vendorId = finalizedLicenseModelList[0].id; + } - onVendorParamChanged(deltaData, forms.VENDOR_SOFTWARE_PRODUCT_DETAILS); + let vendorName = + finalizedLicenseModelList.find( + licenseModelItem => licenseModelItem.id === vendorId + ).name || ''; + let deltaData = { + vendorId, + vendorName, + licensingVersion, + licensingData: {} + }; - } + onVendorParamChanged(deltaData, forms.VENDOR_SOFTWARE_PRODUCT_DETAILS); + } - buildLicensingVersionsListItems() { - let {licensingVersionsList} = this.props; + buildLicensingVersionsListItems() { + let { licensingVersionsList } = this.props; - let licensingVersionsListItems = [{ - enum: '', - title: i18n('Select...') - }]; + let licensingVersionsListItems = [ + { + enum: '', + title: i18n('Select...') + } + ]; - return licensingVersionsListItems.concat(licensingVersionsList.map(version => ({enum: version.id, title: version.name}))); - } + return licensingVersionsListItems.concat( + licensingVersionsList.map(version => ({ + enum: version.id, + title: version.name + })) + ); + } - onFeatureGroupsChanged({featureGroups}) { - this.onLicensingDataChanged({featureGroups}); - } + onFeatureGroupsChanged({ featureGroups }) { + this.onLicensingDataChanged({ featureGroups }); + } - onLicensingDataChanged(deltaData) { - this.props.onDataChanged({ - licensingData: { - ...this.props.currentSoftwareProduct.licensingData, - ...deltaData - } - }, forms.VENDOR_SOFTWARE_PRODUCT_DETAILS); - } + onLicensingDataChanged(deltaData) { + this.props.onDataChanged( + { + licensingData: { + ...this.props.currentSoftwareProduct.licensingData, + ...deltaData + } + }, + forms.VENDOR_SOFTWARE_PRODUCT_DETAILS + ); + } - onSelectSubCategory(subCategory) { - let {softwareProductCategories, onDataChanged} = this.props; - let category = SoftwareProductCategoriesHelper.getCurrentCategoryOfSubCategory(subCategory, softwareProductCategories); - onDataChanged({category, subCategory}, forms.VENDOR_SOFTWARE_PRODUCT_DETAILS); - } + onSelectSubCategory(subCategory) { + let { softwareProductCategories, onDataChanged } = this.props; + let category = SoftwareProductCategoriesHelper.getCurrentCategoryOfSubCategory( + subCategory, + softwareProductCategories + ); + onDataChanged( + { category, subCategory }, + forms.VENDOR_SOFTWARE_PRODUCT_DETAILS + ); + } - save(){ - return this.validationForm.handleFormSubmit(new Event('dummy')); - } + save() { + return this.validationForm.handleFormSubmit(new Event('dummy')); + } } export default SoftwareProductDetails; |