Add collaboration feature
[sdc.git] / openecomp-ui / src / sdc-app / onboarding / softwareProduct / creation / SoftwareProductCreationView.jsx
1 /*!
2  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
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
42         static propTypes = {
43                 data: SoftwareProductPropType,
44                 finalizedLicenseModelList: PropTypes.array,
45                 softwareProductCategories: PropTypes.array,
46                 VSPNames: PropTypes.object,
47                 usersList: PropTypes.array,
48                 onDataChanged: PropTypes.func.isRequired,
49                 onSubmit: PropTypes.func.isRequired,
50                 onCancel: PropTypes.func.isRequired
51         };
52
53         render() {
54                 let {softwareProductCategories, data = {}, onDataChanged, onCancel, genericFieldInfo, disableVendor} = this.props;
55                 let {name, description, vendorId, subCategory, onboardingMethod} = data;
56
57                 const vendorList = this.getVendorList();
58                 return (
59                         <div className='software-product-creation-page'>
60                                 { genericFieldInfo && <Form
61                                         ref={(validationForm) => this.validationForm = validationForm}
62                                         hasButtons={true}
63                                         onSubmit={() => this.submit() }
64                                         onReset={() => onCancel() }
65                                         labledButtons={true}
66                                         isValid={this.props.isFormValid}
67                                         submitButtonText={i18n('Create')}
68                                         formReady={this.props.formReady}
69                                         onValidateForm={() => this.validate() }>
70                                         <GridSection hasLastColSet>
71                                                 <GridItem colSpan='2'>
72                                                         <Input
73                                                                 value={name}
74                                                                 label={i18n('Name')}
75                                                                 isRequired={true}
76                                                                 onChange={name => onDataChanged({name},SP_CREATION_FORM_NAME, {name: name => this.validateName(name)})}
77                                                                 isValid={genericFieldInfo.name.isValid}
78                                                                 errorText={genericFieldInfo.name.errorText}
79                                                                 type='text'
80                                                                 className='field-section'
81                                                                 data-test-id='new-vsp-name' />
82                                                         <Input
83                                                                 label={i18n('Vendor')}
84                                                                 type='select'
85                                                                 value={vendorId}
86                                                                 overlayPos='bottom'
87                                                                 isRequired={true}
88                                                                 disabled={disableVendor}
89                                                                 onChange={e => this.onSelectVendor(e)}
90                                                                 isValid={genericFieldInfo.vendorId.isValid}
91                                                                 errorText={genericFieldInfo.vendorId.errorText}
92                                                                 className='input-options-select'
93                                                                 groupClassName='bootstrap-input-options'
94                                                                 data-test-id='new-vsp-vendor' >
95                                                                 {vendorList.map(vendor =>
96                                                                 <option key={vendor.title} value={vendor.enum}>{vendor.title}</option>)}
97                                                         </Input>
98                                                         <Input
99                                                                 label={i18n('Category')}
100                                                                 type='select'
101                                                                 value={subCategory}
102                                                                 isRequired={true}
103                                                                 onChange={e => this.onSelectSubCategory(e)}
104                                                                 isValid={genericFieldInfo.subCategory.isValid}
105                                                                 errorText={genericFieldInfo.subCategory.errorText}
106                                                                 className='input-options-select'
107                                                                 groupClassName='bootstrap-input-options'
108                                                                 data-test-id='new-vsp-category' >
109                                                                 <option key='' value=''>{i18n('please select…')}</option>
110                                                                 {softwareProductCategories.map(category =>
111                                                                         category.subcategories &&
112                                                                         <optgroup
113                                                                                 key={category.name}
114                                                                                 label={category.name}>{category.subcategories.map(sub =>
115                                                                                 <option key={sub.uniqueId} value={sub.uniqueId}>{`${sub.name} (${category.name})`}</option>)}
116                                                                         </optgroup>)
117                                                                 }
118                                                         </Input>
119                                                 </GridItem>
120                                                 <GridItem colSpan='2' stretch lastColInRow>
121                                                         <Input
122                                                                 value={description}
123                                                                 label={i18n('Description')}
124                                                                 isRequired={true}
125                                                                 overlayPos='bottom'
126                                                                 onChange={description => onDataChanged({description},SP_CREATION_FORM_NAME)}
127                                                                 isValid={genericFieldInfo.description.isValid}
128                                                                 errorText={genericFieldInfo.description.errorText}
129                                                                 type='textarea'
130                                                                 className='field-section'
131                                                                 data-test-id='new-vsp-description'/>
132                                                 </GridItem>
133                                         </GridSection>
134                                         <OnboardingProcedure genericFieldInfo={genericFieldInfo} onboardingMethod={onboardingMethod} onDataChanged={onDataChanged} />
135                                 </Form>}
136                         </div>
137                 );
138         }
139
140         getVendorList() {
141                 let {finalizedLicenseModelList} =  this.props;
142
143                 return [{enum: '', title: i18n('please select...')}].concat(
144                         sortByStringProperty(finalizedLicenseModelList, 'name').map(vendor => {
145                                 return {
146                                         enum: vendor.id,
147                                         title: vendor.name
148                                 };
149                         })
150                 );
151         }
152
153         onSelectVendor(e) {
154                 const selectedIndex = e.target.selectedIndex;
155                 const vendorId = e.target.options[selectedIndex].value;
156                 this.props.onDataChanged({vendorId},SP_CREATION_FORM_NAME);
157         }
158
159         onSelectSubCategory(e) {
160                 const selectedIndex = e.target.selectedIndex;
161                 const subCategory = e.target.options[selectedIndex].value;
162                 let {softwareProductCategories, onDataChanged} = this.props;
163                 let category = SoftwareProductCategoriesHelper.getCurrentCategoryOfSubCategory(subCategory, softwareProductCategories);
164                 onDataChanged({category, subCategory},SP_CREATION_FORM_NAME);
165         }
166
167         submit() {
168                 let  {data:softwareProduct, finalizedLicenseModelList, usersList} = this.props;
169                 softwareProduct.vendorName = finalizedLicenseModelList.find(vendor => vendor.id === softwareProduct.vendorId).name;
170                 this.props.onSubmit(softwareProduct, usersList);
171         }
172
173         validateName(value) {
174                 const {data: {id}, VSPNames} = this.props;
175                 const isExists = Validator.isItemNameAlreadyExistsInList({itemId: id, itemName: value, list: VSPNames});
176
177                 return !isExists ?  {isValid: true, errorText: ''} :
178                         {isValid: false, errorText: i18n('Software product by the name \'' + value + '\' already exists. Software product name must be unique')};
179         }
180
181         validate() {
182                 this.props.onValidateForm(SP_CREATION_FORM_NAME);
183         }
184 }
185
186 const OnboardingProcedure = ({onboardingMethod, onDataChanged, genericFieldInfo}) => {
187         return(
188                 <GridSection title={i18n('Onboarding procedure')}>
189                         <GridItem colSpan={4}>
190                                 <Input
191                                         label={i18n('Network Package')}
192                                         overlayPos='top'
193                                         isValid={genericFieldInfo.onboardingMethod.isValid}
194                                         checked={onboardingMethod === onboardingMethodConst.NETWORK_PACKAGE}
195                                         errorText={genericFieldInfo.onboardingMethod.errorText}
196                                         onChange={() => onDataChanged({onboardingMethod: onboardingMethodConst.NETWORK_PACKAGE},SP_CREATION_FORM_NAME)}
197                                         type='radio'
198                                         data-test-id='new-vsp-creation-procedure-heat' />
199                         </GridItem>
200                         <GridItem colSpan={4}>
201                                 <Input
202                                         label={i18n('Manual')}
203                                         overlayPos='bottom'
204                                         checked={onboardingMethod === onboardingMethodConst.MANUAL}
205                                         isValid={genericFieldInfo.onboardingMethod.isValid}
206                                         errorText={genericFieldInfo.onboardingMethod.errorText}
207                                         onChange={() => onDataChanged({onboardingMethod: onboardingMethodConst.MANUAL},SP_CREATION_FORM_NAME)}
208                                         type='radio'
209                                         data-test-id='new-vsp-creation-procedure-manual' />
210                         </GridItem>
211                 </GridSection>
212         );
213 };
214
215 export default SoftwareProductCreationView;