[SDC-29] Amdocs OnBoard 1707 initial commit.
[sdc.git] / openecomp-ui / src / sdc-app / onboarding / softwareProduct / attachments / SoftwareProductAttachmentsView.jsx
index c52999c..66fb2f8 100644 (file)
-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;