c9693d4f930575af76701225d6210f9dc1965150
[sdc.git] /
1 /*!
2  * Copyright Â© 2016-2018 European Support Limited
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16 import React from 'react';
17 import PropTypes from 'prop-types';
18 import i18n from 'nfvo-utils/i18n/i18n.js';
19 import Validator from 'nfvo-utils/Validator.js';
20 import Input from 'nfvo-components/input/validation/Input.jsx';
21 import Form from 'nfvo-components/input/validation/Form.jsx';
22 import GridSection from 'nfvo-components/grid/GridSection.jsx';
23 import GridItem from 'nfvo-components/grid/GridItem.jsx';
24
25 import { SP_CREATION_FORM_NAME } from './SoftwareProductCreationConstants.js';
26 import sortByStringProperty from 'nfvo-utils/sortByStringProperty.js';
27
28 import SoftwareProductCategoriesHelper from 'sdc-app/onboarding/softwareProduct/SoftwareProductCategoriesHelper.js';
29 import { onboardingMethod as onboardingMethodConst } from '../SoftwareProductConstants.js';
30
31 const SoftwareProductPropType = PropTypes.shape({
32     id: PropTypes.string,
33     name: PropTypes.string,
34     description: PropTypes.string,
35     category: PropTypes.string,
36     subCategory: PropTypes.string,
37     vendorId: PropTypes.string
38 });
39
40 class SoftwareProductCreationView extends React.Component {
41     static propTypes = {
42         data: SoftwareProductPropType,
43         finalizedLicenseModelList: PropTypes.array,
44         softwareProductCategories: PropTypes.array,
45         VSPNames: PropTypes.object,
46         usersList: PropTypes.array,
47         onDataChanged: PropTypes.func.isRequired,
48         onSubmit: PropTypes.func.isRequired,
49         onCancel: PropTypes.func.isRequired
50     };
51
52     render() {
53         let {
54             softwareProductCategories,
55             data = {},
56             onDataChanged,
57             onCancel,
58             genericFieldInfo,
59             disableVendor
60         } = this.props;
61         let {
62             name,
63             description,
64             vendorId,
65             subCategory,
66             onboardingMethod
67         } = data;
68
69         const vendorList = this.getVendorList();
70         return (
71             <div className="software-product-creation-page">
72                 {genericFieldInfo && (
73                     <Form
74                         ref={validationForm =>
75                             (this.validationForm = validationForm)
76                         }
77                         hasButtons={true}
78                         onSubmit={() => this.submit()}
79                         onReset={() => onCancel()}
80                         labledButtons={true}
81                         isValid={this.props.isFormValid}
82                         submitButtonText={i18n('Create')}
83                         formReady={this.props.formReady}
84                         onValidateForm={() => this.validate()}>
85                         <GridSection hasLastColSet>
86                             <GridItem colSpan="2">
87                                 <Input
88                                     value={name}
89                                     label={i18n('Name')}
90                                     isRequired={true}
91                                     onChange={name =>
92                                         onDataChanged(
93                                             { name },
94                                             SP_CREATION_FORM_NAME
95                                         )
96                                     }
97                                     onBlur={this.validateIsNameUnique}
98                                     isValid={genericFieldInfo.name.isValid}
99                                     errorText={genericFieldInfo.name.errorText}
100                                     type="text"
101                                     className="field-section"
102                                     data-test-id="new-vsp-name"
103                                 />
104                                 <Input
105                                     label={i18n('Vendor')}
106                                     type="select"
107                                     value={vendorId}
108                                     overlayPos="bottom"
109                                     isRequired={true}
110                                     disabled={disableVendor}
111                                     onChange={e => this.onSelectVendor(e)}
112                                     isValid={genericFieldInfo.vendorId.isValid}
113                                     errorText={
114                                         genericFieldInfo.vendorId.errorText
115                                     }
116                                     className="input-options-select"
117                                     groupClassName="bootstrap-input-options"
118                                     data-test-id="new-vsp-vendor">
119                                     {vendorList.map(vendor => (
120                                         <option
121                                             key={vendor.title}
122                                             value={vendor.enum}>
123                                             {vendor.title}
124                                         </option>
125                                     ))}
126                                 </Input>
127                                 <Input
128                                     label={i18n('Category')}
129                                     type="select"
130                                     value={subCategory}
131                                     isRequired={true}
132                                     onChange={e => this.onSelectSubCategory(e)}
133                                     isValid={
134                                         genericFieldInfo.subCategory.isValid
135                                     }
136                                     errorText={
137                                         genericFieldInfo.subCategory.errorText
138                                     }
139                                     className="input-options-select"
140                                     groupClassName="bootstrap-input-options"
141                                     data-test-id="new-vsp-category">
142                                     <option key="" value="">
143                                         {i18n('please select…')}
144                                     </option>
145                                     {softwareProductCategories.map(
146                                         category =>
147                                             category.subcategories && (
148                                                 <optgroup
149                                                     key={category.name}
150                                                     label={category.name}>
151                                                     {category.subcategories.map(
152                                                         sub => (
153                                                             <option
154                                                                 key={
155                                                                     sub.uniqueId
156                                                                 }
157                                                                 value={
158                                                                     sub.uniqueId
159                                                                 }>{`${
160                                                                 sub.name
161                                                             } (${
162                                                                 category.name
163                                                             })`}</option>
164                                                         )
165                                                     )}
166                                                 </optgroup>
167                                             )
168                                     )}
169                                 </Input>
170                             </GridItem>
171                             <GridItem colSpan="2" stretch lastColInRow>
172                                 <Input
173                                     value={description}
174                                     label={i18n('Description')}
175                                     isRequired={true}
176                                     overlayPos="bottom"
177                                     onChange={description =>
178                                         onDataChanged(
179                                             { description },
180                                             SP_CREATION_FORM_NAME
181                                         )
182                                     }
183                                     isValid={
184                                         genericFieldInfo.description.isValid
185                                     }
186                                     errorText={
187                                         genericFieldInfo.description.errorText
188                                     }
189                                     type="textarea"
190                                     className="field-section"
191                                     data-test-id="new-vsp-description"
192                                 />
193                             </GridItem>
194                         </GridSection>
195                         <OnboardingProcedure
196                             genericFieldInfo={genericFieldInfo}
197                             onboardingMethod={onboardingMethod}
198                             onDataChanged={onDataChanged}
199                         />
200                     </Form>
201                 )}
202             </div>
203         );
204     }
205
206     getVendorList() {
207         let { vendorList } = this.props;
208
209         return [{ enum: '', title: i18n('please select...') }].concat(
210             sortByStringProperty(vendorList, 'name').map(vendor => {
211                 return {
212                     enum: vendor.id,
213                     title: vendor.name
214                 };
215             })
216         );
217     }
218
219     onSelectVendor(e) {
220         const selectedIndex = e.target.selectedIndex;
221         const vendorId = e.target.options[selectedIndex].value;
222         this.props.onDataChanged({ vendorId }, SP_CREATION_FORM_NAME);
223     }
224
225     onSelectSubCategory(e) {
226         const selectedIndex = e.target.selectedIndex;
227         const subCategory = e.target.options[selectedIndex].value;
228         let { softwareProductCategories, onDataChanged } = this.props;
229         let category = SoftwareProductCategoriesHelper.getCurrentCategoryOfSubCategory(
230             subCategory,
231             softwareProductCategories
232         );
233         onDataChanged({ category, subCategory }, SP_CREATION_FORM_NAME);
234     }
235
236     submit() {
237         let {
238             data: softwareProduct,
239             finalizedLicenseModelList,
240             usersList
241         } = this.props;
242         softwareProduct.vendorName = finalizedLicenseModelList.find(
243             vendor => vendor.id === softwareProduct.vendorId
244         ).name;
245         this.props.onSubmit(softwareProduct, usersList);
246     }
247
248     validateName(value) {
249         const { data: { id }, VSPNames } = this.props;
250         const isExists = Validator.isItemNameAlreadyExistsInList({
251             itemId: id,
252             itemName: value,
253             list: VSPNames
254         });
255
256         return !isExists
257             ? { isValid: true, errorText: '' }
258             : {
259                   isValid: false,
260                   errorText: i18n(
261                       "Software product by the name '" +
262                           value +
263                           "' already exists. Software product name must be unique"
264                   )
265               };
266     }
267
268     validateIsNameUnique = e => {
269         const value = e.target.value;
270         if (value) {
271             this.props.isNameUnique(value, 'name', SP_CREATION_FORM_NAME);
272         }
273     };
274
275     validate() {
276         this.props.onValidateForm(SP_CREATION_FORM_NAME);
277     }
278 }
279
280 const OnboardingProcedure = ({
281     onboardingMethod,
282     onDataChanged,
283     genericFieldInfo
284 }) => {
285     return (
286         <GridSection title={i18n('Onboarding procedure')}>
287             <GridItem colSpan={4}>
288                 <Input
289                     label={i18n('Network Package')}
290                     overlayPos="top"
291                     checked={
292                         onboardingMethod ===
293                         onboardingMethodConst.NETWORK_PACKAGE
294                     }
295                     errorText={genericFieldInfo.onboardingMethod.errorText}
296                     onChange={() =>
297                         onDataChanged(
298                             {
299                                 onboardingMethod:
300                                     onboardingMethodConst.NETWORK_PACKAGE
301                             },
302                             SP_CREATION_FORM_NAME
303                         )
304                     }
305                     type="radio"
306                     data-test-id="new-vsp-creation-procedure-heat"
307                 />
308             </GridItem>
309             <GridItem colSpan={4}>
310                 <Input
311                     label={i18n('Manual')}
312                     overlayPos="bottom"
313                     checked={onboardingMethod === onboardingMethodConst.MANUAL}
314                     isValid={genericFieldInfo.onboardingMethod.isValid}
315                     errorText={genericFieldInfo.onboardingMethod.errorText}
316                     onChange={() =>
317                         onDataChanged(
318                             { onboardingMethod: onboardingMethodConst.MANUAL },
319                             SP_CREATION_FORM_NAME
320                         )
321                     }
322                     type="radio"
323                     data-test-id="new-vsp-creation-procedure-manual"
324                 />
325             </GridItem>
326         </GridSection>
327     );
328 };
329
330 export default SoftwareProductCreationView;