[SDC] Onboarding 1710 rebase.
[sdc.git] / openecomp-ui / src / sdc-app / onboarding / softwareProduct / landingPage / SoftwareProductLandingPageView.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 classnames from 'classnames';
18 import Dropzone from 'react-dropzone';
19
20
21 import i18n from 'nfvo-utils/i18n/i18n.js';
22
23
24 import SVGIcon from 'sdc-ui/lib/react/SVGIcon.js';
25 import SoftwareProductComponentsList from '../components/SoftwareProductComponentsList.js';
26
27 const SoftwareProductPropType = React.PropTypes.shape({
28         name: React.PropTypes.string,
29         description: React.PropTypes.string,
30         version: React.PropTypes.object,
31         id: React.PropTypes.string,
32         categoryId: React.PropTypes.string,
33         vendorId: React.PropTypes.string,
34         status: React.PropTypes.string,
35         licensingData: React.PropTypes.object,
36         validationData: React.PropTypes.object
37 });
38
39 const ComponentPropType = React.PropTypes.shape({
40         id: React.PropTypes.string,
41         name: React.PropTypes.string,
42         displayName: React.PropTypes.string,
43         description: React.PropTypes.string
44 });
45
46 class SoftwareProductLandingPageView extends React.Component {
47
48         state = {
49
50                 fileName: '',
51                 dragging: false,
52                 files: []
53         };
54
55         static propTypes = {
56                 currentSoftwareProduct: SoftwareProductPropType,
57                 isReadOnlyMode: React.PropTypes.bool,
58                 componentsList: React.PropTypes.arrayOf(ComponentPropType),
59                 onDetailsSelect: React.PropTypes.func,
60                 onAttachmentsSelect: React.PropTypes.func,
61                 onUpload: React.PropTypes.func,
62                 onUploadConfirmation: React.PropTypes.func,
63                 onInvalidFileSizeUpload: React.PropTypes.func,
64                 onComponentSelect: React.PropTypes.func,
65                 onAddComponent: React.PropTypes.func
66         };
67
68         render() {
69                 let {currentSoftwareProduct, isReadOnlyMode, isManual, onDetailsSelect, componentsList} =  this.props;
70                 return (
71                         <div className='software-product-landing-wrapper'>
72                                 <Dropzone
73                                         className={classnames('software-product-landing-view', {'active-dragging': this.state.dragging})}
74                                         onDrop={files => this.handleImportSubmit(files, isReadOnlyMode, isManual)}
75                                         onDragEnter={() => this.handleOnDragEnter(isReadOnlyMode, isManual)}
76                                         onDragLeave={() => this.setState({dragging:false})}
77                                         multiple={false}
78                                         disableClick={true}
79                                         ref='fileInput'
80                                         name='fileInput'
81                                         accept='.zip'
82                                         disabled>
83                                         <div className='draggable-wrapper'>
84                                                 <div className='software-product-landing-view-top'>
85                                                         <div className='row'>
86                                                                 <ProductSummary currentSoftwareProduct={currentSoftwareProduct} onDetailsSelect={onDetailsSelect} />
87                                                                 {isManual ?
88                                                                         <div className='details-panel'/>
89                                                                         : this.renderProductDetails(currentSoftwareProduct, isReadOnlyMode)}
90                                                         </div>
91                                                 </div>
92                                         </div>
93                                 </Dropzone>
94                                 <SoftwareProductComponentsList
95                                         isReadOnlyMode={isReadOnlyMode}
96                                         componentsList={componentsList}
97                                         isManual={isManual}
98                                         currentSoftwareProduct={currentSoftwareProduct}/>
99                         </div>
100                 );
101         }
102
103         handleOnDragEnter(isReadOnlyMode, isManual) {
104                 if (!isReadOnlyMode && !isManual) {
105                         this.setState({dragging: true});
106                 }
107         }
108
109         renderProductDetails(currentSoftwareProduct, isReadOnlyMode) {
110                 let {validationData} = currentSoftwareProduct;
111                 let {onAttachmentsSelect} = this.props;
112                 let details = {
113                         heatTemplates: validationData ? '1' : '0',
114                         images: '0',
115                         otherArtifacts: '0'
116                 };
117
118                 return (
119                         <div className='details-panel'>
120                                 <div className='software-product-landing-view-heading-title'>{i18n('Software Product Attachments')}</div>
121                                 <div className='software-product-landing-view-top-block'>
122                                         <div
123                                                 className='software-product-landing-view-top-block-col'
124                                                 onClick={() => onAttachmentsSelect(currentSoftwareProduct)}>
125                                                 <div>
126                                                         <div className='attachment-details'>{i18n('HEAT Templates')} (<span
127                                                                 className='attachment-details-count'>{details.heatTemplates}</span>)
128                                                         </div>
129                                                 </div>
130                                         </div>
131                                         <div
132                                                 className={classnames('software-product-landing-view-top-block-col-upl', {'disabled': isReadOnlyMode})}>
133                                                 <div className='drag-text'>{i18n('Drag & drop for upload')}</div>
134                                                 <div className='or-text'>{i18n('or')}</div>
135                                                 <div data-test-id='upload-btn' className='upload-btn primary-btn' onClick={() => this.refs.fileInput.open()}>
136                                                         <span className='primary-btn-text'>{i18n('Select file')}</span>
137                                                 </div>
138                                         </div>
139                                 </div>
140                         </div>
141                 );
142         }
143
144         handleImportSubmit(files, isReadOnlyMode, isManual) {
145                 if (isReadOnlyMode || isManual) {
146                         return;
147                 }
148                 if (files[0] && files[0].size) {
149                         this.setState({
150                                 fileName: files[0].name,
151                                 dragging: false,
152                                 complete: '0',
153                         });
154                         this.startUploading(files);
155                 }
156                 else {
157                         this.setState({
158                                 dragging: false
159                         });
160                         this.props.onInvalidFileSizeUpload();
161                 }
162
163         }
164
165         startUploading(files) {
166                 let {onUpload, currentSoftwareProduct, onUploadConfirmation} = this.props;
167
168                 let {validationData} = currentSoftwareProduct;
169
170                 if (!(files && files.length)) {
171                         return;
172                 }
173                 let file = files[0];
174                 let formData = new FormData();
175                 formData.append('upload', file);
176                 this.refs.fileInput.value = '';
177
178                 if (validationData) {
179                         onUploadConfirmation(currentSoftwareProduct.id, formData);
180                 }else {
181                         onUpload(currentSoftwareProduct.id, formData);
182                 }
183
184         }
185 }
186
187 const ProductSummary = ({currentSoftwareProduct, onDetailsSelect}) => {
188         let {name = '', description = '', vendorName = '', fullCategoryDisplayName = '', licenseAgreementName = ''}  = currentSoftwareProduct;
189         return (
190                 <div className='details-panel'>
191                         <div className='software-product-landing-view-heading-title'>{i18n('Software Product Details')}</div>
192                         <div
193                                 className='software-product-landing-view-top-block clickable'
194                                 onClick={() => onDetailsSelect(currentSoftwareProduct)}>
195                                 <div className='details-container'>
196                                         <div className='single-detail-section title-section'>
197                                                 <div className='single-detail-section title-text'>
198                                                         {name}
199                                                 </div>
200                                         </div>
201                                         <div className='details-section'>
202                                                 <div className='multiple-details-section'>
203                                                         <div className='detail-col' >
204                                                                 <div className='title'>{i18n('Vendor')}</div>
205                                                                 <div className='description'>{vendorName}</div>
206                                                         </div>
207                                                         <div className='detail-col'>
208                                                                 <div className='title'>{i18n('Category')}</div>
209                                                                 <div className='description'>{fullCategoryDisplayName}</div>
210                                                         </div>
211                                                         <div className='detail-col'>
212                                                                 <div className='title extra-large'>{i18n('License Agreement')}</div>
213                                                                 <div className='description'>
214                                                                         <LicenseAgreement licenseAgreementName={licenseAgreementName}/>
215                                                                 </div>
216                                                         </div>
217                                                 </div>
218                                                 <div className='single-detail-section'>
219                                                         <div className='title'>{i18n('Description')}</div>
220                                                         <div className='description'>{description}</div>
221                                                 </div>
222                                         </div>
223                                 </div>
224                         </div>
225                 </div>
226         );
227 };
228
229
230 const LicenseAgreement = ({licenseAgreementName}) => {
231         if (!licenseAgreementName) {
232                 return (<div className='missing-license'><SVGIcon name='exclamationTriangleFull'/><div className='warning-text'>{i18n('Missing')}</div></div>);
233         }
234         return <div>{licenseAgreementName}</div>;
235 };
236
237 export default SoftwareProductLandingPageView;