/*
* Copyright © 2016-2018 European Support Limited
* Modifications Copyright (C) 2021 Nordix Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import React from 'react';
import PropTypes from 'prop-types';
import classnames from 'classnames';
import Dropzone from 'react-dropzone';
import i18n from 'nfvo-utils/i18n/i18n.js';
import VnfRepositorySearchBox from 'nfvo-components/vnfMarketPlace/VnfRepositorySearchBox.jsx';
import { SVGIcon } from 'onap-ui-react';
import SoftwareProductComponentsList from 'sdc-app/onboarding/softwareProduct/components/SoftwareProductComponents.js';
import VspUploadStatus from 'sdc-app/onboarding/softwareProduct/landingPage/VspUploadStatus';
import ProgressBar from 'react-bootstrap/lib/ProgressBar';
const SoftwareProductPropType = PropTypes.shape({
name: PropTypes.string,
description: PropTypes.string,
version: PropTypes.string,
id: PropTypes.string,
categoryId: PropTypes.string,
vendorId: PropTypes.string,
licenseType: PropTypes.string,
status: PropTypes.string,
licensingData: PropTypes.object,
validationData: PropTypes.object,
selectedModelList: PropTypes.arrayOf(PropTypes.string)
});
const ComponentPropType = PropTypes.shape({
id: PropTypes.string,
name: PropTypes.string,
displayName: PropTypes.string,
description: PropTypes.string
});
class SoftwareProductLandingPageView extends React.Component {
state = {
fileName: '',
dragging: false,
uploadStatus: {},
files: [],
uploadProgress: 0,
showProgressBar: false
};
constructor(props) {
super(props);
this.getExternalLicenceFeatureState = this.getExternalLicenceFeatureState.bind(
this
);
}
static propTypes = {
currentSoftwareProduct: SoftwareProductPropType,
isReadOnlyMode: PropTypes.bool,
componentsList: PropTypes.arrayOf(ComponentPropType),
version: PropTypes.object,
onLicenseChange: PropTypes.func,
onUpload: PropTypes.func,
fetchUploadStatus: PropTypes.func,
onUploadConfirmation: PropTypes.func,
onInvalidFileSizeUpload: PropTypes.func,
onComponentSelect: PropTypes.func,
onAddComponent: PropTypes.func
};
componentDidMount() {
const {
onCandidateInProcess,
currentSoftwareProduct,
isCertified
} = this.props;
if (currentSoftwareProduct.candidateOnboardingOrigin && !isCertified) {
onCandidateInProcess(currentSoftwareProduct.id);
}
this.keepCheckingUploadStatus();
}
componentWillUnmount() {
this.stopUploadStatusChecking();
}
keepCheckingUploadStatus(initialDelayInMs = 0, updatePeriodInMs = 10000) {
this.stopUploadStatusChecking();
setTimeout(() => this.updateUploadStatus(), initialDelayInMs);
this.uploadStatusInterval = setInterval(
() => this.updateUploadStatus(),
updatePeriodInMs
);
}
stopUploadStatusChecking() {
clearInterval(this.uploadStatusInterval);
}
updateUploadStatus() {
const currentVspId = this.props.currentSoftwareProduct.id;
this.props
.fetchUploadStatus(currentVspId)
.then(uploadStatusResponse => {
const vspUploadStatus = new VspUploadStatus(
uploadStatusResponse
);
this.setState({
uploadStatus: vspUploadStatus
});
})
.catch(error =>
console.error('Could not retrieve upload status', error)
);
}
licenceChange = (e, currentSoftwareProduct, onLicenseChange) => {
currentSoftwareProduct.licenseType = e.target.value
? e.target.value
: 'INTERNAL';
onLicenseChange(currentSoftwareProduct);
};
getExternalLicenceFeatureState() {
const licenseFeature = this.props.features.find(
feature => feature.name === 'EXTERNAL_LICENSE'
);
return licenseFeature ? licenseFeature.active : true;
}
render() {
let {
currentSoftwareProduct,
isReadOnlyMode,
isManual,
onLicenseChange
} = this.props;
let licenceChange = this.licenceChange;
return (
this.handleImportSubmit(files, isReadOnlyMode, isManual)
}
onDragEnter={() =>
this.handleOnDragEnter(isReadOnlyMode, isManual)
}
onDragLeave={() => this.setState({ dragging: false })}
multiple={false}
disableClick={true}
ref="fileInput"
name="fileInput"
accept=".zip, .csar">
{this.renderProductAttachments(
isReadOnlyMode
)}
);
}
handleOnDragEnter(isReadOnlyMode, isManual) {
if (!isReadOnlyMode && !isManual) {
this.setState({ dragging: true });
}
}
isUploadInProgress() {
return (
this.state.uploadStatus.complete !== undefined &&
!this.state.uploadStatus.complete
);
}
renderProductAttachments(isReadOnlyMode) {
let { onBrowseVNF, currentSoftwareProduct } = this.props;
if (this.isUploadInProgress()) {
return (
{i18n('Software Product Attachments')}
{this.state.uploadStatus.statusToString()}
{this.state.showProgressBar && (
)}
);
}
return (
{i18n('Software Product Attachments')}
this.refs.fileInput.open()}
onBrowseVNF={() => onBrowseVNF(currentSoftwareProduct)}
/>
);
}
handleImportSubmit(files, isReadOnlyMode, isManual) {
if (isReadOnlyMode || isManual) {
return;
}
if (files[0] && files[0].size) {
this.setState({
fileName: files[0].name,
dragging: false,
complete: '0'
});
this.startUploading(files);
} else {
this.setState({
dragging: false
});
this.props.onInvalidFileSizeUpload();
}
}
onUploadStart = vspUploadStatus => {
this.setState({
uploadStatus: vspUploadStatus
});
this.stopUploadStatusChecking();
this.showProgressBar();
};
onUploadProgress = progressEvent => {
const vspUploadStatus = new VspUploadStatus({
status: VspUploadStatus.UPLOADING,
complete: false
});
this.setState({
uploadStatus: vspUploadStatus
});
const percentCompleted = Math.round(
progressEvent.loaded * 100 / progressEvent.total
);
if (percentCompleted === 100) {
this.keepCheckingUploadStatus(5000);
this.resetUploadProgress(2000);
}
this.setState({ uploadProgress: percentCompleted });
};
onUploadFinished = () => {
this.updateUploadStatus();
};
showProgressBar() {
this.setState({ showProgressBar: true });
}
hideProgressBar() {
this.setState({ showProgressBar: false });
}
resetUploadProgress(milliseconds) {
setTimeout(() => {
this.setState({ uploadProgress: 0 });
this.hideProgressBar();
}, milliseconds);
}
startUploading(files) {
let {
onUpload,
currentSoftwareProduct,
onUploadConfirmation
} = this.props;
let { validationData } = currentSoftwareProduct;
if (!(files && files.length)) {
return;
}
let file = files[0];
let formData = new FormData();
formData.append('upload', file);
this.refs.fileInput.value = '';
if (validationData) {
onUploadConfirmation(
currentSoftwareProduct.id,
formData,
vspUploadStatus => this.onUploadStart(vspUploadStatus),
this.onUploadProgress,
this.onUploadFinished
);
} else {
onUpload(
currentSoftwareProduct.id,
formData,
vspUploadStatus => this.onUploadStart(vspUploadStatus),
this.onUploadProgress,
this.onUploadFinished
);
}
}
}
const ProductSummary = ({
currentSoftwareProduct,
licenceChange,
onLicenseChange,
externalLicenceEnabled
}) => {
let {
name = '',
description = '',
vendorName = '',
fullCategoryDisplayName = '',
selectedModelList = []
} = currentSoftwareProduct;
return (
{i18n('Software Product Details')}
{i18n('Vendor')}
{vendorName}
{i18n('Category')}
{fullCategoryDisplayName}
{i18n('Model')}
{selectedModelList.length > 0 ? (
{selectedModelList.map(value => (
- {value}
))}
) : (
i18n('model.sdc.label')
)}
{i18n('License Agreement')}
{i18n('Description')}
{description}
);
};
const LicenseAgreementWithExternal = ({
licenceChange,
currentSoftwareProduct,
onLicenseChange
}) => {
return (
);
};
const LicenseAgreementWithoutExternal = ({
licenceChange,
currentSoftwareProduct,
onLicenseChange
}) => {
if (!currentSoftwareProduct.licenseAgreementName) {
return (
licenceChange(
event,
currentSoftwareProduct,
onLicenseChange
)
}>
{i18n('Missing')}
);
}
return {currentSoftwareProduct.licenseAgreementName}
;
};
const LicenseAgreement = ({
licenceChange,
currentSoftwareProduct,
onLicenseChange,
externalLicenceEnabled
}) => {
if (externalLicenceEnabled) {
return (
);
} else {
return (
);
}
};
export default SoftwareProductLandingPageView;