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