aboutsummaryrefslogtreecommitdiffstats
path: root/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachmentsView.jsx
diff options
context:
space:
mode:
Diffstat (limited to 'openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachmentsView.jsx')
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachmentsView.jsx253
1 files changed, 95 insertions, 158 deletions
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachmentsView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachmentsView.jsx
index c52999ca46..66fb2f8356 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachmentsView.jsx
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachmentsView.jsx
@@ -1,182 +1,119 @@
-import React from 'react';
-import FontAwesome from 'react-fontawesome';
-import classNames from 'classnames';
-import Collapse from 'react-bootstrap/lib/Collapse.js';
-
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * 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, {Component, PropTypes} from 'react';
+import Tabs from 'react-bootstrap/lib/Tabs.js';
+import Tab from 'react-bootstrap/lib/Tab.js';
+import {tabsMapping} from './SoftwareProductAttachmentsConstants.js';
import i18n from 'nfvo-utils/i18n/i18n.js';
-import {nodeTypes, mouseActions} from './SoftwareProductAttachmentsConstants';
-
-const typeToIcon = Object.freeze({
- heat: 'building-o',
- volume: 'database',
- network: 'cloud',
- artifact: 'gear',
- env: 'server',
- other: 'cube'
-});
+import Icon from 'nfvo-components/icon/Icon.jsx';
+import HeatValidation from './validation/HeatValidation.js';
-const leftPanelWidth = 250;
-
-class SoftwareProductAttachmentsView extends React.Component {
+class HeatScreenView extends Component {
static propTypes = {
- attachmentsTree: React.PropTypes.object.isRequired
+ isValidationAvailable: PropTypes.bool,
+ goToOverview: PropTypes.bool
};
+
state = {
- treeWidth: '400'
+ activeTab: tabsMapping.SETUP
};
render() {
- let {attachmentsTree, errorList} = this.props;
- let {treeWidth} = this.state;
+ let {isValidationAvailable, isReadOnlyMode, heatDataExist, onDownload, softwareProductId, onProcessAndValidate, heatSetup, HeatSetupComponent, onGoToOverview, version, ...other} = this.props;
return (
- <div className='software-product-attachments'>
- <div className='software-product-attachments-tree' style={{'width' : treeWidth + 'px'}}>
- <div className='tree-wrapper'>
- {
- attachmentsTree && attachmentsTree.children && attachmentsTree.children.map((child, ind) => this.renderNode(child, [ind]))
- }
- </div>
+ <div className='vsp-attachments-view'>
+ <div className='attachments-view-controllers'>
+ {(this.state.activeTab === tabsMapping.SETUP) &&
+ <Icon
+ iconClassName={heatDataExist ? '' : 'disabled'}
+ className={heatDataExist ? '' : 'disabled'}
+ image='download'
+ label={i18n('Download HEAT')}
+ onClick={heatDataExist ? () => onDownload({heatCandidate: heatSetup, isReadOnlyMode, version}) : undefined}
+ data-test-id='download-heat'/>}
+ {(this.state.activeTab === tabsMapping.VALIDATION && softwareProductId) &&
+ <Icon
+ iconClassName={this.props.goToOverview ? '' : 'disabled'}
+ className={`go-to-overview-icon ${this.props.goToOverview ? '' : 'disabled'}`}
+ labelClassName='go-to-overview-label'
+ onClick={this.props.goToOverview ? onGoToOverview : undefined}
+ image='go-to-overview'
+ label={i18n('Go to Overview')}
+ data-test-id='go-to-overview'/>}
+ <Icon
+ image='upload'
+ label={i18n('Upload New HEAT')}
+ className={isReadOnlyMode ? 'disabled' : ''}
+ iconClassName={isReadOnlyMode ? 'disabled' : ''}
+ onClick={evt => {this.refs.hiddenImportFileInput.click(evt);}}
+ data-test-id='upload-heat'/>
+ <input
+ ref='hiddenImportFileInput'
+ type='file'
+ name='fileInput'
+ accept='.zip'
+ onChange={evt => this.handleImport(evt)}/>
</div>
- <div onMouseDown={(e) => this.onChangeTreeWidth(e)} className='software-product-attachments-separator'/>
-
- <div className='software-product-attachments-error-list'>
- {errorList.length ? this.renderErrorList(errorList) : <div className='no-errors'>{attachmentsTree.children ?
- i18n('VALIDATION SUCCESS') : i18n('THERE IS NO HEAT DATA TO PRESENT') }</div>}
- </div>
- </div>
- );
- }
-
- renderNode(node, path) {
- let isFolder = node.children && node.children.length > 0;
- let {onSelectNode} = this.props;
- return (
- <div key={node.name} className='tree-block-inside'>
- {
- <div onDoubleClick={() => this.props.toggleExpanded(path)} className={this.getTreeRowClassName(node.name)}>
- {
- isFolder &&
- <div onClick={() => this.props.toggleExpanded(path)} className={classNames('tree-node-expander', {'tree-node-expander-collapsed': !node.expanded})}>
- <FontAwesome name='caret-down'/>
- </div>
- }
- {
-
- <span className='tree-node-icon'>
- <FontAwesome name={typeToIcon[node.type]}/>
- </span>
- }
- {
-
- <span onClick={() => onSelectNode(node.name)} className={this.getTreeTextClassName(node)}>
- {node.name}
- </span>
- }
- </div>
- }
- {
- isFolder &&
- <Collapse in={node.expanded}>
- <div className='tree-node-children'>
- {
- node.children.map((child, ind) => this.renderNode(child, [...path, ind]))
- }
- </div>
- </Collapse>
- }
+ <Tabs id='attachments-tabs' activeKey={this.state.activeTab} onSelect={key => this.handleTabPress(key)}>
+ <Tab eventKey={tabsMapping.SETUP} title='HEAT Setup'>
+ <HeatSetupComponent
+ heatDataExist={heatDataExist}
+ changeAttachmentsTab={tab => this.setState({activeTab: tab})}
+ onProcessAndValidate={onProcessAndValidate}
+ softwareProductId={softwareProductId}
+ isReadOnlyMode={isReadOnlyMode}
+ version={version}/>
+ </Tab>
+ <Tab eventKey={tabsMapping.VALIDATION} title='Heat Validation' disabled={!isValidationAvailable}>
+ <HeatValidation {...other}/>
+ </Tab>
+ </Tabs>
</div>
);
}
- createErrorList(errorList, node, parent) {
- if (node.errors) {
- node.errors.forEach(error => errorList.push({
- error,
- name: node.name,
- parentName: parent.name,
- type: node.type
- }));
+ handleTabPress(key) {
+ let {heatSetup, heatSetupCache, onProcessAndValidate, isReadOnlyMode, version} = this.props;
+ switch (key) {
+ case tabsMapping.VALIDATION:
+ onProcessAndValidate({heatData: heatSetup, heatDataCache: heatSetupCache, isReadOnlyMode, version}).then(
+ () => this.setState({activeTab: tabsMapping.VALIDATION})
+ );
+ return;
+ case tabsMapping.SETUP:
+ this.setState({activeTab: tabsMapping.SETUP});
+ return;
}
- if (node.children && node.children.length) {
- node.children.map((child) => this.createErrorList(errorList, child, node));
- }
- }
-
- renderErrorList(errors) {
- let prevError = {};
- let {selectedNode} = this.props;
- return errors.map(error => {
- let isSameNodeError = error.name === prevError.name && error.parentName === prevError.parentName;
- prevError = error;
-
- return (
- <div
- key={error.name + error.errorMessage + error.parentName}
-
- onClick={() => this.selectNode(error.name)}
- className={classNames('error-item', {'clicked': selectedNode === error.name, 'shifted': !isSameNodeError})}>
- <span className={classNames('error-item-file-type', {'strong': !isSameNodeError})}>
- {
- error.hasParent ?
- i18n('{type} {name} in {parentName}: ', {
- type: nodeTypes[error.type],
- name: error.name,
- parentName: error.parentName
- }) :
- i18n('{type} {name}: ', {
- type: nodeTypes[error.type],
- name: error.name
- })
- }
- </span>
- <span className={`error-item-file-type ${error.errorLevel}`}> {error.errorMessage} </span>
- </div>
- );
- });
}
- selectNode(currentSelectedNode) {
- let {onUnselectNode, onSelectNode, selectedNode} = this.props;
- if (currentSelectedNode !== selectedNode) {
- onSelectNode(currentSelectedNode);
- }else{
- onUnselectNode();
- }
-
- }
-
- getTreeRowClassName(name) {
- let {hoveredNode, selectedNode} = this.props;
- return classNames({
- 'tree-node-row': true,
- 'tree-node-selected': name === hoveredNode,
- 'tree-node-clicked': name === selectedNode
- });
+ handleImport(evt) {
+ evt.preventDefault();
+ let {version} = this.props;
+ let formData = new FormData();
+ formData.append('upload', this.refs.hiddenImportFileInput.files[0]);
+ this.refs.hiddenImportFileInput.value = '';
+ this.props.onUpload(formData, version);
+ this.setState({activeTab: tabsMapping.SETUP});
}
- getTreeTextClassName(node) {
- let {selectedNode} = this.props;
- return classNames({
- 'tree-element-text': true,
- 'error-status': node.errors,
- 'error-status-selected': node.name === selectedNode
- });
+ save() {
+ return this.props.onSave(this.props.heatSetup, this.props.version);
}
- onChangeTreeWidth(e) {
- if (e.button === mouseActions.MOUSE_BUTTON_CLICK) {
- let onMouseMove = (e) => {
- this.setState({treeWidth: e.clientX - leftPanelWidth});
- };
- let onMouseUp = () => {
- document.removeEventListener('mousemove', onMouseMove);
- document.removeEventListener('mouseup', onMouseUp);
- };
- document.addEventListener('mousemove', onMouseMove);
- document.addEventListener('mouseup', onMouseUp);
- }
- }
}
-export default SoftwareProductAttachmentsView;
+export default HeatScreenView;