/*!
* 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 } from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import Collapse from 'react-bootstrap/lib/Collapse.js';
import SVGIcon from 'sdc-ui/lib/react/SVGIcon.js';
import i18n from 'nfvo-utils/i18n/i18n.js';
import {
mouseActions,
errorLevels,
nodeFilters
} from './HeatValidationConstants.js';
const leftPanelWidth = 250;
const typeToIcon = Object.freeze({
heat: 'nestedHeat',
volume: 'base',
network: 'network',
artifact: 'artifacts',
env: 'env',
other: '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('{title} {hasErrors}', {
title: props.headerTitle,
hasErrors: 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 ? (
{error.name}
{error.errorMessage}
) : (
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 { size } = this.props;
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;