From 280f8015d06af1f41a3ef12e8300801c7a5e0d54 Mon Sep 17 00:00:00 2001
From: AviZi <avi.ziv@amdocs.com>
Date: Fri, 9 Jun 2017 02:39:56 +0300
Subject: [SDC-29] Amdocs OnBoard 1707 initial commit.

Change-Id: Ie4d12a3f574008b792899b368a0902a8b46b5370
Signed-off-by: AviZi <avi.ziv@amdocs.com>
---
 .../details/SoftwareProductDetailsView.jsx         | 480 ++++++++++++++-------
 1 file changed, 320 insertions(+), 160 deletions(-)

(limited to 'openecomp-ui/src/sdc-app/onboarding/softwareProduct/details/SoftwareProductDetailsView.jsx')

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 75a5797dec..1d52da38b0 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/details/SoftwareProductDetailsView.jsx
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/details/SoftwareProductDetailsView.jsx
@@ -1,9 +1,266 @@
+/*!
+ * 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, {Component, PropTypes} from 'react';
 
 import i18n from 'nfvo-utils/i18n/i18n.js';
-import Form from 'nfvo-components/input/validation/ValidationForm.jsx';
-import ValidationInput from 'nfvo-components/input/validation/ValidationInput.jsx';
+import sortByStringProperty from 'nfvo-utils/sortByStringProperty.js';
+import Form from 'nfvo-components/input/validation/Form.jsx';
+import Input from 'nfvo-components/input/validation/Input.jsx';
+import InputOptions from 'nfvo-components/input/inputOptions/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';
+
+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
+	};
+
+	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);
+	}
+
+	render (){
+		let {genericFieldInfo} = this.props;
+		return (
+			<div>
+			{genericFieldInfo && <GridSection title={i18n('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 => this.props.onDataChanged({name}, forms.VENDOR_SOFTWARE_PRODUCT_DETAILS)}/>
+				<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,
+						'vendorName'
+					).map(lm => <option key={lm.id} value={lm.id}>{lm.vendorName}</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.object,
+		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
+	};
+
+	onVendorParamChanged(e) {
+		const selectedIndex = e.target.selectedIndex;
+		const licensingVersion = e.target.options[selectedIndex].value;
+		this.props.onVendorParamChanged({vendorId: this.props.vendorId, licensingVersion:{id:licensingVersion, label: 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: []});
+	}
+
+	render(){
+		return (
+			<GridSection title={i18n('Licenses')}>
+				<GridItem>
+					<Input
+						data-test-id='vsp-licensing-version'
+						onChange={e => this.onVendorParamChanged(e)}
+						value={this.props.licensingVersion ? this.props.licensingVersion.id : ''}
+						label={i18n('Licensing Version')}
+						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'
+						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={()=>{}}
+							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'
+				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 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 {
 
@@ -17,7 +274,7 @@ class SoftwareProductDetails extends Component {
 			subCategory: PropTypes.string,
 			vendorId: PropTypes.string,
 			vendorName: PropTypes.string,
-			licensingVersion: PropTypes.string,
+			licensingVersion: PropTypes.object,
 			licensingData: PropTypes.shape({
 				licenceAgreement: PropTypes.string,
 				featureGroups: PropTypes.array
@@ -31,7 +288,6 @@ class SoftwareProductDetails extends Component {
 		onDataChanged: PropTypes.func.isRequired,
 		onValidityChanged: PropTypes.func.isRequired,
 		qdata: PropTypes.object.isRequired,
-		qschema: PropTypes.object.isRequired,
 		onQDataChanged: PropTypes.func.isRequired,
 		onVendorParamChanged: PropTypes.func.isRequired
 	};
@@ -40,161 +296,63 @@ class SoftwareProductDetails extends Component {
 		licensingVersionsList: []
 	};
 
-	render() {
-		let {softwareProductCategories, finalizedLicenseModelList, onDataChanged, featureGroupsList, licenseAgreementList, currentSoftwareProduct} = this.props;
-		let {name, description, vendorId, licensingVersion, subCategory, licensingData = {}} = currentSoftwareProduct;
+	prepareDataForGeneralSection(){
+		let {softwareProductCategories, finalizedLicenseModelList, onDataChanged, currentSoftwareProduct, genericFieldInfo} = this.props;
+		let {name, description, vendorId, subCategory} = currentSoftwareProduct;
+		return {
+			name,
+			description,
+			vendorId,
+			subCategory,
+			softwareProductCategories,
+			finalizedLicenseModelList,
+			onDataChanged,
+			onVendorParamChanged: args => this.onVendorParamChanged(args),
+			onSelectSubCategory: args => this.onSelectSubCategory(args),
+			genericFieldInfo
+		};
+
+	}
+
+	prepareDataForLicensesSection(){
+		let { featureGroupsList, licenseAgreementList, currentSoftwareProduct } = this.props;
+		let {vendorId, licensingVersion, licensingData = {}} = currentSoftwareProduct;
 		let licensingVersionsList = this.state.licensingVersionsList.length > 0 ? this.state.licensingVersionsList : this.refreshVendorVersionsList(vendorId);
-		let {qdata, qschema, onQDataChanged} = this.props;
+		return {
+			onVendorParamChanged: args => this.onVendorParamChanged(args),
+			vendorId,
+			licensingVersion,
+			licensingVersionsList,
+			licensingData,
+			onFeatureGroupsChanged: args => this.onFeatureGroupsChanged(args),
+			onLicensingDataChanged: args => this.onLicensingDataChanged(args),
+			featureGroupsList,
+			licenseAgreementList,
+		};
+
+	}
+
+	render() {
+		let {currentSoftwareProduct} = this.props;
+		let {qdata, onQDataChanged, dataMap, qGenericFieldInfo} = this.props;
 		let {isReadOnlyMode} = this.props;
 
 		return (
-			<div className='vsp-details-page'>
+		<div className='vsp-details-page'>
 				<Form
-					ref='validationForm'
+					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}>
-					<div className='section-title general'>{i18n('General')}</div>
-					<div className='vsp-general-tab-inline-section'>
-						<div className='vsp-general-tab-sub-section'>
-							<ValidationInput
-								label={i18n('Name')}
-								type='text'
-								value={name}
-								onChange={name => onDataChanged({name})}
-								validations={{validateName: true, maxLength: 120, required: true}}
-								className='field-section'/>
-							<ValidationInput
-								label={i18n('Vendor')}
-								type='select'
-								selectedEnum={vendorId}
-								onEnumChange={vendorId => this.onVendorParamChanged({vendorId})}
-								className='field-section'>
-								{finalizedLicenseModelList.map(lm => <option key={lm.id} value={lm.id}>{lm.vendorName}</option>)}
-							</ValidationInput>
-							<div className='input-row'>
-								<ValidationInput
-									label={i18n('Category')}
-									type='select'
-									selectedEnum={subCategory}
-									onEnumChange={subCategory => this.onSelectSubCategory(subCategory)}
-									className='field-section'>
-									{
-										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>
-										)
-									}
-								</ValidationInput>
-							</div>
-						</div>
-						<div className='vsp-general-tab-sub-section input-row'>
-							<ValidationInput
-								label={i18n('Description')}
-								type='textarea'
-								value={description}
-								onChange={description => onDataChanged({description})}
-								className='field-section'
-								validations={{required: true}}/>
-						</div>
-					</div>
-					<div className='vsp-general-tab-section licenses'>
-						<div className='section-title'>{i18n('Licenses')}</div>
-						<div className='vsp-general-tab-inline-section input-row'>
-							<ValidationInput
-								onEnumChange={licensingVersion => this.onVendorParamChanged({vendorId, licensingVersion})}
-								selectedEnum={licensingVersion}
-								label={i18n('Licensing Version')}
-								values={licensingVersionsList}
-								type='select'
-								className='field-section'/>
-							<ValidationInput
-								label={i18n('License Agreement')}
-								type='select'
-								selectedEnum={licensingData.licenseAgreement}
-								className='field-section'
-								onEnumChange={(licenseAgreement) => this.onLicensingDataChanged({licenseAgreement, featureGroups: []})}>
-								<option key='placeholder' value=''>{i18n('Select...')}</option>
-								{licenseAgreementList.map(la => <option value={la.id} key={la.id}>{la.name}</option>)}
-							</ValidationInput>
-						</div>
-						<div className='vsp-general-tab-inline-section input-row'>
-							{licensingData.licenseAgreement && (
-								<ValidationInput
-									type='select'
-									isMultiSelect={true}
-									onEnumChange={featureGroups => this.onFeatureGroupsChanged({featureGroups})}
-									multiSelectedEnum={licensingData.featureGroups}
-									name='feature-groups'
-									label={i18n('Feature Groups')}
-									clearable={false}
-									values={featureGroupsList}/>)
-							}
-						</div>
-					</div>
-				</Form>
-				<Form
-					data={qdata}
-					schema={qschema}
-					onDataChanged={onQDataChanged}
-					className='vsp-general-tab'
-					hasButtons={false}
-					isReadOnlyMode={isReadOnlyMode}>
-					<div className='vsp-general-tab-section'>
-						<div className='section-title'> {i18n('Availability')} </div>
-						<div className='vsp-general-tab-inline-section'>
-							<div className='vsp-general-tab-sub-section input-row'>
-								<ValidationInput
-									label={i18n('Use Availability Zones for High Availability')}
-									type='checkbox'
-									pointer='/general/availability/useAvailabilityZonesForHighAvailability'/>
-							</div>
-						</div>
-						<div className='section-title'> {i18n('Regions')} </div>
-						<div className='vsp-general-tab-inline-section'>
-							<div className='vsp-general-tab-sub-section input-row'>
-								<ValidationInput
-									type='select'
-									laebl='Ziv'
-									pointer='/general/regionsData/regions'/>
-							</div>
-						</div>
-						<div className='section-title'> {i18n('Storage Data Replication')} </div>
-						<div className='vsp-general-tab-inline-section'>
-							<div className='vsp-general-tab-sub-section'>
-								<ValidationInput
-									label={i18n('Storage Replication Size (GB)')}
-									type='text'
-									pointer='/general/storageDataReplication/storageReplicationSize'
-									className='field-section'/>
-								<ValidationInput
-									label={i18n('Storage Replication Source')}
-									type='text'
-									pointer='/general/storageDataReplication/storageReplicationSource'
-									className='field-section'/>
-							</div>
-							<div className='vsp-general-tab-sub-section'>
-								<ValidationInput
-									label={i18n('Storage Replication Frequency (minutes)')}
-									type='text'
-									pointer='/general/storageDataReplication/storageReplicationFrequency'
-									className='field-section'/>
-								<ValidationInput
-									label={i18n('Storage Replication Destination')}
-									type='text'
-									pointer='/general/storageDataReplication/storageReplicationDestination'
-									className='field-section'/>
-							</div>
-						</div>
-					</div>
+					<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>
 		);
@@ -213,7 +371,9 @@ class SoftwareProductDetails extends Component {
 			licensingVersion,
 			licensingData: {}
 		};
-		onVendorParamChanged(deltaData);
+
+		onVendorParamChanged(deltaData, forms.VENDOR_SOFTWARE_PRODUCT_DETAILS);
+
 	}
 
 	refreshVendorVersionsList(vendorId) {
@@ -229,20 +389,14 @@ class SoftwareProductDetails extends Component {
 		}];
 		if(finalVersions) {
 			finalVersions.forEach(version => licensingVersionsList.push({
-				enum: version,
-				title: version
+				enum: version.id,
+				title: version.label
 			}));
 		}
 
 		return licensingVersionsList;
 	}
 
-	onSelectSubCategory(subCategory) {
-		let {softwareProductCategories, onDataChanged} = this.props;
-		let category = SoftwareProductCategoriesHelper.getCurrentCategoryOfSubCategory(subCategory, softwareProductCategories);
-		onDataChanged({category, subCategory});
-	}
-
 	onFeatureGroupsChanged({featureGroups}) {
 		this.onLicensingDataChanged({featureGroups});
 	}
@@ -253,11 +407,17 @@ class SoftwareProductDetails extends Component {
 				...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);
 	}
 
 	save(){
-		return this.refs.validationForm.handleFormSubmit(new Event('dummy'));
+		return this.validationForm.handleFormSubmit(new Event('dummy'));
 	}
 }
 
-- 
cgit 1.2.3-korg

