1 import React from 'react';
2 import FontAwesome from 'react-fontawesome';
3 import classNames from 'classnames';
4 import Collapse from 'react-bootstrap/lib/Collapse.js';
6 import i18n from 'nfvo-utils/i18n/i18n.js';
7 import {nodeTypes, mouseActions} from './SoftwareProductAttachmentsConstants';
9 const typeToIcon = Object.freeze({
18 const leftPanelWidth = 250;
20 class SoftwareProductAttachmentsView extends React.Component {
23 attachmentsTree: React.PropTypes.object.isRequired
30 let {attachmentsTree, errorList} = this.props;
31 let {treeWidth} = this.state;
33 <div className='software-product-attachments'>
34 <div className='software-product-attachments-tree' style={{'width' : treeWidth + 'px'}}>
35 <div className='tree-wrapper'>
37 attachmentsTree && attachmentsTree.children && attachmentsTree.children.map((child, ind) => this.renderNode(child, [ind]))
41 <div onMouseDown={(e) => this.onChangeTreeWidth(e)} className='software-product-attachments-separator'/>
43 <div className='software-product-attachments-error-list'>
44 {errorList.length ? this.renderErrorList(errorList) : <div className='no-errors'>{attachmentsTree.children ?
45 i18n('VALIDATION SUCCESS') : i18n('THERE IS NO HEAT DATA TO PRESENT') }</div>}
51 renderNode(node, path) {
52 let isFolder = node.children && node.children.length > 0;
53 let {onSelectNode} = this.props;
55 <div key={node.name} className='tree-block-inside'>
57 <div onDoubleClick={() => this.props.toggleExpanded(path)} className={this.getTreeRowClassName(node.name)}>
60 <div onClick={() => this.props.toggleExpanded(path)} className={classNames('tree-node-expander', {'tree-node-expander-collapsed': !node.expanded})}>
61 <FontAwesome name='caret-down'/>
66 <span className='tree-node-icon'>
67 <FontAwesome name={typeToIcon[node.type]}/>
72 <span onClick={() => onSelectNode(node.name)} className={this.getTreeTextClassName(node)}>
80 <Collapse in={node.expanded}>
81 <div className='tree-node-children'>
83 node.children.map((child, ind) => this.renderNode(child, [...path, ind]))
92 createErrorList(errorList, node, parent) {
94 node.errors.forEach(error => errorList.push({
97 parentName: parent.name,
101 if (node.children && node.children.length) {
102 node.children.map((child) => this.createErrorList(errorList, child, node));
106 renderErrorList(errors) {
108 let {selectedNode} = this.props;
109 return errors.map(error => {
110 let isSameNodeError = error.name === prevError.name && error.parentName === prevError.parentName;
115 key={error.name + error.errorMessage + error.parentName}
117 onClick={() => this.selectNode(error.name)}
118 className={classNames('error-item', {'clicked': selectedNode === error.name, 'shifted': !isSameNodeError})}>
119 <span className={classNames('error-item-file-type', {'strong': !isSameNodeError})}>
122 i18n('{type} {name} in {parentName}: ', {
123 type: nodeTypes[error.type],
125 parentName: error.parentName
127 i18n('{type} {name}: ', {
128 type: nodeTypes[error.type],
133 <span className={`error-item-file-type ${error.errorLevel}`}> {error.errorMessage} </span>
139 selectNode(currentSelectedNode) {
140 let {onUnselectNode, onSelectNode, selectedNode} = this.props;
141 if (currentSelectedNode !== selectedNode) {
142 onSelectNode(currentSelectedNode);
149 getTreeRowClassName(name) {
150 let {hoveredNode, selectedNode} = this.props;
152 'tree-node-row': true,
153 'tree-node-selected': name === hoveredNode,
154 'tree-node-clicked': name === selectedNode
158 getTreeTextClassName(node) {
159 let {selectedNode} = this.props;
161 'tree-element-text': true,
162 'error-status': node.errors,
163 'error-status-selected': node.name === selectedNode
167 onChangeTreeWidth(e) {
168 if (e.button === mouseActions.MOUSE_BUTTON_CLICK) {
169 let onMouseMove = (e) => {
170 this.setState({treeWidth: e.clientX - leftPanelWidth});
172 let onMouseUp = () => {
173 document.removeEventListener('mousemove', onMouseMove);
174 document.removeEventListener('mouseup', onMouseUp);
176 document.addEventListener('mousemove', onMouseMove);
177 document.addEventListener('mouseup', onMouseUp);
182 export default SoftwareProductAttachmentsView;