2 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
13 * or implied. See the License for the specific language governing
14 * permissions and limitations under the License.
16 import React, {Component} from 'react';
17 import PropTypes from 'prop-types';
19 import i18n from 'nfvo-utils/i18n/i18n.js';
20 import sortByStringProperty from 'nfvo-utils/sortByStringProperty.js';
21 import Form from 'nfvo-components/input/validation/Form.jsx';
22 import Input from 'nfvo-components/input/validation/Input.jsx';
23 import InputOptions from 'nfvo-components/input/validation/InputOptions.jsx';
24 import GridSection from 'nfvo-components/grid/GridSection.jsx';
25 import GridItem from 'nfvo-components/grid/GridItem.jsx';
26 import SoftwareProductCategoriesHelper from 'sdc-app/onboarding/softwareProduct/SoftwareProductCategoriesHelper.js';
27 import {forms} from 'sdc-app/onboarding/softwareProduct/SoftwareProductConstants.js';
29 class GeneralSection extends React.Component {
31 vendorId: PropTypes.string,
32 name: PropTypes.string,
33 description: PropTypes.string,
34 subCategory: PropTypes.string,
35 softwareProductCategories: PropTypes.array,
36 finalizedLicenseModelList: PropTypes.array,
37 onDataChanged: PropTypes.func.isRequired,
38 onVendorParamChanged: PropTypes.func.isRequired,
39 onSelectSubCategory: PropTypes.func.isRequired
42 onVendorParamChanged(e) {
43 const selectedIndex = e.target.selectedIndex;
44 const vendorId = e.target.options[selectedIndex].value;
45 this.props.onVendorParamChanged({vendorId}, forms.VENDOR_SOFTWARE_PRODUCT_DETAILS);
49 onSelectSubCategory(e) {
50 const selectedIndex = e.target.selectedIndex;
51 const subCategory = e.target.options[selectedIndex].value;
52 this.props.onSelectSubCategory(subCategory);
56 let {genericFieldInfo} = this.props;
59 {genericFieldInfo && <GridSection title={i18n('General')} className='grid-section-general'>
62 data-test-id='vsp-name'
65 value={this.props.name}
67 errorText={genericFieldInfo.name.errorText}
68 isValid={genericFieldInfo.name.isValid}
69 onChange={name => name.length <= 25 && this.props.onDataChanged({name}, forms.VENDOR_SOFTWARE_PRODUCT_DETAILS)}/>
71 data-test-id='vsp-vendor-name'
72 label={i18n('Vendor')}
74 value={this.props.vendorId}
75 onChange={e => this.onVendorParamChanged(e)}>
76 {sortByStringProperty(
77 this.props.finalizedLicenseModelList,
79 ).map(lm => <option key={lm.id} value={lm.id}>{lm.name}</option>)
83 data-test-id='vsp-category-name'
84 label={i18n('Category')}
86 value={this.props.subCategory}
87 onChange={e => this.onSelectSubCategory(e)}>
89 this.props.softwareProductCategories.map(category =>
90 category.subcategories &&
93 label={category.name}>{category.subcategories.map(sub =>
96 value={sub.uniqueId}>{`${sub.name} (${category.name})`}</option>)}
102 <GridItem colSpan={2} stretch>
104 data-test-id='vsp-description'
105 label={i18n('Description')}
108 isValid={genericFieldInfo.description.isValid}
109 errorText={genericFieldInfo.description.errorText}
110 value={this.props.description}
111 onChange={description => this.props.onDataChanged({description}, forms.VENDOR_SOFTWARE_PRODUCT_DETAILS)}/>
117 class LicensesSection extends React.Component {
119 onVendorParamChanged: PropTypes.func.isRequired,
120 vendorId: PropTypes.string,
121 licensingVersion: PropTypes.string,
122 licensingVersionsList: PropTypes.array,
123 licensingData: PropTypes.shape({
124 licenceAgreement: PropTypes.string,
125 featureGroups: PropTypes.array
127 onFeatureGroupsChanged: PropTypes.func.isRequired,
128 onLicensingDataChanged: PropTypes.func.isRequired,
129 featureGroupsList: PropTypes.array,
130 licenseAgreementList: PropTypes.array
133 onVendorParamChanged(e) {
134 const selectedIndex = e.target.selectedIndex;
135 const licensingVersion = e.target.options[selectedIndex].value;
136 this.props.onVendorParamChanged({vendorId: this.props.vendorId, licensingVersion}, forms.VENDOR_SOFTWARE_PRODUCT_DETAILS);
139 onLicensingDataChanged(e) {
140 const selectedIndex = e.target.selectedIndex;
141 const licenseAgreement = e.target.options[selectedIndex].value;
142 this.props.onLicensingDataChanged({licenseAgreement, featureGroups: []});
147 <GridSection title={i18n('Licenses')}>
150 data-test-id='vsp-licensing-version'
151 onChange={e => this.onVendorParamChanged(e)}
152 value={this.props.licensingVersion || ''}
153 label={i18n('Licensing Version')}
155 {this.props.licensingVersionsList.map(version =>
158 value={version.enum}>{version.title}
165 data-test-id='vsp-license-agreement'
166 label={i18n('License Agreement')}
168 value={this.props.licensingData.licenseAgreement ? this.props.licensingData.licenseAgreement : '' }
169 onChange={(e) => this.onLicensingDataChanged(e)}>
170 <option key='placeholder' value=''>{i18n('Select...')}</option>
171 {this.props.licenseAgreementList.map(la => <option value={la.id} key={la.id}>{la.name}</option>)}
175 {this.props.licensingData.licenseAgreement && (
177 data-test-id='vsp-feature-group'
180 onInputChange={()=>{}}
181 onEnumChange={featureGroups => this.props.onFeatureGroupsChanged({featureGroups})}
182 multiSelectedEnum={this.props.licensingData.featureGroups}
183 name='feature-groups'
184 label={i18n('Feature Groups')}
186 values={this.props.featureGroupsList}/>)
193 const AvailabilitySection = (props) => (
194 <GridSection title={i18n('Availability')}>
195 <GridItem colSpan={2}>
197 data-test-id='vsp-use-availability-zone'
198 label={i18n('Use Availability Zones for High Availability')}
200 checked={props.dataMap['general/availability/useAvailabilityZonesForHighAvailability']}
201 value={props.dataMap['general/availability/useAvailabilityZonesForHighAvailability']}
202 onChange={(aZone) => props.onQDataChanged({'general/availability/useAvailabilityZonesForHighAvailability' : aZone})} />
206 const RegionsSection = (props) => (
207 <GridSection title={i18n('Regions')}>
210 data-test-id='vsp-regions'
213 onInputChange={()=>{}}
214 onEnumChange={(regions) => props.onQDataChanged({'general/regionsData/regions' : regions})}
215 multiSelectedEnum={props.dataMap['general/regionsData/regions']}
218 values={props.genericFieldInfo['general/regionsData/regions'].enum} />
222 const StorageDataReplicationSection = (props) => (
223 <GridSection title={i18n('Storage Data Replication')}>
226 data-test-id='vsp-storage-rep-size'
227 label={i18n('Storage Replication Size (GB)')}
229 isValid={props.genericFieldInfo['general/storageDataReplication/storageReplicationSize'].isValid}
230 errorText={props.genericFieldInfo['general/storageDataReplication/storageReplicationSize'].errorText}
231 value={props.dataMap['general/storageDataReplication/storageReplicationSize']}
232 onChange={(sRep) => props.onQDataChanged({'general/storageDataReplication/storageReplicationSize' : sRep})} />
236 data-test-id='vsp-storage-rep-source'
237 label={i18n('Storage Replication Source')}
239 isValid={props.genericFieldInfo['general/storageDataReplication/storageReplicationSource'].isValid}
240 errorText={props.genericFieldInfo['general/storageDataReplication/storageReplicationSource'].errorText}
241 value={props.dataMap['general/storageDataReplication/storageReplicationSource']}
242 onChange={(sRepSource) => props.onQDataChanged({'general/storageDataReplication/storageReplicationSource' : sRepSource})} />
246 data-test-id='vsp-storage-rep-freq'
247 label={i18n('Storage Replication Freq. (min)')}
249 isValid={props.genericFieldInfo['general/storageDataReplication/storageReplicationFrequency'].isValid}
250 errorText={props.genericFieldInfo['general/storageDataReplication/storageReplicationFrequency'].errorText}
251 value={props.dataMap['general/storageDataReplication/storageReplicationFrequency']}
252 onChange={(sRepFreq) => props.onQDataChanged({'general/storageDataReplication/storageReplicationFrequency' : sRepFreq})} />
256 data-test-id='vsp-storage-rep-dest'
257 label={i18n('Storage Replication Destination')}
259 isValid={props.genericFieldInfo['general/storageDataReplication/storageReplicationDestination'].isValid}
260 errorText={props.genericFieldInfo['general/storageDataReplication/storageReplicationDestination'].errorText}
261 value={props.dataMap['general/storageDataReplication/storageReplicationDestination']}
262 onChange={(sRepDest) => props.onQDataChanged({'general/storageDataReplication/storageReplicationDestination' : sRepDest})} />
267 class SoftwareProductDetails extends Component {
270 vendorName: PropTypes.string,
271 currentSoftwareProduct: PropTypes.shape({
272 id: PropTypes.string,
273 name: PropTypes.string,
274 description: PropTypes.string,
275 category: PropTypes.string,
276 subCategory: PropTypes.string,
277 vendorId: PropTypes.string,
278 vendorName: PropTypes.string,
279 licensingVersion: PropTypes.string,
280 licensingData: PropTypes.shape({
281 licenceAgreement: PropTypes.string,
282 featureGroups: PropTypes.array
285 softwareProductCategories: PropTypes.array,
286 finalizedLicenseModelList: PropTypes.array,
287 licenseAgreementList: PropTypes.array,
288 featureGroupsList: PropTypes.array,
289 onSubmit: PropTypes.func.isRequired,
290 onDataChanged: PropTypes.func.isRequired,
291 onValidityChanged: PropTypes.func.isRequired,
292 qdata: PropTypes.object.isRequired,
293 onQDataChanged: PropTypes.func.isRequired,
294 onVendorParamChanged: PropTypes.func.isRequired
297 prepareDataForGeneralSection(){
298 let {softwareProductCategories, finalizedLicenseModelList, onDataChanged, currentSoftwareProduct, genericFieldInfo} = this.props;
299 let {name, description, vendorId, subCategory} = currentSoftwareProduct;
305 softwareProductCategories,
306 finalizedLicenseModelList,
308 onVendorParamChanged: args => this.onVendorParamChanged(args),
309 onSelectSubCategory: args => this.onSelectSubCategory(args),
315 prepareDataForLicensesSection(){
316 let { featureGroupsList, licenseAgreementList, currentSoftwareProduct } = this.props;
317 let {vendorId, licensingVersion, licensingData = {}} = currentSoftwareProduct;
319 onVendorParamChanged: args => this.onVendorParamChanged(args),
322 licensingVersionsList: this.buildLicensingVersionsListItems(),
324 onFeatureGroupsChanged: args => this.onFeatureGroupsChanged(args),
325 onLicensingDataChanged: args => this.onLicensingDataChanged(args),
327 licenseAgreementList,
333 let {currentSoftwareProduct} = this.props;
334 let {qdata, onQDataChanged, dataMap, qGenericFieldInfo} = this.props;
335 let {isReadOnlyMode} = this.props;
338 <div className='vsp-details-page'>
340 ref={(validationForm) => this.validationForm = validationForm}
341 className='vsp-general-tab'
344 isValid={this.props.isFormValid}
345 onSubmit={() => this.props.onSubmit(currentSoftwareProduct, qdata)}
346 onValidityChanged={(isValidityData) => this.props.onValidityChanged(isValidityData)}
347 isReadOnlyMode={isReadOnlyMode}>
348 <GeneralSection {...this.prepareDataForGeneralSection()}/>
349 <LicensesSection {...this.prepareDataForLicensesSection()}/>
350 <AvailabilitySection onQDataChanged={onQDataChanged} dataMap={dataMap} />
351 <RegionsSection onQDataChanged={onQDataChanged} dataMap={dataMap} genericFieldInfo={qGenericFieldInfo} />
352 <StorageDataReplicationSection onQDataChanged={onQDataChanged} dataMap={dataMap} genericFieldInfo={qGenericFieldInfo} />
358 onVendorParamChanged({vendorId, licensingVersion}) {
359 let {finalizedLicenseModelList, onVendorParamChanged} = this.props;
360 if(!licensingVersion) {
361 const licensingVersionsList = this.buildLicensingVersionsListItems();
362 licensingVersion = licensingVersionsList[0].enum;
364 let vendorName = finalizedLicenseModelList.find(licenseModelItem => licenseModelItem.id === vendorId).name || '';
372 onVendorParamChanged(deltaData, forms.VENDOR_SOFTWARE_PRODUCT_DETAILS);
376 buildLicensingVersionsListItems() {
377 let {licensingVersionsList} = this.props;
379 let licensingVersionsListItems = [{
381 title: i18n('Select...')
384 return licensingVersionsListItems.concat(licensingVersionsList.map(version => ({enum: version.id, title: version.name})));
387 onFeatureGroupsChanged({featureGroups}) {
388 this.onLicensingDataChanged({featureGroups});
391 onLicensingDataChanged(deltaData) {
392 this.props.onDataChanged({
394 ...this.props.currentSoftwareProduct.licensingData,
397 }, forms.VENDOR_SOFTWARE_PRODUCT_DETAILS);
400 onSelectSubCategory(subCategory) {
401 let {softwareProductCategories, onDataChanged} = this.props;
402 let category = SoftwareProductCategoriesHelper.getCurrentCategoryOfSubCategory(subCategory, softwareProductCategories);
403 onDataChanged({category, subCategory}, forms.VENDOR_SOFTWARE_PRODUCT_DETAILS);
407 return this.validationForm.handleFormSubmit(new Event('dummy'));
411 export default SoftwareProductDetails;