Merge "Replace FileUtils.toByteArray() with IOUtils"
[sdc.git] / openecomp-ui / src / sdc-app / onboarding / licenseModel / entitlementPools / EntitlementPoolsEditorView.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
18 import i18n from 'nfvo-utils/i18n/i18n.js';
19 import Validator from 'nfvo-utils/Validator.js';
20
21 import Input from 'nfvo-components/input/validation/Input.jsx';
22 import InputOptions from 'nfvo-components/input/validation/InputOptions.jsx';
23 import Form from 'nfvo-components/input/validation/Form.jsx';
24 import Button from 'sdc-ui/lib/react/Button.js';
25 import GridSection from 'nfvo-components/grid/GridSection.jsx';
26 import GridItem from 'nfvo-components/grid/GridItem.jsx';
27 import {optionsInputValues as  EntitlementPoolsOptionsInputValues, SP_ENTITLEMENT_POOL_FORM, tabIds}  from  './EntitlementPoolsConstants.js';
28 import {optionsInputValues as LicenseModelOptionsInputValues} from '../LicenseModelConstants.js';
29 import {validateStartDate, thresholdValueValidation} from '../LicenseModelValidations.js';
30 import {DATE_FORMAT} from 'sdc-app/onboarding/OnboardingConstants.js';
31 import {other as optionInputOther} from 'nfvo-components/input/validation/InputOptions.jsx';
32 import Tabs from 'sdc-ui/lib/react/Tabs.js';
33 import Tab from 'sdc-ui/lib/react/Tab.js';
34 import EntitlementPoolsLimits from './EntitlementPoolsLimits.js';
35 import {limitType, NEW_LIMIT_TEMP_ID} from '../limits/LimitEditorConstants.js';
36
37 const EntitlementPoolPropType = React.PropTypes.shape({
38         id: React.PropTypes.string,
39         name: React.PropTypes.string,
40         description: React.PropTypes.string,
41         operationalScope: React.PropTypes.shape({
42                 choices: React.PropTypes.array,
43                 other: React.PropTypes.string
44         }),
45         thresholdUnits: React.PropTypes.string,
46         thresholdValue: React.PropTypes.number,
47         increments: React.PropTypes.string,
48         startDate: React.PropTypes.string,
49         expiryDate: React.PropTypes.string
50 });
51
52 const EntitlementPoolsFormContent = ({data, genericFieldInfo, onDataChanged, validateName,
53          thresholdValueValidation, validateStartDate}) => {
54
55         let {name, description, operationalScope, thresholdUnits, thresholdValue,
56                 increments, startDate, expiryDate} = data;
57         return (
58                 <GridSection>
59                         <GridItem colSpan={2}>
60                                 <Input
61                                         onChange={name => onDataChanged({name}, SP_ENTITLEMENT_POOL_FORM, {name: validateName})}
62                                         isValid={genericFieldInfo.name.isValid}
63                                         isRequired={true}
64                                         errorText={genericFieldInfo.name.errorText}
65                                         label={i18n('Name')}
66                                         value={name}
67                                         data-test-id='create-ep-name'
68                                         type='text'/>
69                         </GridItem>
70                         <GridItem colSpan={2}>
71                                 <InputOptions
72                                         onInputChange={()=>{}}
73                                         isMultiSelect={true}
74                                         onEnumChange={operationalScope => onDataChanged({operationalScope:{choices: operationalScope, other: ''}},
75                                                 SP_ENTITLEMENT_POOL_FORM)}
76                                         onOtherChange={operationalScope => onDataChanged({operationalScope:{choices: [optionInputOther.OTHER],
77                                                 other: operationalScope}}, SP_ENTITLEMENT_POOL_FORM)}
78                                         label={i18n('Operational Scope')}
79                                         data-test-id='create-ep-operational-scope'
80                                         type='select'
81                                         multiSelectedEnum={operationalScope && operationalScope.choices}
82                                         otherValue={operationalScope && operationalScope.other}
83                                         values={EntitlementPoolsOptionsInputValues.OPERATIONAL_SCOPE}
84                                         isValid={genericFieldInfo.operationalScope.isValid}
85                                         errorText={genericFieldInfo.operationalScope.errorText} />
86                         </GridItem>
87                         <GridItem colSpan={2} stretch>
88                                 <Input
89                                         onChange={description => onDataChanged({description}, SP_ENTITLEMENT_POOL_FORM)}
90                                         isValid={genericFieldInfo.description.isValid}
91                                         errorText={genericFieldInfo.description.errorText}
92                                         label={i18n('Description')}
93                                         value={description}
94                                         data-test-id='create-ep-description'
95                                         type='textarea'/>
96                         </GridItem>
97                         <GridItem colSpan={2}>
98                                 <div className='threshold-section'>
99                                         <Input
100                                                 onChange={e => {
101                                                         // setting the unit to the correct value
102                                                         const selectedIndex = e.target.selectedIndex;
103                                                         const val = e.target.options[selectedIndex].value;
104                                                         onDataChanged({thresholdUnits: val}, SP_ENTITLEMENT_POOL_FORM);
105                                                         // TODO make sure that the value is valid too
106                                                         if(thresholdValue && thresholdValue !== '') {
107                                                                 onDataChanged({thresholdValue: thresholdValue}, SP_ENTITLEMENT_POOL_FORM,{thresholdValue : thresholdValueValidation});
108                                                         }}
109
110                                                 }
111                                                 value={thresholdUnits}
112                                                 label={i18n('Threshold Units')}
113                                                 data-test-id='create-ep-threshold-units'
114                                                 isValid={genericFieldInfo.thresholdUnits.isValid}
115                                                 errorText={genericFieldInfo.thresholdUnits.errorText}
116                                                 groupClassName='bootstrap-input-options'
117                                                 className='input-options-select'
118                                                 type='select' >
119                                                 {LicenseModelOptionsInputValues.THRESHOLD_UNITS.map(mtype =>
120                                                         <option key={mtype.enum} value={mtype.enum}>{`${mtype.title}`}</option>)}
121                                         </Input>
122
123                                         <Input
124                                                 className='entitlement-pools-form-row-threshold-value'
125                                                 onChange={thresholdValue => onDataChanged({thresholdValue}, SP_ENTITLEMENT_POOL_FORM,
126                                                         {thresholdValue : thresholdValueValidation})}
127                                                 label={i18n('Threshold Value')}
128                                                 isValid={genericFieldInfo.thresholdValue.isValid}
129                                                 errorText={genericFieldInfo.thresholdValue.errorText}
130                                                 data-test-id='create-ep-threshold-value'
131                                                 value={thresholdValue}
132                                                 type='text'/>
133                                 </div>
134                                 <Input
135                                         onChange={increments => onDataChanged({increments}, SP_ENTITLEMENT_POOL_FORM)}
136                                         label={i18n('Increments')}
137                                         value={increments}
138                                         data-test-id='create-ep-increments'
139                                         type='text'/>
140                                 <div className='date-section'>
141                                         <Input
142                                                 type='date'
143                                                 label={i18n('Start Date')}
144                                                 value={startDate}
145                                                 dateFormat={DATE_FORMAT}
146                                                 startDate={startDate}
147                                                 endDate={expiryDate}
148                                                 onChange={startDate => onDataChanged(
149                                                         {startDate: startDate ? startDate.format(DATE_FORMAT) : ''},
150                                                         SP_ENTITLEMENT_POOL_FORM,
151                                                         {startDate: validateStartDate}
152                                                 )}
153                                                 isValid={genericFieldInfo.startDate.isValid}
154                                                 errorText={genericFieldInfo.startDate.errorText}
155                                                 selectsStart/>  
156                                         <Input
157                                                 type='date'
158                                                 label={i18n('Expiry Date')}
159                                                 value={expiryDate}
160                                                 dateFormat={DATE_FORMAT}
161                                                 startDate={startDate}
162                                                 endDate={expiryDate}
163                                                 onChange={expiryDate => {
164                                                         onDataChanged({expiryDate: expiryDate ? expiryDate.format(DATE_FORMAT) : ''}, SP_ENTITLEMENT_POOL_FORM);
165                                                         onDataChanged({startDate}, SP_ENTITLEMENT_POOL_FORM, {startDate: validateStartDate});
166                                                 }}
167                                                 isValid={genericFieldInfo.expiryDate.isValid}
168                                                 errorText={genericFieldInfo.expiryDate.errorText}
169                                                 selectsEnd/>
170                                 </div>                                                  
171                         </GridItem>                                                                     
172                 </GridSection>
173         );
174 };
175
176 class EntitlementPoolsEditorView extends React.Component {
177
178         static propTypes = {
179                 data: EntitlementPoolPropType,
180                 previousData: EntitlementPoolPropType,
181                 EPNames: React.PropTypes.object,
182                 isReadOnlyMode: React.PropTypes.bool,
183                 onDataChanged: React.PropTypes.func.isRequired,
184                 onSubmit: React.PropTypes.func.isRequired,
185                 onCancel: React.PropTypes.func.isRequired
186         };
187
188         static defaultProps = {
189                 data: {}
190         };
191
192         componentDidUpdate(prevProps) {                         
193                 if (this.props.formReady && this.props.formReady !== prevProps.formReady) { // if form validation succeeded -> continue with submit
194                         this.submit();
195                 }
196         }
197         
198         state = {               
199                 selectedTab: tabIds.GENERAL,
200                 selectedLimit: ''
201         };
202
203         render() {
204                 let {data = {}, onDataChanged, isReadOnlyMode, genericFieldInfo, onCloseLimitEditor, limitsList = []} = this.props;
205                 const {selectedTab} = this.state;
206                 const isTabsDisabled = !data.id || !this.props.isFormValid;
207
208                 return (
209                         <div>
210                         <Tabs 
211                                 type='menu' 
212                                 activeTab={selectedTab} 
213                                 onTabClick={(tabIndex)=>{
214                                         if (tabIndex === tabIds.ADD_LIMIT_BUTTON)  {
215                                                 this.onAddLimit();
216                                         } else {
217                                                 this.setState({selectedTab: tabIndex});
218                                                 this.setState({selectedLimit: ''});
219                                                 onCloseLimitEditor();
220                                         }
221                                         
222                                 }} 
223                                 invalidTabs={[]}>
224                                 <Tab tabId={tabIds.GENERAL} data-test-id='general-tab' title={i18n('General')}>
225                                         {
226                                                 genericFieldInfo && <Form
227                                                         ref='validationForm'
228                                                         hasButtons={false}                                              
229                                                         labledButtons={false}
230                                                         isReadOnlyMode={isReadOnlyMode}
231                                                         isValid={this.props.isFormValid}
232                                                         formReady={this.props.formReady}
233                                                         onValidateForm={() => this.props.onValidateForm(SP_ENTITLEMENT_POOL_FORM) }
234                                                         className='license-model-form entitlement-pools-form'>
235                                                         <EntitlementPoolsFormContent
236                                                                 data={data}
237                                                                 genericFieldInfo={genericFieldInfo}
238                                                                 onDataChanged={onDataChanged}
239                                                                 validateName={(value) => this.validateName(value)}
240                                                                 validateStartDate={(value, state) => validateStartDate(value, state)}
241                                                                 thresholdValueValidation={(value, state) => thresholdValueValidation(value, state)}/>
242                                                 </Form>
243                                         }
244                                 </Tab>
245                                 <Tab disabled={isTabsDisabled} tabId={tabIds.SP_LIMITS} data-test-id='sp-limits-tab' title={i18n('SP Limits')}>
246                                         {selectedTab === tabIds.SP_LIMITS && 
247                                                 <EntitlementPoolsLimits 
248                                                         limitType={limitType.SERVICE_PROVIDER} 
249                                                         limitsList={limitsList.filter(item => item.type === limitType.SERVICE_PROVIDER)}
250                                                         selectedLimit={this.state.selectedLimit}
251                                                         onCloseLimitEditor={() => this.onCloseLimitEditor()}
252                                                         onSelectLimit={limit => this.onSelectLimit(limit)}/>}
253                                 </Tab>
254                                 <Tab disabled={isTabsDisabled} tabId={tabIds.VENDOR_LIMITS} data-test-id='vendor-limits-tab' title={i18n('Vendor Limits')}>
255                                         {selectedTab === tabIds.VENDOR_LIMITS && 
256                                                 <EntitlementPoolsLimits 
257                                                         limitType={limitType.VENDOR} 
258                                                         limitsList={limitsList.filter(item => item.type === limitType.VENDOR)}
259                                                         selectedLimit={this.state.selectedLimit}
260                                                         onCloseLimitEditor={() => this.onCloseLimitEditor()}
261                                                         onSelectLimit={limit => this.onSelectLimit(limit)}/>}
262                                 </Tab>
263                                 {selectedTab !== tabIds.GENERAL ? 
264                                         <Button disabled={this.state.selectedLimit} className='add-limit-button' tabId={tabIds.ADD_LIMIT_BUTTON} btnType='link' iconName='plus'>{i18n('Add Limit')}</Button> : 
265                                         <div></div> // Render empty div to not break tabs
266                                 }
267                         </Tabs>
268                         <GridSection className='license-model-modal-buttons entitlement-pools-editor-buttons'>
269                         {!this.state.selectedLimit && <Button btnType='default' disabled={!this.props.isFormValid} onClick={() => this.submit()} type='reset'>{i18n('Save')}</Button>}
270                         <Button btnType={this.state.selectedLimit ? 'default' : 'outline'} onClick={() => this.props.onCancel()} type='reset'>
271                                 {i18n('Cancel')}
272                         </Button>
273                         </GridSection>  
274                         </div>
275                 );
276         }
277
278         submit() {
279                 const {data: entitlementPool, previousData: previousEntitlementPool, formReady} = this.props;
280
281                 if (!formReady) {
282                         this.props.onValidateForm(SP_ENTITLEMENT_POOL_FORM);
283                 } else {
284                         this.props.onSubmit({entitlementPool, previousEntitlementPool});
285                 }
286
287                 
288         }
289
290         validateName(value) {
291                 const {data: {id}, EPNames} = this.props;
292                 const isExists = Validator.isItemNameAlreadyExistsInList({itemId: id, itemName: value, list: EPNames});
293
294                 return !isExists ?  {isValid: true, errorText: ''} :
295                 {isValid: false, errorText: i18n('Entitlement pool by the name \'' + value + '\' already exists. Entitlement pool name must be unique')};
296         }
297
298         onSelectLimit(limit) {
299                 if (limit.id === this.state.selectedLimit) {
300                         this.setState({selectedLimit: ''});
301                         return;
302                 }
303                 this.setState({selectedLimit: limit.id});
304                 this.props.onOpenLimitEditor(limit);
305         }
306
307         onCloseLimitEditor() {
308                 this.setState({selectedLimit: ''});
309                 this.props.onCloseLimitEditor();
310         }
311
312         onAddLimit() {
313                 this.setState({selectedLimit: NEW_LIMIT_TEMP_ID});
314                 this.props.onOpenLimitEditor();
315         }
316
317
318
319 }
320
321 export default EntitlementPoolsEditorView;