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 from 'react';
18 import PropTypes, { string } from 'prop-types';
19 import i18n from 'nfvo-utils/i18n/i18n.js';
20 import Validator from 'nfvo-utils/Validator.js';
21 import Input from 'nfvo-components/input/validation/Input.jsx';
22 import Form from 'nfvo-components/input/validation/Form.jsx';
23 import GridSection from 'nfvo-components/grid/GridSection.jsx';
24 import GridItem from 'nfvo-components/grid/GridItem.jsx';
26 import { SP_CREATION_FORM_NAME } from './SoftwareProductCreationConstants.js';
27 import sortByStringProperty from 'nfvo-utils/sortByStringProperty.js';
29 import SoftwareProductCategoriesHelper from 'sdc-app/onboarding/softwareProduct/SoftwareProductCategoriesHelper.js';
32 onboardingMethod as onboardingMethodConst
33 } from '../SoftwareProductConstants.js';
34 import SelectInput from 'nfvo-components/input/SelectInput.jsx';
36 const SoftwareProductPropType = PropTypes.shape({
38 name: PropTypes.string,
39 description: PropTypes.string,
40 category: PropTypes.string,
41 subCategory: PropTypes.string,
42 vendorId: PropTypes.string,
43 selectedModelList: PropTypes.arrayOf(string)
46 class SoftwareProductCreationView extends React.Component {
48 data: SoftwareProductPropType,
49 finalizedLicenseModelList: PropTypes.array,
50 softwareProductCategories: PropTypes.array,
51 VSPNames: PropTypes.object,
52 usersList: PropTypes.array,
53 modelList: PropTypes.array,
54 onDataChanged: PropTypes.func.isRequired,
55 onSubmit: PropTypes.func.isRequired,
56 onCancel: PropTypes.func.isRequired
61 softwareProductCategories,
79 const vendorList = this.getVendorList();
81 <div className="software-product-creation-page">
82 {genericFieldInfo && (
84 ref={validationForm =>
85 (this.validationForm = validationForm)
88 onSubmit={() => this.submit()}
89 onReset={() => onCancel()}
91 isValid={this.props.isFormValid}
92 submitButtonText={i18n('Create')}
93 formReady={this.props.formReady}
94 btnClassName="sdc-modal__footer"
95 onValidateForm={() => this.validate()}>
96 <GridSection hasLastColSet>
97 <GridItem colSpan="2">
105 SP_CREATION_FORM_NAME
108 onBlur={this.validateIsNameUnique}
109 isValid={genericFieldInfo.name.isValid}
110 errorText={genericFieldInfo.name.errorText}
112 className="field-section"
113 data-test-id="new-vsp-name"
116 label={i18n('Vendor')}
121 disabled={disableVendor}
122 onChange={e => this.onSelectVendor(e)}
123 isValid={genericFieldInfo.vendorId.isValid}
125 genericFieldInfo.vendorId.errorText
127 className="input-options-select"
128 groupClassName="bootstrap-input-options"
129 data-test-id="new-vsp-vendor">
130 {vendorList.map(vendor => (
139 label={i18n('Category')}
143 onChange={e => this.onSelectSubCategory(e)}
145 genericFieldInfo.subCategory.isValid
148 genericFieldInfo.subCategory.errorText
150 className="input-options-select"
151 groupClassName="bootstrap-input-options"
152 data-test-id="new-vsp-category">
153 <option key="" value="">
154 {i18n('please select…')}
156 {softwareProductCategories.map(
158 category.subcategories && (
161 label={category.name}>
162 {category.subcategories.map(
182 <GridItem colSpan="2" stretch lastColInRow>
185 label={i18n('Description')}
188 onChange={description =>
191 SP_CREATION_FORM_NAME
195 genericFieldInfo.description.isValid
198 genericFieldInfo.description.errorText
201 className="field-section"
202 data-test-id="new-vsp-description"
207 <GridItem colSpan={2}>
209 genericFieldInfo={genericFieldInfo}
210 onboardingMethod={onboardingMethod}
211 onDataChanged={onDataChanged}
214 <GridItem colSpan={2}>
216 genericFieldInfo={genericFieldInfo}
217 modelOption={modelOption}
218 modelList={modelList}
219 selectedModelList={selectedModelList}
220 onDataChanged={onDataChanged}
231 let { vendorList } = this.props;
233 return [{ enum: '', title: i18n('please select...') }].concat(
234 sortByStringProperty(vendorList, 'name').map(vendor => {
244 const selectedIndex = e.target.selectedIndex;
245 const vendorId = e.target.options[selectedIndex].value;
246 this.props.onDataChanged({ vendorId }, SP_CREATION_FORM_NAME);
249 onSelectSubCategory(e) {
250 const selectedIndex = e.target.selectedIndex;
251 const subCategory = e.target.options[selectedIndex].value;
252 let { softwareProductCategories, onDataChanged } = this.props;
253 let category = SoftwareProductCategoriesHelper.getCurrentCategoryOfSubCategory(
255 softwareProductCategories
257 onDataChanged({ category, subCategory }, SP_CREATION_FORM_NAME);
261 let { finalizedLicenseModelList, usersList } = this.props;
262 const softwareProduct = { ...this.props.data };
263 softwareProduct.vendorName = finalizedLicenseModelList.find(
264 vendor => vendor.id === softwareProduct.vendorId
266 delete softwareProduct.modelOption;
267 this.props.onSubmit(softwareProduct, usersList);
270 validateName(value) {
271 const { data: { id }, VSPNames } = this.props;
272 const isExists = Validator.isItemNameAlreadyExistsInList({
279 ? { isValid: true, errorText: '' }
283 "Software product by the name '" +
285 "' already exists. Software product name must be unique"
290 validateIsNameUnique = e => {
291 const value = e.target.value;
293 this.props.isNameUnique(value, 'name', SP_CREATION_FORM_NAME);
298 this.props.onValidateForm(SP_CREATION_FORM_NAME);
302 const OnboardingProcedure = ({
308 <GridSection title={i18n('Onboarding procedure')} required={true}>
309 <GridItem colSpan={4}>
311 label={i18n('Network Package')}
315 onboardingMethodConst.NETWORK_PACKAGE
317 errorText={genericFieldInfo.onboardingMethod.errorText}
322 onboardingMethodConst.NETWORK_PACKAGE
324 SP_CREATION_FORM_NAME
328 data-test-id="new-vsp-creation-procedure-heat"
331 <GridItem colSpan={4}>
333 label={i18n('Manual')}
335 checked={onboardingMethod === onboardingMethodConst.MANUAL}
336 isValid={genericFieldInfo.onboardingMethod.isValid}
337 errorText={genericFieldInfo.onboardingMethod.errorText}
340 { onboardingMethod: onboardingMethodConst.MANUAL },
341 SP_CREATION_FORM_NAME
345 data-test-id="new-vsp-creation-procedure-manual"
346 groupClassName="no-bottom-margin"
353 const ModelSelection = ({
358 selectedModelList = []
360 function onSelectChanged(selectedValueList) {
362 if (selectedValueList) {
363 modelList1 = selectedValueList.map(item => item.value);
365 onDataChanged({ selectedModelList: modelList1 }, SP_CREATION_FORM_NAME);
368 function selectDefaultModel() {
371 { modelOption: ModelOption.DEFAULT },
372 SP_CREATION_FORM_NAME
374 onDataChanged({ selectedModelList: [] }, SP_CREATION_FORM_NAME);
379 <GridSection title={i18n('Model')} required={true}>
380 <GridItem colSpan={4}>
382 label={i18n('model.sdc.label')}
383 checked={modelOption === ModelOption.DEFAULT}
384 errorText={genericFieldInfo.modelOption.errorText}
385 onChange={selectDefaultModel()}
387 data-test-id="model-option-default"
390 label={i18n('vsp.model.select.label')}
391 checked={modelOption === ModelOption.SELECTED}
392 isValid={genericFieldInfo.modelOption.isValid}
393 errorText={genericFieldInfo.modelOption.errorText}
396 { modelOption: ModelOption.SELECTED },
397 SP_CREATION_FORM_NAME
401 data-test-id="model-option-selected"
402 groupClassName="no-bottom-margin"
405 <GridItem colSpan={4}>
406 {modelOption === ModelOption.SELECTED && <br />}
407 {modelOption === ModelOption.SELECTED && (
409 options={modelList.map(model => ({
413 onMultiSelectChanged={onSelectChanged}
414 value={selectedModelList}
416 placeholder={i18n('vsp.model.select.label')}
420 {modelOption === ModelOption.SELECTED && <br />}
426 export default SoftwareProductCreationView;