2 * Copyright © 2016-2018 European Support Limited
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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 or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 import React from 'react';
17 import PropTypes from 'prop-types';
18 import classnames from 'classnames';
19 import Dropzone from 'react-dropzone';
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';
26 import { SVGIcon } from 'onap-ui-react';
27 import SoftwareProductComponentsList from 'sdc-app/onboarding/softwareProduct/components/SoftwareProductComponents.js';
29 const SoftwareProductPropType = PropTypes.shape({
30 name: PropTypes.string,
31 description: PropTypes.string,
32 version: PropTypes.string,
34 categoryId: PropTypes.string,
35 vendorId: PropTypes.string,
36 licenseType: PropTypes.string,
37 status: PropTypes.string,
38 licensingData: PropTypes.object,
39 validationData: PropTypes.object
42 const ComponentPropType = PropTypes.shape({
44 name: PropTypes.string,
45 displayName: PropTypes.string,
46 description: PropTypes.string
49 class SoftwareProductLandingPageView extends React.Component {
58 this.getExternalLicenceFeatureState = this.getExternalLicenceFeatureState.bind(
64 currentSoftwareProduct: SoftwareProductPropType,
65 isReadOnlyMode: PropTypes.bool,
66 componentsList: PropTypes.arrayOf(ComponentPropType),
67 version: PropTypes.object,
68 onLicenseChange: PropTypes.func,
69 onUpload: PropTypes.func,
70 onUploadConfirmation: PropTypes.func,
71 onInvalidFileSizeUpload: PropTypes.func,
72 onComponentSelect: PropTypes.func,
73 onAddComponent: PropTypes.func
78 currentSoftwareProduct,
81 if (currentSoftwareProduct.candidateOnboardingOrigin && !isCertified) {
82 onCandidateInProcess(currentSoftwareProduct.id);
86 licenceChange = (e, currentSoftwareProduct, onLicenseChange) => {
87 currentSoftwareProduct.licenseType = e.target.value
90 onLicenseChange(currentSoftwareProduct);
93 getExternalLicenceFeatureState() {
94 var licenseFeature = this.props.features.find(
95 feature => feature.name === 'EXTERNAL_LICENSE'
97 return licenseFeature ? licenseFeature.active : true;
102 currentSoftwareProduct,
107 let licenceChange = this.licenceChange;
109 <div className="software-product-landing-wrapper">
111 className={classnames('software-product-landing-view', {
112 'active-dragging': this.state.dragging
115 this.handleImportSubmit(files, isReadOnlyMode, isManual)
118 this.handleOnDragEnter(isReadOnlyMode, isManual)
120 onDragLeave={() => this.setState({ dragging: false })}
125 accept=".zip, .csar">
126 <div className="draggable-wrapper">
127 <div className="software-product-landing-view-top">
128 <div className="row">
130 currentSoftwareProduct={
131 currentSoftwareProduct
133 licenceChange={licenceChange}
134 onLicenseChange={onLicenseChange}
135 externalLicenceEnabled={this.getExternalLicenceFeatureState()}
137 {this.renderProductDetails(
145 <SoftwareProductComponentsList />
150 handleOnDragEnter(isReadOnlyMode, isManual) {
151 if (!isReadOnlyMode && !isManual) {
152 this.setState({ dragging: true });
156 renderProductDetails(isManual, isReadOnlyMode) {
157 let { onBrowseVNF, currentSoftwareProduct } = this.props;
159 if (Configuration.get('showBrowseVNF')) {
161 <div className="details-panel">
164 <div className="software-product-landing-view-heading-title">
165 {i18n('Software Product Attachments')}
167 <VnfRepositorySearchBox
168 dataTestId="upload-btn"
169 isReadOnlyMode={isReadOnlyMode}
170 className={classnames(
171 'software-product-landing-view-top-block-col-upl showVnf',
172 { disabled: isReadOnlyMode }
174 onClick={() => this.refs.fileInput.open()}
176 onBrowseVNF(currentSoftwareProduct)
185 <div className="details-panel">
188 <div className="software-product-landing-view-heading-title">
189 {i18n('Software Product Attachments')}
191 <DraggableUploadFileBox
192 dataTestId="upload-btn"
193 isReadOnlyMode={isReadOnlyMode}
194 className={classnames(
195 'software-product-landing-view-top-block-col-upl',
196 { disabled: isReadOnlyMode }
198 onClick={() => this.refs.fileInput.open()}
199 onBrowseVNF={() => onBrowseVNF()}
208 handleImportSubmit(files, isReadOnlyMode, isManual) {
209 if (isReadOnlyMode || isManual) {
212 if (files[0] && files[0].size) {
214 fileName: files[0].name,
218 this.startUploading(files);
223 this.props.onInvalidFileSizeUpload();
227 startUploading(files) {
230 currentSoftwareProduct,
234 let { validationData } = currentSoftwareProduct;
236 if (!(files && files.length)) {
240 let formData = new FormData();
241 formData.append('upload', file);
242 this.refs.fileInput.value = '';
244 if (validationData) {
245 onUploadConfirmation(currentSoftwareProduct.id, formData);
247 onUpload(currentSoftwareProduct.id, formData);
252 const ProductSummary = ({
253 currentSoftwareProduct,
256 externalLicenceEnabled
262 fullCategoryDisplayName = ''
263 } = currentSoftwareProduct;
265 <div className="details-panel">
266 <div className="software-product-landing-view-heading-title">
267 {i18n('Software Product Details')}
269 <div className="software-product-landing-view-top-block">
270 <div className="details-container">
271 <div className="single-detail-section title-section">
272 <div className="single-detail-section title-text">
276 <div className="details-section">
277 <div className="multiple-details-section">
278 <div className="detail-col">
279 <div className="title">{i18n('Vendor')}</div>
280 <div className="description">{vendorName}</div>
282 <div className="detail-col">
283 <div className="title">{i18n('Category')}</div>
284 <div className="description">
285 {fullCategoryDisplayName}
288 <div className="detail-col">
289 <div className="title extra-large">
290 {i18n('License Agreement')}
292 <div className="description">
294 licenceChange={licenceChange}
295 currentSoftwareProduct={
296 currentSoftwareProduct
298 onLicenseChange={onLicenseChange}
299 externalLicenceEnabled={
300 externalLicenceEnabled
306 <div className="single-detail-section">
307 <div className="title">{i18n('Description')}</div>
308 <div className="description">{description}</div>
317 const LicenseAgreementWithExternal = ({
319 currentSoftwareProduct,
323 <div className="missing-license">
332 currentSoftwareProduct,
336 checked={currentSoftwareProduct.licenseType === 'INTERNAL'}
339 <div className="description licenceLabel">
340 {i18n('Internal license')}
350 currentSoftwareProduct,
354 checked={currentSoftwareProduct.licenseType === 'EXTERNAL'}
357 <div className="description licenceLabel">
358 {i18n('External license')}
365 const LicenseAgreementWithoutExternal = ({
367 currentSoftwareProduct,
370 if (!currentSoftwareProduct.licenseAgreementName) {
373 className="missing-license clickable"
377 currentSoftwareProduct,
381 <SVGIcon color="warning" name="exclamationTriangleFull" />
382 <div className="warning-text">{i18n('Missing')}</div>
386 return <div>{currentSoftwareProduct.licenseAgreementName}</div>;
389 const LicenseAgreement = ({
391 currentSoftwareProduct,
393 externalLicenceEnabled
395 if (externalLicenceEnabled) {
397 <LicenseAgreementWithExternal
398 licenceChange={licenceChange}
399 currentSoftwareProduct={currentSoftwareProduct}
400 onLicenseChange={onLicenseChange}
405 <LicenseAgreementWithoutExternal
406 licenceChange={licenceChange}
407 currentSoftwareProduct={currentSoftwareProduct}
408 onLicenseChange={onLicenseChange}
414 export default SoftwareProductLandingPageView;