Add collaboration feature
[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 PropTypes from 'prop-types';
18 import classnames from 'classnames';
19 import Dropzone from 'react-dropzone';
20
21
22 import i18n from 'nfvo-utils/i18n/i18n.js';
23 import DraggableUploadFileBox from 'nfvo-components/fileupload/DraggableUploadFileBox.jsx';
24
25 import SVGIcon from 'sdc-ui/lib/react/SVGIcon.js';
26 import SoftwareProductComponentsList from 'sdc-app/onboarding/softwareProduct/components/SoftwareProductComponents.js';
27
28 const SoftwareProductPropType = PropTypes.shape({
29         name: PropTypes.string,
30         description: PropTypes.string,
31         version: PropTypes.object,
32         id: PropTypes.string,
33         categoryId: PropTypes.string,
34         vendorId: PropTypes.string,
35         status: PropTypes.string,
36         licensingData: PropTypes.object,
37         validationData: PropTypes.object
38 });
39
40 const ComponentPropType = PropTypes.shape({
41         id: PropTypes.string,
42         name: PropTypes.string,
43         displayName: PropTypes.string,
44         description: PropTypes.string
45 });
46
47 class SoftwareProductLandingPageView extends React.Component {
48
49         state = {
50
51                 fileName: '',
52                 dragging: false,
53                 files: []
54         };
55
56         static propTypes = {
57                 currentSoftwareProduct: SoftwareProductPropType,
58                 isReadOnlyMode: PropTypes.bool,
59                 componentsList: PropTypes.arrayOf(ComponentPropType),
60                 version: PropTypes.object,
61                 onDetailsSelect: PropTypes.func,
62                 onUpload: PropTypes.func,
63                 onUploadConfirmation: PropTypes.func,
64                 onInvalidFileSizeUpload: PropTypes.func,
65                 onComponentSelect: PropTypes.func,
66                 onAddComponent: PropTypes.func
67         };
68
69         render() {
70                 let {currentSoftwareProduct, isReadOnlyMode, isManual, onDetailsSelect} =  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                         </div>
95                 );
96         }
97
98         handleOnDragEnter(isReadOnlyMode, isManual) {
99                 if (!isReadOnlyMode && !isManual) {
100                         this.setState({dragging: true});
101                 }
102         }
103
104         renderProductDetails(isManual, isReadOnlyMode) {
105                 return (
106                         <div className='details-panel'>
107                                 { !isManual && <div>
108                                         <div className='software-product-landing-view-heading-title'>{i18n('Software Product Attachments')}</div>
109                                                 <DraggableUploadFileBox
110                                                         dataTestId='upload-btn'
111                                                         isReadOnlyMode={isReadOnlyMode}
112                                                         className={classnames('software-product-landing-view-top-block-col-upl', {'disabled': isReadOnlyMode})}
113                                                         onClick={() => this.refs.fileInput.open()}/>
114                                         </div>
115                                 }
116                         </div>
117                 );
118         }
119
120         handleImportSubmit(files, isReadOnlyMode, isManual) {
121                 if (isReadOnlyMode || isManual) {
122                         return;
123                 }
124                 if (files[0] && files[0].size) {
125                         this.setState({
126                                 fileName: files[0].name,
127                                 dragging: false,
128                                 complete: '0',
129                         });
130                         this.startUploading(files);
131                 }
132                 else {
133                         this.setState({
134                                 dragging: false
135                         });
136                         this.props.onInvalidFileSizeUpload();
137                 }
138
139         }
140
141         startUploading(files) {
142                 let {onUpload, currentSoftwareProduct, onUploadConfirmation} = this.props;
143
144                 let {validationData} = currentSoftwareProduct;
145
146                 if (!(files && files.length)) {
147                         return;
148                 }
149                 let file = files[0];
150                 let formData = new FormData();
151                 formData.append('upload', file);
152                 this.refs.fileInput.value = '';
153
154                 if (validationData) {
155                         onUploadConfirmation(currentSoftwareProduct.id, formData);
156                 }else {
157                         onUpload(currentSoftwareProduct.id, formData);
158                 }
159
160         }
161 }
162
163 const ProductSummary = ({currentSoftwareProduct, onDetailsSelect}) => {
164         let {name = '', description = '', vendorName = '', fullCategoryDisplayName = '', licenseAgreementName = ''}  = currentSoftwareProduct;
165         return (
166                 <div className='details-panel'>
167                         <div className='software-product-landing-view-heading-title'>{i18n('Software Product Details')}</div>
168                         <div
169                                 className='software-product-landing-view-top-block clickable'
170                                 onClick={() => onDetailsSelect(currentSoftwareProduct)}>
171                                 <div className='details-container'>
172                                         <div className='single-detail-section title-section'>
173                                                 <div className='single-detail-section title-text'>
174                                                         {name}
175                                                 </div>
176                                         </div>
177                                         <div className='details-section'>
178                                                 <div className='multiple-details-section'>
179                                                         <div className='detail-col' >
180                                                                 <div className='title'>{i18n('Vendor')}</div>
181                                                                 <div className='description'>{vendorName}</div>
182                                                         </div>
183                                                         <div className='detail-col'>
184                                                                 <div className='title'>{i18n('Category')}</div>
185                                                                 <div className='description'>{fullCategoryDisplayName}</div>
186                                                         </div>
187                                                         <div className='detail-col'>
188                                                                 <div className='title extra-large'>{i18n('License Agreement')}</div>
189                                                                 <div className='description'>
190                                                                         <LicenseAgreement licenseAgreementName={licenseAgreementName}/>
191                                                                 </div>
192                                                         </div>
193                                                 </div>
194                                                 <div className='single-detail-section'>
195                                                         <div className='title'>{i18n('Description')}</div>
196                                                         <div className='description'>{description}</div>
197                                                 </div>
198                                         </div>
199                                 </div>
200                         </div>
201                 </div>
202         );
203 };
204
205
206 const LicenseAgreement = ({licenseAgreementName}) => {
207         if (!licenseAgreementName) {
208                 return (<div className='missing-license'><SVGIcon color='warning' name='exclamationTriangleFull'/><div className='warning-text'>{i18n('Missing')}</div></div>);
209         }
210         return <div>{licenseAgreementName}</div>;
211 };
212
213 export default SoftwareProductLandingPageView;