aboutsummaryrefslogtreecommitdiffstats
path: root/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/validation/HeatValidationView.jsx
diff options
context:
space:
mode:
Diffstat (limited to 'openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/validation/HeatValidationView.jsx')
-rw-r--r--openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/validation/HeatValidationView.jsx542
1 files changed, 320 insertions, 222 deletions
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/validation/HeatValidationView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/validation/HeatValidationView.jsx
index 3fdaa9c591..c6ee5efd36 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/validation/HeatValidationView.jsx
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/attachments/validation/HeatValidationView.jsx
@@ -13,254 +13,352 @@
* or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/
-import React, {Component} from 'react';
+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';
+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'
+ 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
+ };
- 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 (<div className='vsp-attachments-heat-validation' data-test-id='heat-validation-editor'>
- <HeatFileTree errorList={this.props.errorList} attachmentsTree={this.props.attachmentsTree}
- onSelectNode={this.props.onSelectNode} toggleExpanded={this.props.toggleExpanded}
- selectedNode={this.props.selectedNode} onDeselectNode={this.props.onDeselectNode} />
- <HeatMessageBoard errors={this.props.currentErrors} warnings={this.props.currentWarnings} selectedNode={this.props.selectedNode} />
- </div> );
- }
+ render() {
+ return (
+ <div
+ className="vsp-attachments-heat-validation"
+ data-test-id="heat-validation-editor">
+ <HeatFileTree
+ errorList={this.props.errorList}
+ attachmentsTree={this.props.attachmentsTree}
+ onSelectNode={this.props.onSelectNode}
+ toggleExpanded={this.props.toggleExpanded}
+ selectedNode={this.props.selectedNode}
+ onDeselectNode={this.props.onDeselectNode}
+ />
+ <HeatMessageBoard
+ errors={this.props.currentErrors}
+ warnings={this.props.currentWarnings}
+ selectedNode={this.props.selectedNode}
+ />
+ </div>
+ );
+ }
}
function HeatFileTreeRow(props) {
- let {node, path, toggleExpanded, selectedNode, selectNode} = props;
- let isFolder = node.children && node.children.length > 0;
- return (
- <div onDoubleClick={() => toggleExpanded(path)} className={classNames({
- 'tree-node-row': true,
- 'tree-node-clicked': node.name === props.selectedNode
- })} data-test-id='validation-tree-node'>
- <div className='name-section'>
- {
- isFolder &&
- <div onClick={() => toggleExpanded(path)}
- className='tree-node-expander'>
- <SVGIcon name={!node.expanded ? 'chevronUp' : 'chevronDown'} data-test-id='validation-tree-block-toggle'/>
- </div>
- }
- {
-
- <span className='tree-node-icon'>
- <SVGIcon name={typeToIcon[node.type]} color={selectedNode === node.name ? 'primary' : 'secondary'}/>
- </span>
- }
- {
-
- <span className='tree-node-name' onClick={() => selectNode(node.name)} data-test-id='validation-tree-node-name'>
- {node.name ? node.name : 'UNKNOWN'}
- </span>
- }
- </div>
- <ErrorsAndWarningsCount errorList={node.errors} onClick={() => selectNode(node.name)} />
- </div>);
+ let { node, path, toggleExpanded, selectedNode, selectNode } = props;
+ let isFolder = node.children && node.children.length > 0;
+ return (
+ <div
+ onDoubleClick={() => toggleExpanded(path)}
+ className={classNames({
+ 'tree-node-row': true,
+ 'tree-node-clicked': node.name === props.selectedNode
+ })}
+ data-test-id="validation-tree-node">
+ <div className="name-section">
+ {isFolder && (
+ <div
+ onClick={() => toggleExpanded(path)}
+ className="tree-node-expander">
+ <SVGIcon
+ name={!node.expanded ? 'chevronUp' : 'chevronDown'}
+ data-test-id="validation-tree-block-toggle"
+ />
+ </div>
+ )}
+ {
+ <span className="tree-node-icon">
+ <SVGIcon
+ name={typeToIcon[node.type]}
+ color={
+ selectedNode === node.name
+ ? 'primary'
+ : 'secondary'
+ }
+ />
+ </span>
+ }
+ {
+ <span
+ className="tree-node-name"
+ onClick={() => selectNode(node.name)}
+ data-test-id="validation-tree-node-name">
+ {node.name ? node.name : 'UNKNOWN'}
+ </span>
+ }
+ </div>
+ <ErrorsAndWarningsCount
+ errorList={node.errors}
+ onClick={() => selectNode(node.name)}
+ />
+ </div>
+ );
}
function HeatFileTreeHeader(props) {
- let hasErrors = props.errorList.filter(error => error.level === errorLevels.ERROR).length > 0;
- return (
- <div onClick={() => props.selectNode(nodeFilters.ALL)} className={classNames({'attachments-tree-header': true,
- 'header-selected' : props.selectedNode === nodeFilters.ALL})} data-test-id='validation-tree-header'>
- <div className='tree-header-title' >
- {/*<SVGIcon name='zip' color={props.selectedNode === nodeFilters.ALL ? 'primary' : ''} iconClassName='header-icon' />*/}
- <span className={classNames({'tree-header-title-text' : true,
- 'tree-header-title-selected' : props.selectedNode === nodeFilters.ALL})}>{i18n('{title} {hasErrors}', {title: props.headerTitle, hasErrors: hasErrors ? '(Draft)' : ''})}</span>
- </div>
- <ErrorsAndWarningsCount errorList={props.errorList} size='large' />
- </div>);
+ let hasErrors =
+ props.errorList.filter(error => error.level === errorLevels.ERROR)
+ .length > 0;
+ return (
+ <div
+ onClick={() => props.selectNode(nodeFilters.ALL)}
+ className={classNames({
+ 'attachments-tree-header': true,
+ 'header-selected': props.selectedNode === nodeFilters.ALL
+ })}
+ data-test-id="validation-tree-header">
+ <div className="tree-header-title">
+ {/*<SVGIcon name='zip' color={props.selectedNode === nodeFilters.ALL ? 'primary' : ''} iconClassName='header-icon' />*/}
+ <span
+ className={classNames({
+ 'tree-header-title-text': true,
+ 'tree-header-title-selected':
+ props.selectedNode === nodeFilters.ALL
+ })}>
+ {i18n('{title} {hasErrors}', {
+ title: props.headerTitle,
+ hasErrors: hasErrors ? '(Draft)' : ''
+ })}
+ </span>
+ </div>
+ <ErrorsAndWarningsCount errorList={props.errorList} size="large" />
+ </div>
+ );
}
-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 (
- <div className='validation-tree-section' style={{'width' : this.state.treeWidth + 'px'}}>
- <div className='vsp-attachments-heat-validation-tree'>
- <div className='tree-wrapper'>
- {attachmentsTree && attachmentsTree.children && attachmentsTree.children.map((child, ind) => this.renderNode(child, [ind]))}
- </div>
- </div>
- <div onMouseDown={(e) => this.onChangeTreeWidth(e)}
- className='vsp-attachments-heat-validation-separator' data-test-id='validation-tree-separator'></div>
- </div>);
- }
- renderNode(node, path) {
- let rand = Math.random() * (3000 - 1) + 1;
- let isFolder = node.children && node.children.length > 0;
- let {selectedNode} = this.props;
- return (
- <div key={node.name + rand} className={classNames({'tree-block-inside' : !node.header})}>
- {
- node.header ?
- <HeatFileTreeHeader headerTitle={node.name} selectedNode={selectedNode} errorList={this.props.errorList} selectNode={(nodeName) => this.selectNode(nodeName)} /> :
- <HeatFileTreeRow toggleExpanded={this.props.toggleExpanded} node={node} path={path} selectedNode={selectedNode} selectNode={() => this.selectNode(node.name)} />
- }
- {
- isFolder &&
- <Collapse in={node.expanded}>
- <div className='tree-node-children'>
- {
- node.children.map((child, ind) => this.renderNode(child, [...path, ind]))
- }
- </div>
- </Collapse>
- }
- </div>
- );
- }
-
-
-
-
-
- selectNode(currentSelectedNode) {
- let {onDeselectNode, onSelectNode, selectedNode} = this.props;
- if (currentSelectedNode !== selectedNode) {
- onSelectNode(currentSelectedNode);
- } else {
- onDeselectNode();
- }
-
-
+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 (
+ <div
+ className="validation-tree-section"
+ style={{ width: this.state.treeWidth + 'px' }}>
+ <div className="vsp-attachments-heat-validation-tree">
+ <div className="tree-wrapper">
+ {attachmentsTree &&
+ attachmentsTree.children &&
+ attachmentsTree.children.map((child, ind) =>
+ this.renderNode(child, [ind])
+ )}
+ </div>
+ </div>
+ <div
+ onMouseDown={e => this.onChangeTreeWidth(e)}
+ className="vsp-attachments-heat-validation-separator"
+ data-test-id="validation-tree-separator"
+ />
+ </div>
+ );
+ }
+ renderNode(node, path) {
+ let rand = Math.random() * (3000 - 1) + 1;
+ let isFolder = node.children && node.children.length > 0;
+ let { selectedNode } = this.props;
+ return (
+ <div
+ key={node.name + rand}
+ className={classNames({ 'tree-block-inside': !node.header })}>
+ {node.header ? (
+ <HeatFileTreeHeader
+ headerTitle={node.name}
+ selectedNode={selectedNode}
+ errorList={this.props.errorList}
+ selectNode={nodeName => this.selectNode(nodeName)}
+ />
+ ) : (
+ <HeatFileTreeRow
+ toggleExpanded={this.props.toggleExpanded}
+ node={node}
+ path={path}
+ selectedNode={selectedNode}
+ selectNode={() => this.selectNode(node.name)}
+ />
+ )}
+ {isFolder && (
+ <Collapse in={node.expanded}>
+ <div className="tree-node-children">
+ {node.children.map((child, ind) =>
+ this.renderNode(child, [...path, ind])
+ )}
+ </div>
+ </Collapse>
+ )}
+ </div>
+ );
+ }
- }
+ 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);
- }
- }
+ 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 (
- <div className='message-board-section'>
- { allItems.map(error => this.renderError(error)) }
- </div>
- );
- }
- renderError(error) {
- let rand = Math.random() * (3000 - 1) + 1;
- return (
- <div
- key={error.name + error.errorMessage + error.parentName + rand}
- className='error-item' data-test-id='validation-error'>
- {error.level === errorLevels.WARNING ?
- <SVGIcon name='exclamationTriangleLine' iconClassName='large' color='warning' /> : <SVGIcon name='error' iconClassName='large' color='negative' /> }
- <span className='error-item-file-type'>
- {
- (this.props.selectedNode === nodeFilters.ALL) ?
- <span>
- <span className='error-file-name'>
- {error.name}
- </span>
- <span>
- {error.errorMessage}
- </span>
- </span> :
- error.errorMessage
- }
- </span>
- </div>
- );
- }
+ static propTypes = {
+ currentErrors: PropTypes.array,
+ currentWarnings: PropTypes.array,
+ selectedNode: PropTypes.string
+ };
+ render() {
+ let { errors, warnings } = this.props;
+ let allItems = [...errors, ...warnings];
+ return (
+ <div className="message-board-section">
+ {allItems.map(error => this.renderError(error))}
+ </div>
+ );
+ }
+ renderError(error) {
+ let rand = Math.random() * (3000 - 1) + 1;
+ return (
+ <div
+ key={error.name + error.errorMessage + error.parentName + rand}
+ className="error-item"
+ data-test-id="validation-error">
+ {error.level === errorLevels.WARNING ? (
+ <SVGIcon
+ name="exclamationTriangleLine"
+ iconClassName="large"
+ color="warning"
+ />
+ ) : (
+ <SVGIcon
+ name="error"
+ iconClassName="large"
+ color="negative"
+ />
+ )}
+ <span className="error-item-file-type">
+ {this.props.selectedNode === nodeFilters.ALL ? (
+ <span>
+ <span className="error-file-name">
+ {error.name}
+ </span>
+ <span>{error.errorMessage}</span>
+ </span>
+ ) : (
+ error.errorMessage
+ )}
+ </span>
+ </div>
+ );
+ }
}
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 (<div className='counters'>
- {(errors.errorCount > 0) && <div className='counter'>
- <SVGIcon name='error' color='negative' iconClassName={size}/>
- <div className={'error-text ' + (size ? size : '')} data-test-id='validation-error-count'>{errors.errorCount}</div>
- </div>}
- {(errors.warningCount > 0) && <div className='counter'>
- <SVGIcon name='exclamationTriangleLine' iconClassName={size} color='warning'/>
- <div className={'warning-text ' + (size ? size : '')} data-test-id='validation-warning-count'>{errors.warningCount}</div>
- </div>}
- </div>);
- }
- 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};
- }
+ 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 (
+ <div className="counters">
+ {errors.errorCount > 0 && (
+ <div className="counter">
+ <SVGIcon
+ name="error"
+ color="negative"
+ iconClassName={size}
+ />
+ <div
+ className={'error-text ' + (size ? size : '')}
+ data-test-id="validation-error-count">
+ {errors.errorCount}
+ </div>
+ </div>
+ )}
+ {errors.warningCount > 0 && (
+ <div className="counter">
+ <SVGIcon
+ name="exclamationTriangleLine"
+ iconClassName={size}
+ color="warning"
+ />
+ <div
+ className={'warning-text ' + (size ? size : '')}
+ data-test-id="validation-warning-count">
+ {errors.warningCount}
+ </div>
+ </div>
+ )}
+ </div>
+ );
+ }
+ 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;