/*!
* 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 classNames from 'classnames';
import Collapse from 'react-bootstrap/lib/Collapse.js';
import Icon from 'nfvo-components/icon/Icon.jsx';
import SVGIcon from 'nfvo-components/icon/SVGIcon.jsx';
import i18n from 'nfvo-utils/i18n/i18n.js';
import {mouseActions, errorLevels, nodeFilters} from './HeatValidationConstants.js';
const leftPanelWidth = 250;
const typeToIcon = Object.freeze({
heat: 'heat',
volume: 'volume',
network: 'network',
artifact: 'validation-artifacts',
env: 'env',
other: 'validation-other'
});
class HeatValidationView extends Component {
static propTypes = {
attachmentsTree: PropTypes.object.isRequired,
errorList: PropTypes.array.isRequired,
currentErrors: PropTypes.array.isRequired,
currentWarnings: PropTypes.array.isRequired,
onSelectNode: PropTypes.func.isRequired,
onDeselectNode: PropTypes.func.isRequired,
toggleExpanded: PropTypes.func.isRequired,
selectedNode: PropTypes.string
};
render() {
return (
);
}
}
function HeatFileTreeRow(props) {
let {node, path, toggleExpanded, selectedNode, selectNode} = props;
let isFolder = node.children && node.children.length > 0;
return (
toggleExpanded(path)} className={classNames({
'tree-node-row': true,
'tree-node-clicked': node.name === props.selectedNode
})} data-test-id='validation-tree-node'>
{
isFolder &&
toggleExpanded(path)}
className='tree-node-expander'>
}
{
}
{
selectNode(node.name)} data-test-id='validation-tree-node-name'>
{node.name ? node.name : 'UNKNOWN'}
}
selectNode(node.name)} />
);
}
function HeatFileTreeHeader(props) {
let hasErrors = props.errorList.filter(error => error.level === errorLevels.ERROR).length > 0;
return (
props.selectNode(nodeFilters.ALL)} className={classNames({'attachments-tree-header': true,
'header-selected' : props.selectedNode === nodeFilters.ALL})} data-test-id='validation-tree-header'>
{i18n(`HEAT${hasErrors ? ' (Draft)' : ''}`)}
);
}
class HeatFileTree extends React.Component {
static propTypes = {
attachmentsTree: PropTypes.object.isRequired,
errorList: PropTypes.array.isRequired,
onSelectNode: PropTypes.func.isRequired,
onDeselectNode: PropTypes.func.isRequired,
toggleExpanded: PropTypes.func.isRequired,
selectedNode: PropTypes.string
};
state = {
treeWidth: '400'
};
render() {
let {attachmentsTree} = this.props;
return (
{attachmentsTree && attachmentsTree.children && attachmentsTree.children.map((child, ind) => this.renderNode(child, [ind]))}
this.onChangeTreeWidth(e)}
className='vsp-attachments-heat-validation-separator' data-test-id='validation-tree-separator'>
);
}
renderNode(node, path) {
let rand = Math.random() * (3000 - 1) + 1;
let isFolder = node.children && node.children.length > 0;
let {selectedNode} = this.props;
return (
{
node.header ?
this.selectNode(nodeName)} /> :
this.selectNode(node.name)} />
}
{
isFolder &&
{
node.children.map((child, ind) => this.renderNode(child, [...path, ind]))
}
}
);
}
selectNode(currentSelectedNode) {
let {onDeselectNode, onSelectNode, selectedNode} = this.props;
if (currentSelectedNode !== selectedNode) {
onSelectNode(currentSelectedNode);
} else {
onDeselectNode();
}
}
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);
}
}
}
class HeatMessageBoard extends Component {
static propTypes = {
currentErrors: PropTypes.array,
currentWarnings: PropTypes.array,
selectedNode: PropTypes.string
};
render() {
let {errors, warnings} = this.props;
let allItems = [...errors, ...warnings];
return (
{ allItems.map(error => this.renderError(error)) }
);
}
renderError(error) {
let rand = Math.random() * (3000 - 1) + 1;
return (
{error.level === errorLevels.WARNING ?
: }
{
(this.props.selectedNode === nodeFilters.ALL) ?
{i18n('{errorName}:', {
errorName: error.name
})}
{i18n('{message}', {message: error.errorMessage})}
:
i18n('{errorMsg}', {
errorMsg: error.errorMessage
})
}
);
}
}
class ErrorsAndWarningsCount extends Component {
static propTypes = {
errorList: PropTypes.array,
size: PropTypes.string
};
render() {
let errors = this.getErrorsAndWarningsCount(this.props.errorList);
if (!errors) {
return null;
}
let errIcon = 'error';
let {size} = this.props;
if (size && size === 'large') {
errIcon += '-lg';
}
return (
{(errors.errorCount > 0) &&
}
{(errors.warningCount > 0) &&
}
);
}
getErrorsAndWarningsCount(errorList) {
let errorCount = 0, warningCount = 0;
if (errorList && errorList.length > 0) {
for (let i = 0; i < errorList.length; i++) {
if (errorList[i].level === errorLevels.ERROR) {
errorCount++;
} else if (errorList[i].level === errorLevels.WARNING) {
warningCount++;
}
}
}
if (errorCount === 0 && warningCount === 0) {
return null;
}
return {errorCount, warningCount};
}
}
export default HeatValidationView;