2 * Copyright © 2016-2018 European Support Limited
3 * Modifications Copyright (C) 2021 Nordix Foundation.
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
14 * or implied. See the License for the specific language governing
15 * permissions and limitations under the License.
17 import React, { Component } from 'react';
18 import PropTypes from 'prop-types';
20 import i18n from 'nfvo-utils/i18n/i18n.js';
21 import sortByStringProperty from 'nfvo-utils/sortByStringProperty.js';
22 import Form from 'nfvo-components/input/validation/Form.jsx';
23 import Input from 'nfvo-components/input/validation/Input.jsx';
24 import InputOptions from 'nfvo-components/input/validation/InputOptions.jsx';
25 import GridSection from 'nfvo-components/grid/GridSection.jsx';
26 import GridItem from 'nfvo-components/grid/GridItem.jsx';
27 import SoftwareProductCategoriesHelper from 'sdc-app/onboarding/softwareProduct/SoftwareProductCategoriesHelper.js';
28 import { forms } from 'sdc-app/onboarding/softwareProduct/SoftwareProductConstants.js';
29 import { versionStatus } from 'sdc-app/common/helpers/ItemsHelperConstants.js';
31 const DeprecatedVlmInfo = ({ vendorName, onVendorRemove }) => {
33 <div className="depricated-vlm-info">
35 data-test-id="vsp-vendor-name"
37 onClick={() => onVendorRemove()}
38 label={i18n('Vendor')}
40 value={`${vendorName} (Archived)`}>
43 value={`${vendorName} (Archived)`}>{`${vendorName} (Archived)`}</option>
49 class GeneralSection extends React.Component {
51 vendorId: PropTypes.string,
52 name: PropTypes.string,
53 description: PropTypes.string,
54 subCategory: PropTypes.string,
55 selectedModelList: PropTypes.arrayOf(PropTypes.string),
56 softwareProductCategories: PropTypes.array,
57 finalizedLicenseModelList: PropTypes.array,
58 onDataChanged: PropTypes.func.isRequired,
59 onVendorParamChanged: PropTypes.func.isRequired,
60 onSelectSubCategory: PropTypes.func.isRequired,
61 isVendorArchived: PropTypes.bool,
62 onArchivedVendorRemove: PropTypes.func
65 onVendorParamChanged(e) {
66 const selectedIndex = e.target.selectedIndex;
67 const vendorId = e.target.options[selectedIndex].value;
68 this.props.onVendorParamChanged(
70 forms.VENDOR_SOFTWARE_PRODUCT_DETAILS
74 onSelectSubCategory(e) {
75 const selectedIndex = e.target.selectedIndex;
76 const subCategory = e.target.options[selectedIndex].value;
77 this.props.onSelectSubCategory(subCategory);
81 finalizedLicenseModelList,
85 this.props.onArchivedVendorRemove({
86 finalizedLicenseModelList,
93 let { genericFieldInfo } = this.props;
96 {genericFieldInfo && (
98 title={i18n('General')}
99 className="grid-section-general">
102 data-test-id="vsp-name"
106 value={this.props.name}
108 errorText={genericFieldInfo.name.errorText}
109 isValid={genericFieldInfo.name.isValid}
112 this.props.onDataChanged(
114 forms.VENDOR_SOFTWARE_PRODUCT_DETAILS
118 {this.props.isVendorArchived ? (
120 onVendorRemove={() => this.onVendorRemove()}
121 vendorName={this.props.vendorName}
125 data-test-id="vsp-vendor-name"
126 label={i18n('Vendor')}
128 value={this.props.vendorId}
130 this.onVendorParamChanged(e)
132 {sortByStringProperty(
133 this.props.finalizedLicenseModelList,
136 <option key={lm.id} value={lm.id}>
143 data-test-id="vsp-category-name"
144 label={i18n('Category')}
146 value={this.props.subCategory}
147 onChange={e => this.onSelectSubCategory(e)}>
148 {this.props.softwareProductCategories.map(
150 category.subcategories && (
153 label={category.name}>
154 {category.subcategories.map(
169 <div className="form-group">
170 <label className="control-label">
174 {this.props.selectedModelList.length > 0 ? (
176 {this.props.selectedModelList.map(
177 value => <li>{value}</li>
181 i18n('model.sdc.label')
186 <GridItem colSpan={2} stretch>
188 data-test-id="vsp-description"
189 label={i18n('Description')}
192 isValid={genericFieldInfo.description.isValid}
194 genericFieldInfo.description.errorText
196 value={this.props.description}
197 onChange={description =>
198 this.props.onDataChanged(
200 forms.VENDOR_SOFTWARE_PRODUCT_DETAILS
211 class LicensesSection extends React.Component {
213 onVendorParamChanged: PropTypes.func.isRequired,
214 vendorId: PropTypes.string,
215 licensingVersion: PropTypes.string,
216 licensingVersionsList: PropTypes.array,
217 licensingData: PropTypes.shape({
218 licenceAgreement: PropTypes.string,
219 featureGroups: PropTypes.array
221 onFeatureGroupsChanged: PropTypes.func.isRequired,
222 onLicensingDataChanged: PropTypes.func.isRequired,
223 featureGroupsList: PropTypes.array,
224 licenseAgreementList: PropTypes.array,
225 isVendorArchived: PropTypes.bool,
226 licenseType: PropTypes.string
229 onVendorParamChanged(e) {
230 const selectedIndex = e.target.selectedIndex;
231 const licensingVersion = e.target.options[selectedIndex].value;
232 this.props.onVendorParamChanged(
233 { vendorId: this.props.vendorId, licensingVersion },
234 forms.VENDOR_SOFTWARE_PRODUCT_DETAILS
238 onLicensingDataChanged(e) {
239 const selectedIndex = e.target.selectedIndex;
240 const licenseAgreement = e.target.options[selectedIndex].value;
241 this.props.onLicensingDataChanged({
249 <GridSection title={i18n('Licenses')}>
252 data-test-id="vsp-licensing-version"
253 onChange={e => this.onVendorParamChanged(e)}
254 value={this.props.licensingVersion || ''}
255 label={i18n('Licensing Version')}
257 this.props.isVendorArchived ||
258 this.props.licenseType !== 'INTERNAL'
261 {this.props.licensingVersionsList.map(version => (
262 <option key={version.enum} value={version.enum}>
270 data-test-id="vsp-license-agreement"
271 label={i18n('License Agreement')}
274 this.props.isVendorArchived ||
275 this.props.licenseType !== 'INTERNAL'
278 this.props.licensingData.licenseAgreement
279 ? this.props.licensingData.licenseAgreement
282 onChange={e => this.onLicensingDataChanged(e)}>
283 <option key="placeholder" value="">
286 {this.props.licenseAgreementList.map(la => (
287 <option value={la.id} key={la.id}>
294 {this.props.licensingData.licenseAgreement && (
296 data-test-id="vsp-feature-group"
299 onInputChange={() => {}}
301 this.props.isVendorArchived ||
302 this.props.licenseType !== 'INTERNAL'
304 onEnumChange={featureGroups =>
305 this.props.onFeatureGroupsChanged({
310 this.props.licensingData.featureGroups
312 name="feature-groups"
313 label={i18n('Feature Groups')}
315 values={this.props.featureGroupsList}
323 const AvailabilitySection = props => (
324 <GridSection title={i18n('Availability')}>
325 <GridItem colSpan={2}>
327 data-test-id="vsp-use-availability-zone"
328 label={i18n('Use Availability Zones for High Availability')}
332 'general/availability/useAvailabilityZonesForHighAvailability'
337 'general/availability/useAvailabilityZonesForHighAvailability'
341 props.onQDataChanged({
342 'general/availability/useAvailabilityZonesForHighAvailability': aZone
349 const RegionsSection = props => (
350 <GridSection title={i18n('Regions')}>
353 data-test-id="vsp-regions"
356 onInputChange={() => {}}
357 onEnumChange={regions =>
358 props.onQDataChanged({
359 'general/regionsData/regions': regions
362 multiSelectedEnum={props.dataMap['general/regionsData/regions']}
366 props.genericFieldInfo['general/regionsData/regions'].enum
372 const StorageDataReplicationSection = props => (
373 <GridSection title={i18n('Storage Data Replication')}>
376 data-test-id="vsp-storage-rep-size"
377 label={i18n('Storage Replication Size (GB)')}
380 props.genericFieldInfo[
381 'general/storageDataReplication/storageReplicationSize'
385 props.genericFieldInfo[
386 'general/storageDataReplication/storageReplicationSize'
391 'general/storageDataReplication/storageReplicationSize'
395 props.onQDataChanged({
396 'general/storageDataReplication/storageReplicationSize': sRep
403 data-test-id="vsp-storage-rep-source"
404 label={i18n('Storage Replication Source')}
407 props.genericFieldInfo[
408 'general/storageDataReplication/storageReplicationSource'
412 props.genericFieldInfo[
413 'general/storageDataReplication/storageReplicationSource'
418 'general/storageDataReplication/storageReplicationSource'
421 onChange={sRepSource =>
422 props.onQDataChanged({
423 'general/storageDataReplication/storageReplicationSource': sRepSource
430 data-test-id="vsp-storage-rep-freq"
431 label={i18n('Storage Replication Freq. (min)')}
434 props.genericFieldInfo[
435 'general/storageDataReplication/storageReplicationFrequency'
439 props.genericFieldInfo[
440 'general/storageDataReplication/storageReplicationFrequency'
445 'general/storageDataReplication/storageReplicationFrequency'
448 onChange={sRepFreq =>
449 props.onQDataChanged({
450 'general/storageDataReplication/storageReplicationFrequency': sRepFreq
457 data-test-id="vsp-storage-rep-dest"
458 label={i18n('Storage Replication Destination')}
461 props.genericFieldInfo[
462 'general/storageDataReplication/storageReplicationDestination'
466 props.genericFieldInfo[
467 'general/storageDataReplication/storageReplicationDestination'
472 'general/storageDataReplication/storageReplicationDestination'
475 onChange={sRepDest =>
476 props.onQDataChanged({
477 'general/storageDataReplication/storageReplicationDestination': sRepDest
485 class SoftwareProductDetails extends Component {
487 vendorName: PropTypes.string,
488 currentSoftwareProduct: PropTypes.shape({
489 id: PropTypes.string,
490 name: PropTypes.string,
491 description: PropTypes.string,
492 category: PropTypes.string,
493 subCategory: PropTypes.string,
494 vendorId: PropTypes.string,
495 vendorName: PropTypes.string,
496 licensingVersion: PropTypes.string,
497 licenseType: PropTypes.string,
498 licensingData: PropTypes.shape({
499 licenceAgreement: PropTypes.string,
500 featureGroups: PropTypes.array
503 softwareProductCategories: PropTypes.array,
504 finalizedLicenseModelList: PropTypes.array,
505 licenseAgreementList: PropTypes.array,
506 featureGroupsList: PropTypes.array,
507 onSubmit: PropTypes.func.isRequired,
508 onDataChanged: PropTypes.func.isRequired,
509 onValidityChanged: PropTypes.func.isRequired,
510 qdata: PropTypes.object.isRequired,
511 onQDataChanged: PropTypes.func.isRequired,
512 onVendorParamChanged: PropTypes.func.isRequired
515 prepareDataForGeneralSection() {
517 softwareProductCategories,
518 finalizedLicenseModelList,
520 currentSoftwareProduct,
523 onArchivedVendorRemove
531 selectedModelList = []
532 } = currentSoftwareProduct;
538 softwareProductCategories,
539 finalizedLicenseModelList,
541 onVendorParamChanged: args => this.onVendorParamChanged(args),
542 onSelectSubCategory: args => this.onSelectSubCategory(args),
547 onArchivedVendorRemove
551 prepareDataForLicensesSection() {
554 licenseAgreementList,
555 currentSoftwareProduct,
563 } = currentSoftwareProduct;
565 onVendorParamChanged: args => this.onVendorParamChanged(args),
568 licensingVersionsList: this.buildLicensingVersionsListItems(),
570 onFeatureGroupsChanged: args => this.onFeatureGroupsChanged(args),
571 onLicensingDataChanged: args => this.onLicensingDataChanged(args),
573 licenseAgreementList,
580 let { currentSoftwareProduct } = this.props;
581 let { qdata, onQDataChanged, dataMap, qGenericFieldInfo } = this.props;
582 let { isReadOnlyMode } = this.props;
585 <div className="vsp-details-page">
587 ref={validationForm =>
588 (this.validationForm = validationForm)
590 className="vsp-general-tab"
593 isValid={this.props.isFormValid}
595 this.props.onSubmit(currentSoftwareProduct, qdata)
597 onValidityChanged={isValidityData =>
598 this.props.onValidityChanged(isValidityData)
600 isReadOnlyMode={isReadOnlyMode}>
601 <GeneralSection {...this.prepareDataForGeneralSection()} />
603 {...this.prepareDataForLicensesSection()}
606 onQDataChanged={onQDataChanged}
610 onQDataChanged={onQDataChanged}
612 genericFieldInfo={qGenericFieldInfo}
614 <StorageDataReplicationSection
615 onQDataChanged={onQDataChanged}
617 genericFieldInfo={qGenericFieldInfo}
624 onVendorParamChanged({ vendorId, licensingVersion }) {
625 let { finalizedLicenseModelList, onVendorParamChanged } = this.props;
626 if (!licensingVersion) {
627 const licensingVersionsList = this.buildLicensingVersionsListItems();
628 licensingVersion = licensingVersionsList[0].enum;
632 vendorId = finalizedLicenseModelList[0].id;
636 finalizedLicenseModelList.find(
637 licenseModelItem => licenseModelItem.id === vendorId
646 onVendorParamChanged(deltaData, forms.VENDOR_SOFTWARE_PRODUCT_DETAILS);
649 buildLicensingVersionsListItems() {
650 let { licensingVersionsList } = this.props;
652 let licensingVersionsListItems = [
655 title: i18n('Select...')
659 return licensingVersionsListItems.concat(
660 licensingVersionsList
661 .filter(item => item.status === versionStatus.CERTIFIED)
669 onFeatureGroupsChanged({ featureGroups }) {
670 this.onLicensingDataChanged({ featureGroups });
673 onLicensingDataChanged(deltaData) {
674 this.props.onDataChanged(
677 ...this.props.currentSoftwareProduct.licensingData,
681 forms.VENDOR_SOFTWARE_PRODUCT_DETAILS
685 onSelectSubCategory(subCategory) {
686 let { softwareProductCategories, onDataChanged } = this.props;
687 let category = SoftwareProductCategoriesHelper.getCurrentCategoryOfSubCategory(
689 softwareProductCategories
692 { category, subCategory },
693 forms.VENDOR_SOFTWARE_PRODUCT_DETAILS
698 return this.validationForm.handleFormSubmit(new Event('dummy'));
702 export default SoftwareProductDetails;