Add new code new version
[sdc.git] / openecomp-ui / src / sdc-app / heatvalidation / attachments / AttachmentsView.jsx
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';
5
6 import i18n from 'nfvo-utils/i18n/i18n.js';
7 import {nodeTypes, mouseActions} from './AttachmentsConstants';
8
9 const typeToIcon = Object.freeze({
10         heat: 'building-o',
11         volume: 'database',
12         network: 'cloud',
13         artifact: 'gear',
14         env: 'server',
15         other: 'cube'
16 });
17
18 const leftPanelWidth = 250;
19
20 class SoftwareProductAttachmentsView extends React.Component {
21
22         static propTypes = {
23                 attachmentsTree: React.PropTypes.object.isRequired
24         };
25         state = {
26                 treeWidth: '400',
27         };
28
29         render() {
30                 let {attachmentsTree, errorList = []} = this.props;
31
32                 let {treeWidth} = this.state;
33                 return (
34                         <div className='software-product-attachments'>
35                                 <div className='software-product-view'>
36                                         <div className='software-product-landing-view-right-side'>
37                                                 <div className='software-product-attachments-main'>
38                                                         <div className='software-product-attachments-tree' style={{'width' : treeWidth + 'px'}}>
39                                                                 <div className='tree-wrapper'>
40                                                                         {
41                                                                                 attachmentsTree && attachmentsTree.children && attachmentsTree.children.map((child, ind) => this.renderNode(child, [ind]))
42                                                                         }
43                                                                 </div>
44                                                         </div>
45                                                         <div className='software-product-attachments-separator' onMouseDown={e => this.onChangeTreeWidth(e)} />
46                                                         <div className='software-product-attachments-error-list'>
47                                                                 {errorList.length ? this.renderErrorList(errorList) : <div className='no-errors'>{attachmentsTree.children ?
48                                                                         i18n('VALIDATION SUCCESS') : i18n('THERE IS NO HEAT DATA TO PRESENT') }</div>}
49                                                         </div>
50                                                 </div>
51                                         </div>
52                                 </div>
53                         </div>
54                 );
55         }
56
57
58
59         renderNode(node, path) {
60                 let isFolder = node.children && node.children.length > 0;
61                 let {onSelectNode} = this.props;
62                 return (
63                         <div key={node.name} className='tree-block-inside'>
64                                 {
65                                         <div onDoubleClick={() => this.props.toggleExpanded(path)} className={this.getTreeRowClassName(node.name)}>
66                                                 {
67                                                         isFolder &&
68                                                         <div onClick={() => this.props.toggleExpanded(path)} className={classNames('tree-node-expander', {'tree-node-expander-collapsed': !node.expanded})}>
69                                                                 <FontAwesome name='caret-down'/>
70                                                         </div>
71                                                 }
72                                                 {
73
74                                                         <span className='tree-node-icon'>
75                                                                 <FontAwesome name={typeToIcon[node.type]}/>
76                                                         </span>
77                                                 }
78                                                 {
79
80                                                         <span onClick={() => onSelectNode(node.name)} className={this.getTreeTextClassName(node)}>
81                                                         {node.name}
82                                                         </span>
83                                                 }
84                                         </div>
85                                 }
86                                 {
87                                         isFolder &&
88                                         <Collapse in={node.expanded}>
89                                                 <div className='tree-node-children'>
90                                                         {
91                                                                 node.children.map((child, ind) => this.renderNode(child, [...path, ind]))
92                                                         }
93                                                 </div>
94                                         </Collapse>
95                                 }
96                         </div>
97                 );
98         }
99
100         createErrorList(errorList, node, parent) {
101                 if (node.errors) {
102                         node.errors.forEach(error => errorList.push({
103                                 error,
104                                 name: node.name,
105                                 parentName: parent.name,
106                                 type: node.type
107                         }));
108                 }
109                 if (node.children && node.children.length) {
110                         node.children.map((child) => this.createErrorList(errorList, child, node));
111                 }
112         }
113
114         renderErrorList(errors) {
115                 let prevError = {};
116                 let {selectedNode} = this.props;
117                 return errors.map(error => {
118                         let isSameNodeError = error.name === prevError.name && error.parentName === prevError.parentName;
119                         prevError = error;
120
121                         return (
122                                 <div
123                                         key={error.name + error.errorMessage + error.parentName}
124
125                                         onClick={() => this.selectNode(error.name)}
126                                         className={classNames('error-item', {'clicked': selectedNode === error.name, 'shifted': !isSameNodeError})}>
127                                         <span className={classNames('error-item-file-type', {'strong': !isSameNodeError})}>
128                                         {
129                                                 error.hasParent ?
130                                                         i18n('{type}  {name} in {parentName}: ', {
131                                                                 type: nodeTypes[error.type],
132                                                                 name: error.name,
133                                                                 parentName: error.parentName
134                                                         }) :
135                                                         i18n('{type}  {name}: ', {
136                                                                 type: nodeTypes[error.type],
137                                                                 name: error.name
138                                                         })
139                                         }
140                                         </span>
141                                         <span className={`error-item-file-type ${error.errorLevel}`}> {error.errorMessage} </span>
142                                 </div>
143                         );
144                 });
145         }
146
147         selectNode(currentSelectedNode) {
148                 let {onUnselectNode, onSelectNode, selectedNode} = this.props;
149                 if (currentSelectedNode !== selectedNode) {
150                         onSelectNode(currentSelectedNode);
151                 }else{
152                         onUnselectNode();
153                 }
154
155         }
156
157         getTreeRowClassName(name) {
158                 let {hoveredNode, selectedNode} = this.props;
159                 return classNames({
160                         'tree-node-row': true,
161                         'tree-node-selected': name === hoveredNode,
162                         'tree-node-clicked': name === selectedNode
163                 });
164         }
165
166         getTreeTextClassName(node) {
167                 let {selectedNode} = this.props;
168                 return classNames({
169                         'tree-element-text': true,
170                         'error-status': node.errors,
171                         'error-status-selected': node.name === selectedNode
172                 });
173         }
174
175         onChangeTreeWidth(e) {
176                 if (e.button === mouseActions.MOUSE_BUTTON_CLICK) {
177                         let onMouseMove = (e) => {
178                                 this.setState({treeWidth: e.clientX - leftPanelWidth});
179                         };
180                         let onMouseUp = () => {
181                                 document.removeEventListener('mousemove', onMouseMove);
182                                 document.removeEventListener('mouseup', onMouseUp);
183                         };
184                         document.addEventListener('mousemove', onMouseMove);
185                         document.addEventListener('mouseup', onMouseUp);
186                 }
187         }
188 }
189
190 export default SoftwareProductAttachmentsView;