/*! * 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.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;