Add new code new version
[sdc.git] / openecomp-ui / src / sdc-app / onboarding / softwareProduct / landingPage / SoftwareProductLandingPageView.jsx
1 import React from 'react';
2 import classnames from 'classnames';
3 import Dropzone from 'react-dropzone';
4
5
6 import i18n from 'nfvo-utils/i18n/i18n.js';
7 import ListEditorView from 'nfvo-components/listEditor/ListEditorView.jsx';
8 import ListEditorItemView from 'nfvo-components/listEditor/ListEditorItemView.jsx';
9
10 import FontAwesome from 'react-fontawesome';
11 import SoftwareProductLandingPageUploadConfirmationModal from './SoftwareProductLandingPageUploadConfirmationModal.jsx';
12
13
14 const SoftwareProductPropType = React.PropTypes.shape({
15         name: React.PropTypes.string,
16         description: React.PropTypes.string,
17         version: React.PropTypes.string,
18         id: React.PropTypes.string,
19         categoryId: React.PropTypes.string,
20         vendorId: React.PropTypes.string,
21         status: React.PropTypes.string,
22         licensingData: React.PropTypes.object,
23         validationData: React.PropTypes.object
24 });
25
26 const ComponentPropType = React.PropTypes.shape({
27         id: React.PropTypes.string,
28         name: React.PropTypes.string,
29         displayName: React.PropTypes.string,
30         description: React.PropTypes.string
31 });
32
33 class SoftwareProductLandingPageView extends React.Component {
34
35         state = {
36                 localFilter: '',
37                 fileName: '',
38                 dragging: false,
39                 files: []
40         };
41
42         static propTypes = {
43                 currentSoftwareProduct: SoftwareProductPropType,
44                 isReadOnlyMode: React.PropTypes.bool,
45                 componentsList: React.PropTypes.arrayOf(ComponentPropType),
46                 onDetailsSelect: React.PropTypes.func,
47                 onAttachmentsSelect: React.PropTypes.func,
48                 onUpload: React.PropTypes.func,
49                 onUploadConfirmation: React.PropTypes.func,
50                 onInvalidFileSizeUpload: React.PropTypes.func,
51                 onComponentSelect: React.PropTypes.func,
52                 onAddComponent: React.PropTypes.func
53         };
54
55         render() {
56                 let {currentSoftwareProduct, isReadOnlyMode, componentsList = []} =  this.props;
57                 return (
58                         <div className='software-product-landing-wrapper'>
59                                 <Dropzone
60                                         className={classnames('software-product-landing-view', {'active-dragging': this.state.dragging})}
61                                         onDrop={files => this.handleImportSubmit(files, isReadOnlyMode)}
62                                         onDragEnter={() => this.handleOnDragEnter(isReadOnlyMode)}
63                                         onDragLeave={() => this.setState({dragging:false})}
64                                         multiple={false}
65                                         disableClick={true}
66                                         ref='fileInput'
67                                         name='fileInput'
68                                         accept='.zip'
69                                         disabled>
70                                         <div className='draggable-wrapper'>
71                                                 <div className='software-product-landing-view-top'>
72                                                         <div className='row'>
73                                                                 {this.renderProductSummary(currentSoftwareProduct)}
74                                                                 {this.renderProductDetails(currentSoftwareProduct, isReadOnlyMode)}
75                                                         </div>
76                                                 </div>
77                                         </div>
78                                 </Dropzone>
79                                 {
80                                         componentsList.length > 0 && this.renderComponents()
81                                 }
82                                 <SoftwareProductLandingPageUploadConfirmationModal confirmationButtonText={i18n('Continue')}/>
83                         </div>
84                 );
85         }
86
87         handleOnDragEnter(isReadOnlyMode) {
88                 if (!isReadOnlyMode) {
89                         this.setState({dragging: true});
90                 }
91         }
92
93         renderProductSummary(currentSoftwareProduct) {
94                 let {name = '', description = '', vendorName = '', fullCategoryDisplayName = '', licenseAgreementName = ''}  = currentSoftwareProduct;
95                 let {onDetailsSelect} = this.props;
96                 return (
97                         <div className='details-panel'>
98                                 <div className='software-product-landing-view-heading-title'>{i18n('Software Product Details')}</div>
99                                 <div
100                                         className='software-product-landing-view-top-block clickable'
101                                         onClick={() => onDetailsSelect(currentSoftwareProduct)}>
102                                         <div className='details-container'>
103                                                 <div className='single-detail-section title-section'>
104                                                         <div>
105                                                                 <div>{name}</div>
106                                                         </div>
107                                                 </div>
108                                                 <div className='multiple-details-section'>
109                                                         <div className='detail-col' >
110                                                                 <div className='title'>{i18n('Vendor')}</div>
111                                                                 <div className='description'>{vendorName}</div>
112                                                         </div>
113                                                         <div className='detail-col'>
114                                                                 <div className='title'>{i18n('Category')}</div>
115                                                                 <div className='description'>{fullCategoryDisplayName}</div>
116                                                         </div>
117                                                         <div className='detail-col'>
118                                                                 <div className='title extra-large'>{i18n('License Agreement')}</div>
119                                                                 <div className='description'>
120                                                                         {this.renderLicenseAgreement(licenseAgreementName)}
121                                                                 </div>
122                                                         </div>
123                                                 </div>
124                                                 <div className='single-detail-section'>
125                                                         <div className='title'>{i18n('Description')}</div>
126                                                         <div className='description'>{description}</div>
127                                                 </div>
128                                         </div>
129                                 </div>
130                         </div>
131                 );
132         }
133
134         renderProductDetails(currentSoftwareProduct, isReadOnlyMode) {
135                 let {validationData} = currentSoftwareProduct;
136                 let {onAttachmentsSelect} = this.props;
137                 let details = {
138                         heatTemplates: validationData ? '1' : '0',
139                         images: '0',
140                         otherArtifacts: '0'
141                 };
142
143                 return (
144                         <div className='details-panel'>
145                                 <div className='software-product-landing-view-heading-title'>{i18n('Software Product Attachments')}</div>
146                                 <div className='software-product-landing-view-top-block'>
147                                         <div
148                                                 className='software-product-landing-view-top-block-col'
149                                                 onClick={() => onAttachmentsSelect(currentSoftwareProduct)}>
150                                                 <div>
151                                                         <div className='attachment-details'>{i18n('HEAT Templates')} (<span
152                                                                 className='attachment-details-count'>{details.heatTemplates}</span>)
153                                                         </div>
154                                                         <div className='attachment-details'>{i18n('Images')} (<span
155                                                                 className='attachment-details-count'>{details.images}</span>)
156                                                         </div>
157                                                         <div className='attachment-details'>{i18n('Other Artifacts')} (<span
158                                                                 className='attachment-details-count'>{details.otherArtifacts}</span>)
159                                                         </div>
160                                                 </div>
161                                         </div>
162                                         <div
163                                                 className={classnames('software-product-landing-view-top-block-col-upl', {'disabled': isReadOnlyMode})}>
164                                                 <div className='drag-text'>{i18n('Drag & drop for upload')}</div>
165                                                 <div className='or-text'>{i18n('or')}</div>
166                                                 <div className='upload-btn primary-btn' onClick={() => this.refs.fileInput.open()}>
167                                                         <span className='primary-btn-text'>{i18n('Select file')}</span>
168                                                 </div>
169                                         </div>
170                                 </div>
171                         </div>
172                 );
173         }
174
175         renderComponents() {
176                 const {localFilter} = this.state;
177
178                 return (
179                         <ListEditorView
180                                 title={i18n('Virtual Function Components')}
181                                 filterValue={localFilter}
182                                 placeholder={i18n('Filter Components')}
183                                 onFilter={filter => this.setState({localFilter: filter})}>
184                                 {this.filterList().map(component => this.renderComponentsListItem(component))}
185                         </ListEditorView>
186                 );
187         }
188
189         renderComponentsListItem(component) {
190                 let {id: componentId, name, displayName, description = ''} = component;
191                 let {currentSoftwareProduct: {id}, onComponentSelect} = this.props;
192                 return (
193                         <ListEditorItemView
194                                 key={name + Math.floor(Math.random() * (100 - 1) + 1).toString()}
195                                 className='list-editor-item-view'
196                                 onSelect={() => onComponentSelect({id, componentId})}>
197                                 <div className='list-editor-item-view-field'>
198                                         <div className='title'>{i18n('Component')}</div>
199                                         <div className='name'>{displayName}</div>
200                                 </div>
201                                 <div className='list-editor-item-view-field'>
202                                         <div className='title'>{i18n('Description')}</div>
203                                         <div className='description'>{description}</div>
204                                 </div>
205                         </ListEditorItemView>
206                 );
207         }
208
209         renderLicenseAgreement(licenseAgreementName) {
210                 if (!licenseAgreementName) {
211                         return (<FontAwesome name='exclamation-triangle' className='warning-icon'/>);
212                 }
213                 return (licenseAgreementName);
214         }
215
216
217         filterList() {
218                 let {componentsList = []} = this.props;
219
220                 let {localFilter} = this.state;
221                 if (localFilter.trim()) {
222                         const filter = new RegExp(escape(localFilter), 'i');
223                         return componentsList.filter(({displayName = '', description = ''}) => {
224                                 return escape(displayName).match(filter) || escape(description).match(filter);
225                         });
226                 }
227                 else {
228                         return componentsList;
229                 }
230         }
231
232         handleImportSubmit(files, isReadOnlyMode) {
233                 if (isReadOnlyMode) {
234                         return;
235                 }
236                 if (files[0] && files[0].size) {
237                         this.setState({
238                                 fileName: files[0].name,
239                                 dragging: false,
240                                 complete: '0',
241                         });
242                         this.startUploading(files);
243                 }
244                 else {
245                         this.props.onInvalidFileSizeUpload();
246                 }
247
248         }
249
250         startUploading(files) {
251                 let {onUpload, currentSoftwareProduct, onUploadConfirmation} = this.props;
252
253                 let {validationData} = currentSoftwareProduct;
254
255                 if (!(files && files.length)) {
256                         return;
257                 }
258                 let file = files[0];
259                 let formData = new FormData();
260                 formData.append('upload', file);
261                 this.refs.fileInput.value = '';
262
263                 if (validationData) {
264                         onUploadConfirmation(currentSoftwareProduct.id, formData);
265                 }else {
266                         onUpload(currentSoftwareProduct.id, formData);
267                 }
268
269         }
270 }
271
272 export default SoftwareProductLandingPageView;