/*! * 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 '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: '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(`${error.name}`)} {i18n(error.errorMessage)} : i18n(error.errorMesage) }
); } } 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.errorCount}
} {(errors.warningCount > 0) &&
{errors.warningCount}
}
); } 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;