import React from 'react'; import FontAwesome from 'react-fontawesome'; import classNames from 'classnames'; import Collapse from 'react-bootstrap/lib/Collapse.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' }); const leftPanelWidth = 250; class SoftwareProductAttachmentsView extends React.Component { static propTypes = { attachmentsTree: React.PropTypes.object.isRequired }; state = { treeWidth: '400' }; render() { let {attachmentsTree, errorList} = this.props; let {treeWidth} = this.state; return (
{ attachmentsTree && attachmentsTree.children && attachmentsTree.children.map((child, ind) => this.renderNode(child, [ind])) }
this.onChangeTreeWidth(e)} className='software-product-attachments-separator'/>
{errorList.length ? this.renderErrorList(errorList) :
{attachmentsTree.children ? i18n('VALIDATION SUCCESS') : i18n('THERE IS NO HEAT DATA TO PRESENT') }
}
); } renderNode(node, path) { let isFolder = node.children && node.children.length > 0; let {onSelectNode} = this.props; return (
{
this.props.toggleExpanded(path)} className={this.getTreeRowClassName(node.name)}> { isFolder &&
this.props.toggleExpanded(path)} className={classNames('tree-node-expander', {'tree-node-expander-collapsed': !node.expanded})}>
} { } { onSelectNode(node.name)} className={this.getTreeTextClassName(node)}> {node.name} }
} { isFolder &&
{ node.children.map((child, ind) => this.renderNode(child, [...path, ind])) }
}
); } createErrorList(errorList, node, parent) { if (node.errors) { node.errors.forEach(error => errorList.push({ error, name: node.name, parentName: parent.name, type: node.type })); } 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 (
this.selectNode(error.name)} className={classNames('error-item', {'clicked': selectedNode === error.name, 'shifted': !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 }) } {error.errorMessage}
); }); } 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 }); } getTreeTextClassName(node) { let {selectedNode} = this.props; return classNames({ 'tree-element-text': true, 'error-status': node.errors, 'error-status-selected': node.name === selectedNode }); } 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;