aboutsummaryrefslogtreecommitdiffstats
path: root/openecomp-ui/src/nfvo-components
diff options
context:
space:
mode:
Diffstat (limited to 'openecomp-ui/src/nfvo-components')
-rw-r--r--openecomp-ui/src/nfvo-components/SubmitErrorResponse.jsx228
-rw-r--r--openecomp-ui/src/nfvo-components/accordion/Accordion.jsx63
-rw-r--r--openecomp-ui/src/nfvo-components/datepicker/Datepicker.jsx151
-rw-r--r--openecomp-ui/src/nfvo-components/editor/TabulatedEditor.jsx165
-rw-r--r--openecomp-ui/src/nfvo-components/fileupload/DraggableUploadFileBox.jsx35
-rw-r--r--openecomp-ui/src/nfvo-components/grid/GridItem.jsx21
-rw-r--r--openecomp-ui/src/nfvo-components/grid/GridSection.jsx35
-rw-r--r--openecomp-ui/src/nfvo-components/input/ExpandableInput.jsx177
-rw-r--r--openecomp-ui/src/nfvo-components/input/SelectInput.jsx68
-rw-r--r--openecomp-ui/src/nfvo-components/input/ToggleInput.jsx93
-rw-r--r--openecomp-ui/src/nfvo-components/input/dualListbox/DualListboxView.jsx348
-rw-r--r--openecomp-ui/src/nfvo-components/input/validation/Form.jsx272
-rw-r--r--openecomp-ui/src/nfvo-components/input/validation/Input.jsx404
-rw-r--r--openecomp-ui/src/nfvo-components/input/validation/InputOptions.jsx545
-rw-r--r--openecomp-ui/src/nfvo-components/input/validation/InputWrapper.jsx255
-rw-r--r--openecomp-ui/src/nfvo-components/input/validation/Tabs.jsx116
-rw-r--r--openecomp-ui/src/nfvo-components/input/validation/ValidationButtons.jsx81
-rw-r--r--openecomp-ui/src/nfvo-components/listEditor/ListEditorItemView.jsx108
-rw-r--r--openecomp-ui/src/nfvo-components/listEditor/ListEditorItemViewField.jsx6
-rw-r--r--openecomp-ui/src/nfvo-components/listEditor/ListEditorView.jsx148
-rw-r--r--openecomp-ui/src/nfvo-components/listEditor/listEditor.stories.js77
-rw-r--r--openecomp-ui/src/nfvo-components/loader/Loader.jsx61
-rw-r--r--openecomp-ui/src/nfvo-components/loader/LoaderConstants.js8
-rw-r--r--openecomp-ui/src/nfvo-components/loader/LoaderReducer.js85
-rw-r--r--openecomp-ui/src/nfvo-components/modal/GlobalModal.js280
-rw-r--r--openecomp-ui/src/nfvo-components/modal/GlobalModalConstants.js26
-rw-r--r--openecomp-ui/src/nfvo-components/modal/GlobalModalReducer.js58
-rw-r--r--openecomp-ui/src/nfvo-components/modal/Modal.jsx102
-rw-r--r--openecomp-ui/src/nfvo-components/overlay/Overlay.jsx32
-rw-r--r--openecomp-ui/src/nfvo-components/panel/NavigationSideBar.jsx219
-rw-r--r--openecomp-ui/src/nfvo-components/panel/versionController/VersionController.jsx323
-rw-r--r--openecomp-ui/src/nfvo-components/panel/versionController/VersionControllerConstants.js10
-rw-r--r--openecomp-ui/src/nfvo-components/panel/versionController/components/ActionButtons.jsx227
-rw-r--r--openecomp-ui/src/nfvo-components/panel/versionController/components/CommitCommentModal.jsx87
-rw-r--r--openecomp-ui/src/nfvo-components/panel/versionController/components/Permissions.jsx106
-rw-r--r--openecomp-ui/src/nfvo-components/progressBar/ProgressBar.jsx33
-rw-r--r--openecomp-ui/src/nfvo-components/table/SelectActionTable.jsx75
-rw-r--r--openecomp-ui/src/nfvo-components/table/SelectActionTableCell.jsx36
-rw-r--r--openecomp-ui/src/nfvo-components/table/SelectActionTableRow.jsx77
-rw-r--r--openecomp-ui/src/nfvo-components/tree/Tree.jsx406
-rw-r--r--openecomp-ui/src/nfvo-components/tree/Tree.stories.js242
41 files changed, 3470 insertions, 2419 deletions
diff --git a/openecomp-ui/src/nfvo-components/SubmitErrorResponse.jsx b/openecomp-ui/src/nfvo-components/SubmitErrorResponse.jsx
index c15cd1d0e8..56382d6325 100644
--- a/openecomp-ui/src/nfvo-components/SubmitErrorResponse.jsx
+++ b/openecomp-ui/src/nfvo-components/SubmitErrorResponse.jsx
@@ -13,11 +13,11 @@
* 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 ListGroupItem from 'react-bootstrap/lib/ListGroupItem.js';
import i18n from 'nfvo-utils/i18n/i18n.js';
import SVGIcon from 'sdc-ui/lib/react/SVGIcon.js';
-import {Collapse} from 'react-bootstrap';
+import { Collapse } from 'react-bootstrap';
/**
* parsing and showing the following Java Response object
*
@@ -42,121 +42,151 @@ import {Collapse} from 'react-bootstrap';
}
*/
class SubmitErrorResponse extends Component {
+ render() {
+ let {
+ validationResponse: {
+ vspErrors,
+ licensingDataErrors,
+ questionnaireValidationResult,
+ uploadDataErrors
+ }
+ } = this.props;
+ return (
+ <div className="submit-error-response-view">
+ {vspErrors && this.renderVspErrors(vspErrors)}
+ {licensingDataErrors &&
+ this.renderVspErrors(licensingDataErrors)}
+ {questionnaireValidationResult &&
+ this.renderComponentsErrors(questionnaireValidationResult)}
+ {uploadDataErrors &&
+ this.renderUploadDataErrors(uploadDataErrors)}
+ </div>
+ );
+ }
+ renderVspErrors(errors) {
+ return (
+ <ErrorBlock errorType={i18n('VSP Errors')}>
+ <div>
+ {errors.length &&
+ errors.map((error, i) => {
+ return (
+ <ErrorMessage key={i} error={error.message} />
+ );
+ })}
+ </div>
+ </ErrorBlock>
+ );
+ }
- render() {
- let {validationResponse : {vspErrors, licensingDataErrors, questionnaireValidationResult, uploadDataErrors}} = this.props;
- return (
- <div className='submit-error-response-view'>
- {vspErrors && this.renderVspErrors(vspErrors)}
- {licensingDataErrors && this.renderVspErrors(licensingDataErrors)}
- {questionnaireValidationResult && this.renderComponentsErrors(questionnaireValidationResult)}
- {uploadDataErrors && this.renderUploadDataErrors(uploadDataErrors)}
- </div>
- );
- }
-
- renderVspErrors(errors) {
- return (
- <ErrorBlock errorType={i18n('VSP Errors')}>
- <div>
- {errors.length && errors.map((error, i) => {return (<ErrorMessage key={i} error={error.message}/>);})}
- </div>
- </ErrorBlock>
- );
- }
-
-
- renderComponentsErrors(errors) {
- return (
- <ErrorBlock errorType={i18n('Components Errors')}>
- <div>
- {errors.validationData.length && errors.validationData.map((item, i) =>{ return (<ComponentError key={i} item={item}/>);})}
- </div>
- </ErrorBlock>
- );
- }
+ renderComponentsErrors(errors) {
+ return (
+ <ErrorBlock errorType={i18n('Components Errors')}>
+ <div>
+ {errors.validationData.length &&
+ errors.validationData.map((item, i) => {
+ return <ComponentError key={i} item={item} />;
+ })}
+ </div>
+ </ErrorBlock>
+ );
+ }
- renderUploadDataErrors(uploadDataErrors) {
- return (
- <ErrorBlock errorType={i18n('Upload Data Errors')}>
- <div>
- <UploadErrorList items={uploadDataErrors}/>
- </div>
- </ErrorBlock>
- );
- }
+ renderUploadDataErrors(uploadDataErrors) {
+ return (
+ <ErrorBlock errorType={i18n('Upload Data Errors')}>
+ <div>
+ <UploadErrorList items={uploadDataErrors} />
+ </div>
+ </ErrorBlock>
+ );
+ }
}
-
-const ComponentError = ({item}) => {
- return (
- <div>
- <div className='component-name-header'>{item.entityName}</div>
- {item.errors.map((error, i) => {return(<ErrorMessage key={i} error={error}/>);})}
- </div>
- );
+const ComponentError = ({ item }) => {
+ return (
+ <div>
+ <div className="component-name-header">{item.entityName}</div>
+ {item.errors.map((error, i) => {
+ return <ErrorMessage key={i} error={error} />;
+ })}
+ </div>
+ );
};
function* entries(obj) {
- for (let key of Object.keys(obj)) {
- yield {header: key, list: obj[key]};
- }
+ for (let key of Object.keys(obj)) {
+ yield { header: key, list: obj[key] };
+ }
}
-const UploadErrorList = ({items}) => {
- let generator = entries(items);
-
- let errors = [];
- for (let item of generator) {errors.push(
- <div key={item.header}>
- <div className='component-name-header'>{item.header}</div>
- {item.list.map((error, i) => <ErrorMessage key={i} warning={error.level === 'WARNING'} error={error.message}/> )}
- </div>
- );}
+const UploadErrorList = ({ items }) => {
+ let generator = entries(items);
+
+ let errors = [];
+ for (let item of generator) {
+ errors.push(
+ <div key={item.header}>
+ <div className="component-name-header">{item.header}</div>
+ {item.list.map((error, i) => (
+ <ErrorMessage
+ key={i}
+ warning={error.level === 'WARNING'}
+ error={error.message}
+ />
+ ))}
+ </div>
+ );
+ }
- return (
- <div>
- {errors}
- </div>
- );
+ return <div>{errors}</div>;
};
class ErrorBlock extends React.Component {
- state = {
- collapsed: false
- };
-
- render() {
- let {errorType, children} = this.props;
- return (
- <div className='error-block'>
- <ErrorHeader collapsed={this.state.collapsed} onClick={()=>{this.setState({collapsed: !this.state.collapsed});}} errorType={errorType}/>
- <Collapse in={this.state.collapsed}>
- {children}
- </Collapse>
- </div>
- );
- }
+ state = {
+ collapsed: false
+ };
+
+ render() {
+ let { errorType, children } = this.props;
+ return (
+ <div className="error-block">
+ <ErrorHeader
+ collapsed={this.state.collapsed}
+ onClick={() => {
+ this.setState({ collapsed: !this.state.collapsed });
+ }}
+ errorType={errorType}
+ />
+ <Collapse in={this.state.collapsed}>{children}</Collapse>
+ </div>
+ );
+ }
}
-const ErrorHeader = ({errorType, collapsed, onClick}) => {
- return(
- <div onClick={onClick} className='error-block-header'>
- <SVGIcon iconClassName={collapsed ? '' : 'collapse-right' } name='chevronDown' label={errorType} labelPosition='right'/>
- </div>
- );
+const ErrorHeader = ({ errorType, collapsed, onClick }) => {
+ return (
+ <div onClick={onClick} className="error-block-header">
+ <SVGIcon
+ iconClassName={collapsed ? '' : 'collapse-right'}
+ name="chevronDown"
+ label={errorType}
+ labelPosition="right"
+ />
+ </div>
+ );
};
-const ErrorMessage = ({error, warning}) => {
- return (
- <ListGroupItem className='error-code-list-item'>
- <SVGIcon
- name={warning ? 'exclamationTriangleLine' : 'error'}
- color={warning ? 'warning' : 'negative'} />
- <span className='icon-label'>{error}</span>
- </ListGroupItem>
- );
+const ErrorMessage = ({ error, warning }) => {
+ return (
+ <ListGroupItem className="error-code-list-item">
+ <SVGIcon
+ name={warning ? 'exclamationTriangleLine' : 'error'}
+ color={warning ? 'warning' : 'negative'}
+ />
+ <span className="icon-label">{error}</span>
+ </ListGroupItem>
+ );
};
export default SubmitErrorResponse;
diff --git a/openecomp-ui/src/nfvo-components/accordion/Accordion.jsx b/openecomp-ui/src/nfvo-components/accordion/Accordion.jsx
index ac19072307..72f8de0d23 100644
--- a/openecomp-ui/src/nfvo-components/accordion/Accordion.jsx
+++ b/openecomp-ui/src/nfvo-components/accordion/Accordion.jsx
@@ -4,9 +4,9 @@
* 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.
@@ -18,35 +18,38 @@ import React from 'react';
import SVGIcon from 'sdc-ui/lib/react/SVGIcon.js';
import PropTypes from 'prop-types';
-
class Accordion extends React.Component {
+ static propTypes = {
+ title: PropTypes.string,
+ children: PropTypes.node
+ };
- static propTypes = {
- title: PropTypes.string,
- children: PropTypes.node
- }
-
- constructor(props) {
- super(props);
- this.state = {
- open: false
- };
- }
- render() {
- const {children, title} = this.props;
- const {open} = this.state;
- return (
- <div className='accordion'>
- <div onClick={()=>this.setState({open: !open})} className='accordion-header'>
- <SVGIcon name='chevronUp' iconClassName={open ? 'down' : ''}/>
- <div className='title'>{title}</div>
- </div>
- <div className={`accordion-body ${open ? 'open' : ''}`}>
- {children}
- </div>
- </div>
- );
- }
+ constructor(props) {
+ super(props);
+ this.state = {
+ open: false
+ };
+ }
+ render() {
+ const { children, title } = this.props;
+ const { open } = this.state;
+ return (
+ <div className="accordion">
+ <div
+ onClick={() => this.setState({ open: !open })}
+ className="accordion-header">
+ <SVGIcon
+ name="chevronUp"
+ iconClassName={open ? 'down' : ''}
+ />
+ <div className="title">{title}</div>
+ </div>
+ <div className={`accordion-body ${open ? 'open' : ''}`}>
+ {children}
+ </div>
+ </div>
+ );
+ }
}
-export default Accordion; \ No newline at end of file
+export default Accordion;
diff --git a/openecomp-ui/src/nfvo-components/datepicker/Datepicker.jsx b/openecomp-ui/src/nfvo-components/datepicker/Datepicker.jsx
index 25e7e7e02d..b4bc8be9ec 100644
--- a/openecomp-ui/src/nfvo-components/datepicker/Datepicker.jsx
+++ b/openecomp-ui/src/nfvo-components/datepicker/Datepicker.jsx
@@ -5,72 +5,105 @@ import moment from 'moment';
import SVGIcon from 'sdc-ui/lib/react/SVGIcon.js';
class CustomInput extends React.Component {
+ static propTypes = {
+ placeHolderText: PropTypes.string,
+ onChange: PropTypes.func,
+ onClick: PropTypes.func,
+ value: PropTypes.string
+ };
- static propTypes = {
- placeHolderText: PropTypes.string,
- onChange: PropTypes.func,
- onClick: PropTypes.func,
- value: PropTypes.string
- };
-
- render() {
- const {placeholderText, onClick, onClear, inputRef, value: date} = this.props;
- const text = date ? date : placeholderText;
- const textStyle = date ? '' : 'placeholder';
- return (
- <div onClick={onClick} ref={inputRef} className='datepicker-custom-input'>
- <div className={`datepicker-text ${textStyle}`}>{text}</div>
- {date && <SVGIcon onClick={e => {e.stopPropagation(); onClear();}} name='close' className='clear-input'/>}
- <SVGIcon name='calendar'/>
- </div>
- );
- }
-};
+ render() {
+ const {
+ placeholderText,
+ onClick,
+ onClear,
+ inputRef,
+ value: date
+ } = this.props;
+ const text = date ? date : placeholderText;
+ const textStyle = date ? '' : 'placeholder';
+ return (
+ <div
+ onClick={onClick}
+ ref={inputRef}
+ className="datepicker-custom-input">
+ <div className={`datepicker-text ${textStyle}`}>{text}</div>
+ {date && (
+ <SVGIcon
+ onClick={e => {
+ e.stopPropagation();
+ onClear();
+ }}
+ name="close"
+ className="clear-input"
+ />
+ )}
+ <SVGIcon name="calendar" />
+ </div>
+ );
+ }
+}
const parseDate = (date, format) => {
- return typeof date === 'number' ? moment.unix(date) : moment(date, format);
+ return typeof date === 'number' ? moment.unix(date) : moment(date, format);
};
class Datepicker extends React.Component {
- static propTypes = {
- date: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
- format: PropTypes.string,
- onChange: PropTypes.func,
- selectsStart: PropTypes.bool,
- selectsEnd: PropTypes.bool,
- startDate: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
- endDate: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
- disabled: PropTypes.bool,
- label: PropTypes.string,
- isRequired: PropTypes.bool
- }
- render() {
- let {date, format, onChange, selectsStart = false, startDate = null, endDate = null, selectsEnd = false,
- disabled = false, inputRef} = this.props;
- const placeholderText = 'Enter a date';
- const props = {
- format,
- onChange,
- disabled,
- selected: date ? parseDate(date, format) : date,
- selectsStart,
- selectsEnd,
- placeholderText,
- startDate: startDate ? parseDate(startDate, format) : startDate,
- endDate: endDate ? parseDate(endDate, format) : endDate
- };
+ static propTypes = {
+ date: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
+ format: PropTypes.string,
+ onChange: PropTypes.func,
+ selectsStart: PropTypes.bool,
+ selectsEnd: PropTypes.bool,
+ startDate: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
+ endDate: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
+ disabled: PropTypes.bool,
+ label: PropTypes.string,
+ isRequired: PropTypes.bool
+ };
+ render() {
+ let {
+ date,
+ format,
+ onChange,
+ selectsStart = false,
+ startDate = null,
+ endDate = null,
+ selectsEnd = false,
+ disabled = false,
+ inputRef
+ } = this.props;
+ const placeholderText = 'Enter a date';
+ const props = {
+ format,
+ onChange,
+ disabled,
+ selected: date ? parseDate(date, format) : date,
+ selectsStart,
+ selectsEnd,
+ placeholderText,
+ startDate: startDate ? parseDate(startDate, format) : startDate,
+ endDate: endDate ? parseDate(endDate, format) : endDate
+ };
- return (
- <div className='customized-date-picker'>
- <DatePicker
- calendarClassName='customized-date-picker-calendar'
- customInput={<CustomInput inputRef={inputRef} onClear={() => onChange(undefined)} placeholderText={placeholderText}/>}
- minDate={selectsEnd && props.startDate}
- maxDate={selectsStart && props.endDate}
- {...props}/>
- </div>
- );
- }
+ return (
+ <div className="customized-date-picker">
+ <DatePicker
+ calendarClassName="customized-date-picker-calendar"
+ customInput={
+ <CustomInput
+ inputRef={inputRef}
+ onClear={() => onChange(undefined)}
+ placeholderText={placeholderText}
+ />
+ }
+ minDate={selectsEnd && props.startDate}
+ maxDate={selectsStart && props.endDate}
+ {...props}
+ />
+ </div>
+ );
+ }
}
export default Datepicker;
diff --git a/openecomp-ui/src/nfvo-components/editor/TabulatedEditor.jsx b/openecomp-ui/src/nfvo-components/editor/TabulatedEditor.jsx
index 3c9ceed0d8..9fcd7042bc 100644
--- a/openecomp-ui/src/nfvo-components/editor/TabulatedEditor.jsx
+++ b/openecomp-ui/src/nfvo-components/editor/TabulatedEditor.jsx
@@ -20,79 +20,106 @@ import VersionController from 'nfvo-components/panel/versionController/VersionCo
import NavigationSideBar from 'nfvo-components/panel/NavigationSideBar.jsx';
export default class TabulatedEditor extends React.Component {
+ render() {
+ const {
+ navigationBarProps,
+ onToggle,
+ onVersionSwitching,
+ onMoreVersionsClick,
+ onCreate,
+ onSave,
+ onClose,
+ onVersionControllerAction,
+ onNavigate,
+ children,
+ meta,
+ onManagePermissions,
+ onOpenCommentCommitModal,
+ onOpenPermissions,
+ onOpenRevisionsModal
+ } = this.props;
+ let { versionControllerProps } = this.props;
+ const { className = '' } = React.Children.only(children).props;
+ const child = this.prepareChild();
- render() {
- const {navigationBarProps, onToggle, onVersionSwitching, onMoreVersionsClick, onCreate, onSave, onClose,
- onVersionControllerAction, onNavigate, children, meta, onManagePermissions, onOpenCommentCommitModal, onOpenPermissions, onOpenRevisionsModal} = this.props;
- let {versionControllerProps} = this.props;
- const {className = ''} = React.Children.only(children).props;
- const child = this.prepareChild();
+ if (onClose) {
+ versionControllerProps = {
+ ...versionControllerProps,
+ onClose: () => onClose(versionControllerProps)
+ };
+ }
+ return (
+ <div className="software-product-view">
+ <div className="software-product-navigation-side-bar">
+ <NavigationSideBar
+ {...navigationBarProps}
+ onSelect={onNavigate}
+ onToggle={onToggle}
+ />
+ </div>
+ <div className="software-product-landing-view-right-side flex-column">
+ <VersionController
+ {...versionControllerProps}
+ onVersionSwitching={version =>
+ onVersionSwitching(version, meta)
+ }
+ onMoreVersionsClick={onMoreVersionsClick}
+ onManagePermissions={onManagePermissions}
+ onOpenCommentCommitModal={onOpenCommentCommitModal}
+ onOpenPermissions={onOpenPermissions}
+ onOpenRevisionsModal={onOpenRevisionsModal}
+ callVCAction={(action, version, comment) =>
+ onVersionControllerAction(
+ action,
+ version,
+ comment,
+ meta
+ )
+ }
+ onCreate={onCreate && this.handleCreate}
+ onSave={onSave && this.handleSave}
+ />
+ <div className={classnames('content-area', `${className}`)}>
+ {child}
+ </div>
+ </div>
+ </div>
+ );
+ }
- if(onClose) {
- versionControllerProps = {
- ...versionControllerProps,
- onClose: () => onClose(versionControllerProps)
- };
- }
- return (
- <div className='software-product-view'>
- <div className='software-product-navigation-side-bar'>
- <NavigationSideBar {...navigationBarProps} onSelect={onNavigate} onToggle={onToggle}/>
- </div>
- <div className='software-product-landing-view-right-side flex-column'>
- <VersionController
- {...versionControllerProps}
- onVersionSwitching={version => onVersionSwitching(version, meta)}
- onMoreVersionsClick={onMoreVersionsClick}
- onManagePermissions={onManagePermissions}
- onOpenCommentCommitModal={onOpenCommentCommitModal}
- onOpenPermissions={onOpenPermissions}
- onOpenRevisionsModal={onOpenRevisionsModal}
- callVCAction={(action, version, comment) => onVersionControllerAction(action, version, comment, meta)}
- onCreate={onCreate && this.handleCreate}
- onSave={onSave && this.handleSave}/>
- <div className={classnames('content-area', `${className}`)}>
- {
- child
- }
- </div>
- </div>
- </div>
- );
- }
+ prepareChild() {
+ const { onSave, onCreate, children } = this.props;
- prepareChild() {
- const {onSave, onCreate, children} = this.props;
+ const additionalChildProps = { ref: 'editor' };
+ if (onSave) {
+ additionalChildProps.onSave = onSave;
+ }
+ if (onCreate) {
+ additionalChildProps.onCreate = onCreate;
+ }
- const additionalChildProps = {ref: 'editor'};
- if (onSave) {
- additionalChildProps.onSave = onSave;
- }
- if (onCreate) {
- additionalChildProps.onCreate = onCreate;
- }
+ const child = React.cloneElement(
+ React.Children.only(children),
+ additionalChildProps
+ );
+ return child;
+ }
- const child = React.cloneElement(React.Children.only(children), additionalChildProps);
- return child;
- }
+ handleSave = () => {
+ const childInstance = this.refs.editor.getWrappedInstance();
+ if (childInstance.save) {
+ return childInstance.save();
+ } else {
+ return this.props.onSave();
+ }
+ };
-
-
- handleSave = () => {
- const childInstance = this.refs.editor.getWrappedInstance();
- if (childInstance.save) {
- return childInstance.save();
- } else {
- return this.props.onSave();
- }
- };
-
- handleCreate = () => {
- const childInstance = this.refs.editor.getWrappedInstance();
- if (childInstance.create) {
- childInstance.create();
- } else {
- this.props.onCreate();
- }
- }
+ handleCreate = () => {
+ const childInstance = this.refs.editor.getWrappedInstance();
+ if (childInstance.create) {
+ childInstance.create();
+ } else {
+ this.props.onCreate();
+ }
+ };
}
diff --git a/openecomp-ui/src/nfvo-components/fileupload/DraggableUploadFileBox.jsx b/openecomp-ui/src/nfvo-components/fileupload/DraggableUploadFileBox.jsx
index 5b4e0a8bee..0d47d859d9 100644
--- a/openecomp-ui/src/nfvo-components/fileupload/DraggableUploadFileBox.jsx
+++ b/openecomp-ui/src/nfvo-components/fileupload/DraggableUploadFileBox.jsx
@@ -26,20 +26,33 @@
* or
* https://github.com/JedWatson/react-select
*/
-import React, {Component} from 'react';
+import React, { Component } from 'react';
import i18n from 'nfvo-utils/i18n/i18n.js';
import Button from 'sdc-ui/lib/react/Button.js';
class DraggableUploadFileBox extends Component {
- render() {
- let {className, onClick, dataTestId, isReadOnlyMode} = this.props;
- return (
- <div className={`file-upload-box ${className} ${isReadOnlyMode ? 'disabled' : ''}`}>
- <div className={`drag-text ${isReadOnlyMode ? 'disabled' : ''}`}>{i18n('Drag & drop for upload')}</div>
- <div className='or-text'>{i18n('or')}</div>
- <Button type='button' data-test-id={dataTestId} btnType='outline' onClick={onClick} disabled={isReadOnlyMode}>{i18n('Select File')}</Button>
- </div>
- );
- }
+ render() {
+ let { className, onClick, dataTestId, isReadOnlyMode } = this.props;
+ return (
+ <div
+ className={`file-upload-box ${className} ${
+ isReadOnlyMode ? 'disabled' : ''
+ }`}>
+ <div
+ className={`drag-text ${isReadOnlyMode ? 'disabled' : ''}`}>
+ {i18n('Drag & drop for upload')}
+ </div>
+ <div className="or-text">{i18n('or')}</div>
+ <Button
+ type="button"
+ data-test-id={dataTestId}
+ btnType="outline"
+ onClick={onClick}
+ disabled={isReadOnlyMode}>
+ {i18n('Select File')}
+ </Button>
+ </div>
+ );
+ }
}
export default DraggableUploadFileBox;
diff --git a/openecomp-ui/src/nfvo-components/grid/GridItem.jsx b/openecomp-ui/src/nfvo-components/grid/GridItem.jsx
index c62e042bf4..9723cde2c0 100644
--- a/openecomp-ui/src/nfvo-components/grid/GridItem.jsx
+++ b/openecomp-ui/src/nfvo-components/grid/GridItem.jsx
@@ -15,12 +15,21 @@
*/
import React from 'react';
-const GridItem = ({colSpan = 1, children, lastColInRow = false, stretch = false, className = ''}) => (
- <div className={`grid-col-${colSpan} ${lastColInRow ? 'last-col-in-row' : ''} ${className}`}>
- <div className={`grid-item${stretch ? '-stretch' : ''}`}>
- {children}
- </div>
- </div>
+const GridItem = ({
+ colSpan = 1,
+ children,
+ lastColInRow = false,
+ stretch = false,
+ className = ''
+}) => (
+ <div
+ className={`grid-col-${colSpan} ${
+ lastColInRow ? 'last-col-in-row' : ''
+ } ${className}`}>
+ <div className={`grid-item${stretch ? '-stretch' : ''}`}>
+ {children}
+ </div>
+ </div>
);
export default GridItem;
diff --git a/openecomp-ui/src/nfvo-components/grid/GridSection.jsx b/openecomp-ui/src/nfvo-components/grid/GridSection.jsx
index 8f4a024fdb..f2e3588d9e 100644
--- a/openecomp-ui/src/nfvo-components/grid/GridSection.jsx
+++ b/openecomp-ui/src/nfvo-components/grid/GridSection.jsx
@@ -17,21 +17,32 @@ import React from 'react';
import PropTypes from 'prop-types';
import classnames from 'classnames';
-const GridSection = ({title, children, className = '', titleClassName, hasLastColSet = false}) => {
- return (
- <div className={classnames('grid-section', className, {'has-last-col-set': hasLastColSet})}>
- {title && <div className={`section-title ${titleClassName || ''}`}>{title}</div>}
- <div className='grid-items'>
- {children}
- </div>
- </div>
- );
+const GridSection = ({
+ title,
+ children,
+ className = '',
+ titleClassName,
+ hasLastColSet = false
+}) => {
+ return (
+ <div
+ className={classnames('grid-section', className, {
+ 'has-last-col-set': hasLastColSet
+ })}>
+ {title && (
+ <div className={`section-title ${titleClassName || ''}`}>
+ {title}
+ </div>
+ )}
+ <div className="grid-items">{children}</div>
+ </div>
+ );
};
GridSection.propTypes = {
- title: PropTypes.string,
- titleClassName: PropTypes.string,
- hasLastColSet: PropTypes.bool
+ title: PropTypes.string,
+ titleClassName: PropTypes.string,
+ hasLastColSet: PropTypes.bool
};
export default GridSection;
diff --git a/openecomp-ui/src/nfvo-components/input/ExpandableInput.jsx b/openecomp-ui/src/nfvo-components/input/ExpandableInput.jsx
index 82fbe1deed..3973ae8c5d 100644
--- a/openecomp-ui/src/nfvo-components/input/ExpandableInput.jsx
+++ b/openecomp-ui/src/nfvo-components/input/ExpandableInput.jsx
@@ -19,99 +19,118 @@ import ReactDOM from 'react-dom';
import SVGIcon from 'sdc-ui/lib/react/SVGIcon.js';
import Input from 'nfvo-components/input/validation/InputWrapper.jsx';
-const ExpandableInputClosed = ({iconType, onClick}) => (
- <SVGIcon className='expandable-input-wrapper closed' data-test-id='expandable-input-closed' name={iconType} onClick={onClick} />
+const ExpandableInputClosed = ({ iconType, onClick }) => (
+ <SVGIcon
+ className="expandable-input-wrapper closed"
+ data-test-id="expandable-input-closed"
+ name={iconType}
+ onClick={onClick}
+ />
);
class ExpandableInputOpened extends React.Component {
- componentDidMount(){
- this.rawDomNode = ReactDOM.findDOMNode(this.searchInputNode.inputWrapper);
- this.rawDomNode.focus();
- }
+ componentDidMount() {
+ this.rawDomNode = ReactDOM.findDOMNode(
+ this.searchInputNode.inputWrapper
+ );
+ this.rawDomNode.focus();
+ }
- componentWillReceiveProps(newProps){
- if (!newProps.value){
- if (!(document.activeElement === this.rawDomNode)){
- this.props.handleBlur();
- }
- }
- }
+ componentWillReceiveProps(newProps) {
+ if (!newProps.value) {
+ if (!(document.activeElement === this.rawDomNode)) {
+ this.props.handleBlur();
+ }
+ }
+ }
- handleClose(){
- this.props.onChange('');
- this.rawDomNode.focus();
- }
+ handleClose() {
+ this.props.onChange('');
+ this.rawDomNode.focus();
+ }
- handleKeyDown(e){
- if (e.key === 'Escape'){
- e.preventDefault();
- if (this.props.value) {
- this.handleClose();
- } else {
- this.rawDomNode.blur();
- }
- };
- }
+ handleKeyDown(e) {
+ if (e.key === 'Escape') {
+ e.preventDefault();
+ if (this.props.value) {
+ this.handleClose();
+ } else {
+ this.rawDomNode.blur();
+ }
+ }
+ }
- render() {
- let {iconType, value, onChange, handleBlur} = this.props;
- return (
- <div className='expandable-input-wrapper opened' key='expandable'>
- <Input
- type='text'
- data-test-id='expandable-input-opened'
- value={value}
- ref={(input) => this.searchInputNode = input}
- className='expandable-active'
- groupClassName='expandable-input-control'
- onChange={e => onChange(e)}
- onKeyDown={e => this.handleKeyDown(e)}
- onBlur={handleBlur}/>
- {value && <SVGIcon data-test-id='expandable-input-close-btn' onClick={() => this.handleClose()} name='close' />}
- {!value && <SVGIcon name={iconType} onClick={handleBlur}/>}
- </div>
- );
- }
+ render() {
+ let { iconType, value, onChange, handleBlur } = this.props;
+ return (
+ <div className="expandable-input-wrapper opened" key="expandable">
+ <Input
+ type="text"
+ data-test-id="expandable-input-opened"
+ value={value}
+ ref={input => (this.searchInputNode = input)}
+ className="expandable-active"
+ groupClassName="expandable-input-control"
+ onChange={e => onChange(e)}
+ onKeyDown={e => this.handleKeyDown(e)}
+ onBlur={handleBlur}
+ />
+ {value && (
+ <SVGIcon
+ data-test-id="expandable-input-close-btn"
+ onClick={() => this.handleClose()}
+ name="close"
+ />
+ )}
+ {!value && <SVGIcon name={iconType} onClick={handleBlur} />}
+ </div>
+ );
+ }
}
class ExpandableInput extends React.Component {
+ static propTypes = {
+ iconType: PropTypes.string,
+ onChange: PropTypes.func,
+ value: PropTypes.string
+ };
- static propTypes = {
- iconType: PropTypes.string,
- onChange: PropTypes.func,
- value: PropTypes.string
- };
+ state = { showInput: false };
- state = {showInput: false};
+ closeInput() {
+ if (!this.props.value) {
+ this.setState({ showInput: false });
+ }
+ }
- closeInput(){
- if (!this.props.value) {
- this.setState({showInput: false});
- }
- }
+ getValue() {
+ return this.props.value;
+ }
- getValue(){
- return this.props.value;
- }
-
- render(){
- let {iconType, value, onChange = false} = this.props;
- return (
- <div className='expandable-input-top'>
- {this.state.showInput &&
- <ExpandableInputOpened
- key='open'
- iconType={iconType}
- onChange={onChange}
- value={value}
- handleKeyDown={(e) => this.handleKeyDown(e)}
- handleBlur={() => this.closeInput()}/>
- }
- {!this.state.showInput && <ExpandableInputClosed key='closed' iconType={iconType} onClick={() => this.setState({showInput: true})} />}
- </div>
- );
- }
+ render() {
+ let { iconType, value, onChange = false } = this.props;
+ return (
+ <div className="expandable-input-top">
+ {this.state.showInput && (
+ <ExpandableInputOpened
+ key="open"
+ iconType={iconType}
+ onChange={onChange}
+ value={value}
+ handleKeyDown={e => this.handleKeyDown(e)}
+ handleBlur={() => this.closeInput()}
+ />
+ )}
+ {!this.state.showInput && (
+ <ExpandableInputClosed
+ key="closed"
+ iconType={iconType}
+ onClick={() => this.setState({ showInput: true })}
+ />
+ )}
+ </div>
+ );
+ }
}
-
export default ExpandableInput;
diff --git a/openecomp-ui/src/nfvo-components/input/SelectInput.jsx b/openecomp-ui/src/nfvo-components/input/SelectInput.jsx
index 03c727379e..b0e0d87d7c 100644
--- a/openecomp-ui/src/nfvo-components/input/SelectInput.jsx
+++ b/openecomp-ui/src/nfvo-components/input/SelectInput.jsx
@@ -26,43 +26,51 @@
* or
* https://github.com/JedWatson/react-select
*/
-import React, {Component} from 'react';
+import React, { Component } from 'react';
import Select from 'react-select';
class SelectInput extends Component {
+ inputValue = [];
- inputValue = [];
+ render() {
+ let { label, value, ...other } = this.props;
+ const dataTestId = this.props['data-test-id']
+ ? { 'data-test-id': this.props['data-test-id'] }
+ : {};
+ return (
+ <div
+ {...dataTestId}
+ className="validation-input-wrapper dropdown-multi-select">
+ <div className="form-group">
+ {label && <label className="control-label">{label}</label>}
+ <Select
+ ref="_myInput"
+ onChange={value => this.onSelectChanged(value)}
+ {...other}
+ value={value}
+ />
+ </div>
+ </div>
+ );
+ }
- render() {
- let {label, value, ...other} = this.props;
- const dataTestId = this.props['data-test-id'] ? {'data-test-id': this.props['data-test-id']} : {};
- return (
- <div {...dataTestId} className='validation-input-wrapper dropdown-multi-select'>
- <div className='form-group'>
- {label && <label className='control-label'>{label}</label>}
- <Select ref='_myInput' onChange={value => this.onSelectChanged(value)} {...other} value={value} />
- </div>
- </div>
- );
- }
+ getValue() {
+ return this.inputValue && this.inputValue.length ? this.inputValue : '';
+ }
- getValue() {
- return this.inputValue && this.inputValue.length ? this.inputValue : '';
- }
+ onSelectChanged(value) {
+ this.props.onMultiSelectChanged(value);
+ }
- onSelectChanged(value) {
- this.props.onMultiSelectChanged(value);
- }
-
- componentDidMount() {
- let {value} = this.props;
- this.inputValue = value ? value : [];
- }
- componentDidUpdate() {
- if (this.inputValue !== this.props.value) {
- this.inputValue = this.props.value;
- }
- }
+ componentDidMount() {
+ let { value } = this.props;
+ this.inputValue = value ? value : [];
+ }
+ componentDidUpdate() {
+ if (this.inputValue !== this.props.value) {
+ this.inputValue = this.props.value;
+ }
+ }
}
export default SelectInput;
diff --git a/openecomp-ui/src/nfvo-components/input/ToggleInput.jsx b/openecomp-ui/src/nfvo-components/input/ToggleInput.jsx
index 31a8a66d86..947570fa29 100644
--- a/openecomp-ui/src/nfvo-components/input/ToggleInput.jsx
+++ b/openecomp-ui/src/nfvo-components/input/ToggleInput.jsx
@@ -16,55 +16,60 @@
import React from 'react';
import PropTypes from 'prop-types';
-export default
-class ToggleInput extends React.Component {
+export default class ToggleInput extends React.Component {
+ static propTypes = {
+ label: PropTypes.node,
+ value: PropTypes.bool,
+ onChange: PropTypes.func,
+ disabled: PropTypes.bool
+ };
- static propTypes = {
- label: PropTypes.node,
- value: PropTypes.bool,
- onChange: PropTypes.func,
- disabled: PropTypes.bool
- }
+ static defaultProps = {
+ value: false,
+ label: ''
+ };
- static defaultProps = {
- value: false,
- label: ''
- }
+ state = {
+ value: this.props.value
+ };
- state = {
- value: this.props.value
- }
+ status() {
+ return this.state.value ? 'on' : 'off';
+ }
- status() {
- return this.state.value ? 'on' : 'off';
- }
+ render() {
+ let { label, disabled } = this.props;
+ let checked = this.status() === 'on';
+ //TODO check onclick
+ return (
+ <div
+ className="toggle-input-wrapper form-group"
+ onClick={!disabled && this.click}>
+ <div className="toggle-input-label">{label}</div>
+ <div className="toggle-switch">
+ <input
+ className="toggle toggle-round-flat"
+ type="checkbox"
+ checked={checked}
+ readOnly
+ />
+ <label />
+ </div>
+ </div>
+ );
+ }
- render() {
- let {label, disabled} = this.props;
- let checked = this.status() === 'on';
- //TODO check onclick
- return (
- <div className='toggle-input-wrapper form-group' onClick={!disabled && this.click}>
- <div className='toggle-input-label'>{label}</div>
- <div className='toggle-switch'>
- <input className='toggle toggle-round-flat' type='checkbox' checked={checked} readOnly/>
- <label></label>
- </div>
- </div>
- );
- }
+ click = () => {
+ let value = !this.state.value;
+ this.setState({ value });
- click = () => {
- let value = !this.state.value;
- this.setState({value});
+ let onChange = this.props.onChange;
+ if (onChange) {
+ onChange(value);
+ }
+ };
- let onChange = this.props.onChange;
- if (onChange) {
- onChange(value);
- }
- }
-
- getValue() {
- return this.state.value;
- }
+ getValue() {
+ return this.state.value;
+ }
}
diff --git a/openecomp-ui/src/nfvo-components/input/dualListbox/DualListboxView.jsx b/openecomp-ui/src/nfvo-components/input/dualListbox/DualListboxView.jsx
index a689c50778..7ab4c8242c 100644
--- a/openecomp-ui/src/nfvo-components/input/dualListbox/DualListboxView.jsx
+++ b/openecomp-ui/src/nfvo-components/input/dualListbox/DualListboxView.jsx
@@ -19,136 +19,224 @@ import SVGIcon from 'sdc-ui/lib/react/SVGIcon.js';
import Input from 'nfvo-components/input/validation/InputWrapper.jsx';
class DualListboxView extends React.Component {
-
- static propTypes = {
-
- availableList: PropTypes.arrayOf(PropTypes.shape({
- id: PropTypes.string.isRequired,
- name: PropTypes.string.isRequired
- })),
- filterTitle: PropTypes.shape({
- left: PropTypes.string,
- right: PropTypes.string
- }),
- selectedValuesList: PropTypes.arrayOf(PropTypes.string),
-
- onChange: PropTypes.func.isRequired
- };
-
- static defaultProps = {
- selectedValuesList: [],
- availableList: [],
- filterTitle: {
- left: '',
- right: ''
- }
- };
-
- state = {
- availableListFilter: '',
- selectedValuesListFilter: '',
- selectedValues: []
- };
-
- render() {
- let {availableList, selectedValuesList, filterTitle, isReadOnlyMode} = this.props;
- let {availableListFilter, selectedValuesListFilter} = this.state;
-
- let unselectedList = availableList.filter(availableItem => !selectedValuesList.find(value => value === availableItem.id));
- let selectedList = availableList.filter(availableItem => selectedValuesList.find(value => value === availableItem.id));
- selectedList = selectedList.sort((a, b) => selectedValuesList.indexOf(a.id) - selectedValuesList.indexOf(b.id));
- return (
- <div className='dual-list-box'>
- {this.renderListbox(filterTitle.left, unselectedList, {
- value: availableListFilter,
- ref: 'availableListFilter',
- disabled: isReadOnlyMode,
- onChange: (value) => this.setState({availableListFilter: value})
- }, {ref: 'availableValues', disabled: isReadOnlyMode, testId: 'available',})}
- {this.renderOperationsBar(isReadOnlyMode)}
- {this.renderListbox(filterTitle.right, selectedList, {
- value: selectedValuesListFilter,
- ref: 'selectedValuesListFilter',
- disabled: isReadOnlyMode,
- onChange: (value) => this.setState({selectedValuesListFilter: value})
- }, {ref: 'selectedValues', disabled: isReadOnlyMode, testId: 'selected'})}
- </div>
- );
- }
-
- renderListbox(filterTitle, list, filterProps, props) {
- let regExFilter = new RegExp(escape(filterProps.value), 'i');
- let matchedItems = list.filter(item => item.name.match(regExFilter));
- let unMatchedItems = list.filter(item => !item.name.match(regExFilter));
- return (
- <div className='dual-search-multi-select-section'>
- <p>{filterTitle}</p>
- <div className='dual-text-box-search search-wrapper'>
- <Input data-test-id={`${props.testId}-search-input`}
- name='search-input-control' type='text'
- groupClassName='search-input-control'
- {...filterProps}/>
- <SVGIcon name='search' className='search-icon'/>
- </div>
- <Input
- multiple
- onChange={(event) => this.onSelectItems(event.target.selectedOptions)}
- groupClassName='dual-list-box-multi-select'
- type='select'
- name='dual-list-box-multi-select'
- data-test-id={`${props.testId}-select-input`}
- disabled={props.disabled}
- ref={props.ref}>
- {matchedItems.map(item => this.renderOption(item.id, item.name))}
- {matchedItems.length && unMatchedItems.length && <option style={{pointerEvents: 'none'}}>--------------------</option>}
- {unMatchedItems.map(item => this.renderOption(item.id, item.name))}
- </Input>
- </div>
- );
- }
-
- onSelectItems(selectedOptions) {
- let selectedValues = Object.keys(selectedOptions).map((k) => selectedOptions[k].value);
- this.setState({selectedValues});
- }
-
- renderOption(value, name) {
- return (<option className='dual-list-box-multi-select-text' key={value} value={value}>{name}</option>);
- }
-
- renderOperationsBar(isReadOnlyMode) {
- return (
- <div className={`dual-list-options-bar${isReadOnlyMode ? ' disabled' : ''}`}>
- {this.renderOperationBarButton(() => this.addToSelectedList(), 'angleRight')}
- {this.renderOperationBarButton(() => this.removeFromSelectedList(), 'angleLeft')}
- {this.renderOperationBarButton(() => this.addAllToSelectedList(), 'angleDoubleRight')}
- {this.renderOperationBarButton(() => this.removeAllFromSelectedList(), 'angleDoubleLeft')}
- </div>
- );
- }
-
- renderOperationBarButton(onClick, iconName){
- return (<div className='dual-list-option' data-test-id={`operation-icon-${iconName}`} onClick={onClick}><SVGIcon name={iconName}/></div>);
- }
-
- addToSelectedList() {
- this.props.onChange(this.props.selectedValuesList.concat(this.state.selectedValues));
- this.setState({selectedValues: []});
- }
-
- removeFromSelectedList() {
- const selectedValues = this.state.selectedValues;
- this.props.onChange(this.props.selectedValuesList.filter(value => !selectedValues.find(selectedValue => selectedValue === value)));
- this.setState({selectedValues: []});
- }
-
- addAllToSelectedList() {
- this.props.onChange(this.props.availableList.map(item => item.id));
- }
-
- removeAllFromSelectedList() {
- this.props.onChange([]);
- }
+ static propTypes = {
+ availableList: PropTypes.arrayOf(
+ PropTypes.shape({
+ id: PropTypes.string.isRequired,
+ name: PropTypes.string.isRequired
+ })
+ ),
+ filterTitle: PropTypes.shape({
+ left: PropTypes.string,
+ right: PropTypes.string
+ }),
+ selectedValuesList: PropTypes.arrayOf(PropTypes.string),
+
+ onChange: PropTypes.func.isRequired
+ };
+
+ static defaultProps = {
+ selectedValuesList: [],
+ availableList: [],
+ filterTitle: {
+ left: '',
+ right: ''
+ }
+ };
+
+ state = {
+ availableListFilter: '',
+ selectedValuesListFilter: '',
+ selectedValues: []
+ };
+
+ render() {
+ let {
+ availableList,
+ selectedValuesList,
+ filterTitle,
+ isReadOnlyMode
+ } = this.props;
+ let { availableListFilter, selectedValuesListFilter } = this.state;
+
+ let unselectedList = availableList.filter(
+ availableItem =>
+ !selectedValuesList.find(value => value === availableItem.id)
+ );
+ let selectedList = availableList.filter(availableItem =>
+ selectedValuesList.find(value => value === availableItem.id)
+ );
+ selectedList = selectedList.sort(
+ (a, b) =>
+ selectedValuesList.indexOf(a.id) -
+ selectedValuesList.indexOf(b.id)
+ );
+ return (
+ <div className="dual-list-box">
+ {this.renderListbox(
+ filterTitle.left,
+ unselectedList,
+ {
+ value: availableListFilter,
+ ref: 'availableListFilter',
+ disabled: isReadOnlyMode,
+ onChange: value =>
+ this.setState({ availableListFilter: value })
+ },
+ {
+ ref: 'availableValues',
+ disabled: isReadOnlyMode,
+ testId: 'available'
+ }
+ )}
+ {this.renderOperationsBar(isReadOnlyMode)}
+ {this.renderListbox(
+ filterTitle.right,
+ selectedList,
+ {
+ value: selectedValuesListFilter,
+ ref: 'selectedValuesListFilter',
+ disabled: isReadOnlyMode,
+ onChange: value =>
+ this.setState({ selectedValuesListFilter: value })
+ },
+ {
+ ref: 'selectedValues',
+ disabled: isReadOnlyMode,
+ testId: 'selected'
+ }
+ )}
+ </div>
+ );
+ }
+
+ renderListbox(filterTitle, list, filterProps, props) {
+ let regExFilter = new RegExp(escape(filterProps.value), 'i');
+ let matchedItems = list.filter(item => item.name.match(regExFilter));
+ let unMatchedItems = list.filter(item => !item.name.match(regExFilter));
+ return (
+ <div className="dual-search-multi-select-section">
+ <p>{filterTitle}</p>
+ <div className="dual-text-box-search search-wrapper">
+ <Input
+ data-test-id={`${props.testId}-search-input`}
+ name="search-input-control"
+ type="text"
+ groupClassName="search-input-control"
+ {...filterProps}
+ />
+ <SVGIcon name="search" className="search-icon" />
+ </div>
+ <Input
+ multiple
+ onChange={event =>
+ this.onSelectItems(event.target.selectedOptions)
+ }
+ groupClassName="dual-list-box-multi-select"
+ type="select"
+ name="dual-list-box-multi-select"
+ data-test-id={`${props.testId}-select-input`}
+ disabled={props.disabled}
+ ref={props.ref}>
+ {matchedItems.map(item =>
+ this.renderOption(item.id, item.name)
+ )}
+ {matchedItems.length &&
+ unMatchedItems.length && (
+ <option style={{ pointerEvents: 'none' }}>
+ --------------------
+ </option>
+ )}
+ {unMatchedItems.map(item =>
+ this.renderOption(item.id, item.name)
+ )}
+ </Input>
+ </div>
+ );
+ }
+
+ onSelectItems(selectedOptions) {
+ let selectedValues = Object.keys(selectedOptions).map(
+ k => selectedOptions[k].value
+ );
+ this.setState({ selectedValues });
+ }
+
+ renderOption(value, name) {
+ return (
+ <option
+ className="dual-list-box-multi-select-text"
+ key={value}
+ value={value}>
+ {name}
+ </option>
+ );
+ }
+
+ renderOperationsBar(isReadOnlyMode) {
+ return (
+ <div
+ className={`dual-list-options-bar${
+ isReadOnlyMode ? ' disabled' : ''
+ }`}>
+ {this.renderOperationBarButton(
+ () => this.addToSelectedList(),
+ 'angleRight'
+ )}
+ {this.renderOperationBarButton(
+ () => this.removeFromSelectedList(),
+ 'angleLeft'
+ )}
+ {this.renderOperationBarButton(
+ () => this.addAllToSelectedList(),
+ 'angleDoubleRight'
+ )}
+ {this.renderOperationBarButton(
+ () => this.removeAllFromSelectedList(),
+ 'angleDoubleLeft'
+ )}
+ </div>
+ );
+ }
+
+ renderOperationBarButton(onClick, iconName) {
+ return (
+ <div
+ className="dual-list-option"
+ data-test-id={`operation-icon-${iconName}`}
+ onClick={onClick}>
+ <SVGIcon name={iconName} />
+ </div>
+ );
+ }
+
+ addToSelectedList() {
+ this.props.onChange(
+ this.props.selectedValuesList.concat(this.state.selectedValues)
+ );
+ this.setState({ selectedValues: [] });
+ }
+
+ removeFromSelectedList() {
+ const selectedValues = this.state.selectedValues;
+ this.props.onChange(
+ this.props.selectedValuesList.filter(
+ value =>
+ !selectedValues.find(
+ selectedValue => selectedValue === value
+ )
+ )
+ );
+ this.setState({ selectedValues: [] });
+ }
+
+ addAllToSelectedList() {
+ this.props.onChange(this.props.availableList.map(item => item.id));
+ }
+
+ removeAllFromSelectedList() {
+ this.props.onChange([]);
+ }
}
export default DualListboxView;
diff --git a/openecomp-ui/src/nfvo-components/input/validation/Form.jsx b/openecomp-ui/src/nfvo-components/input/validation/Form.jsx
index 6df0bf9009..62fc29a55c 100644
--- a/openecomp-ui/src/nfvo-components/input/validation/Form.jsx
+++ b/openecomp-ui/src/nfvo-components/input/validation/Form.jsx
@@ -19,130 +19,160 @@ import PropTypes from 'prop-types';
import ValidationButtons from './ValidationButtons.jsx';
class Form extends React.Component {
-
- static defaultProps = {
- hasButtons : true,
- onSubmit : null,
- onReset : null,
- labledButtons: true,
- onValidChange : null,
- isValid: true,
- submitButtonText: null,
- cancelButtonText: null
- };
-
- static propTypes = {
- isValid : PropTypes.bool,
- formReady : PropTypes.bool,
- isReadOnlyMode : PropTypes.bool,
- hasButtons : PropTypes.bool,
- onSubmit : PropTypes.func,
- onReset : PropTypes.func,
- labledButtons: PropTypes.bool,
- submitButtonText: PropTypes.string,
- cancelButtonText: PropTypes.string,
- onValidChange : PropTypes.func,
- onValidityChanged: PropTypes.func,
- onValidateForm: PropTypes.func
- };
-
- constructor(props) {
- super(props);
- }
-
-
- render() {
- // eslint-disable-next-line no-unused-vars
- let {isValid, onValidChange, onValidityChanged, onDataChanged, formReady, onValidateForm, isReadOnlyMode, hasButtons, onSubmit, labledButtons, submitButtonText,
- cancelButtonText, children, ...formProps} = this.props;
- return (
- <form {...formProps} ref={(form) => this.form = form} onSubmit={event => this.handleFormValidation(event)}>
- <div className='validation-form-content'>
- <fieldset disabled={isReadOnlyMode}>
- {children}
- </fieldset>
- </div>
- {hasButtons &&
- <ValidationButtons
- labledButtons={labledButtons}
- submitButtonText={submitButtonText}
- cancelButtonText={cancelButtonText}
- ref={(buttons) => this.buttons = buttons}
- isReadOnlyMode={isReadOnlyMode}/>}
- </form>
- );
- }
-
- handleFormValidation(event) {
- event.preventDefault();
- if (this.props.onValidateForm && !this.props.formReady){
- return this.props.onValidateForm();
- } else {
- return this.handleFormSubmit(event);
- }
- }
- handleFormSubmit(event) {
- if (event) {
- event.preventDefault();
- }
- if(this.props.onSubmit) {
- return this.props.onSubmit(event);
- }
- }
-
- componentDidMount() {
- if (this.props.hasButtons) {
- this.buttons.setState({isValid: this.props.isValid});
- }
- }
-
-
-
- componentDidUpdate(prevProps) {
- // only handling this programatically if the validation of the form is done outside of the view
- // (example with a form that is dependent on the state of other forms)
- if (prevProps.isValid !== this.props.isValid) {
- if (this.props.hasButtons) {
- this.buttons.setState({isValid: this.props.isValid});
- }
- // callback in case form is part of bigger picture in view
- if (this.props.onValidChange) {
- this.props.onValidChange(this.props.isValid);
- }
-
- // TODO - maybe this has to be part of componentWillUpdate
- if(this.props.onValidityChanged) {
- this.props.onValidityChanged(this.props.isValid);
- }
- }
- if (this.props.formReady) { // if form validation succeeded -> continue with submit
- this.handleFormSubmit();
- }
- }
-
+ static defaultProps = {
+ hasButtons: true,
+ onSubmit: null,
+ onReset: null,
+ labledButtons: true,
+ onValidChange: null,
+ isValid: true,
+ submitButtonText: null,
+ cancelButtonText: null
+ };
+
+ static propTypes = {
+ isValid: PropTypes.bool,
+ formReady: PropTypes.bool,
+ isReadOnlyMode: PropTypes.bool,
+ hasButtons: PropTypes.bool,
+ onSubmit: PropTypes.func,
+ onReset: PropTypes.func,
+ labledButtons: PropTypes.bool,
+ submitButtonText: PropTypes.string,
+ cancelButtonText: PropTypes.string,
+ onValidChange: PropTypes.func,
+ onValidityChanged: PropTypes.func,
+ onValidateForm: PropTypes.func
+ };
+
+ constructor(props) {
+ super(props);
+ }
+ render() {
+ /* eslint-disable no-unused-vars */
+ let {
+ isValid,
+ onValidChange,
+ onValidityChanged,
+ onDataChanged,
+ formReady,
+ onValidateForm,
+ isReadOnlyMode,
+ hasButtons,
+ onSubmit,
+ labledButtons,
+ submitButtonText,
+ cancelButtonText,
+ children,
+ ...formProps
+ } = this.props;
+ /* eslint-enable no-unused-vars */
+ return (
+ <form
+ {...formProps}
+ ref={form => (this.form = form)}
+ onSubmit={event => this.handleFormValidation(event)}>
+ <div className="validation-form-content">
+ <fieldset disabled={isReadOnlyMode}>{children}</fieldset>
+ </div>
+ {hasButtons && (
+ <ValidationButtons
+ labledButtons={labledButtons}
+ submitButtonText={submitButtonText}
+ cancelButtonText={cancelButtonText}
+ ref={buttons => (this.buttons = buttons)}
+ isReadOnlyMode={isReadOnlyMode}
+ />
+ )}
+ </form>
+ );
+ }
+
+ handleFormValidation(event) {
+ event.preventDefault();
+ if (this.props.onValidateForm && !this.props.formReady) {
+ return this.props.onValidateForm();
+ } else {
+ return this.handleFormSubmit(event);
+ }
+ }
+ handleFormSubmit(event) {
+ if (event) {
+ event.preventDefault();
+ }
+ if (this.props.onSubmit) {
+ return this.props.onSubmit(event);
+ }
+ }
+
+ componentDidMount() {
+ if (this.props.hasButtons) {
+ this.buttons.setState({ isValid: this.props.isValid });
+ }
+ }
+
+ componentDidUpdate(prevProps) {
+ // only handling this programatically if the validation of the form is done outside of the view
+ // (example with a form that is dependent on the state of other forms)
+ if (prevProps.isValid !== this.props.isValid) {
+ if (this.props.hasButtons) {
+ this.buttons.setState({ isValid: this.props.isValid });
+ }
+ // callback in case form is part of bigger picture in view
+ if (this.props.onValidChange) {
+ this.props.onValidChange(this.props.isValid);
+ }
+
+ // TODO - maybe this has to be part of componentWillUpdate
+ if (this.props.onValidityChanged) {
+ this.props.onValidityChanged(this.props.isValid);
+ }
+ }
+ if (this.props.formReady) {
+ // if form validation succeeded -> continue with submit
+ this.handleFormSubmit();
+ }
+ }
}
export class TabsForm extends Form {
- render() {
- // eslint-disable-next-line no-unused-vars
- let {submitButtonText, cancelButtonText, isValid, formReady, onValidateForm, isReadOnlyMode, hasButtons, onSubmit, labledButtons, onValidChange, onValidityChanged, onDataChanged, children,
- ...formProps} = this.props;
- return (
- <form {...formProps} ref={(form) => this.form = form} onSubmit={event => this.handleFormValidation(event)}>
- <div className='validation-form-content'>
- {children}
- </div>
- {hasButtons &&
- <ValidationButtons
- labledButtons={labledButtons}
- submitButtonText={submitButtonText}
- cancelButtonText={cancelButtonText}
- ref={buttons => this.buttons = buttons}
- isReadOnlyMode={isReadOnlyMode}/>
- }
- </form>
- );
- }
+ render() {
+ /* eslint-disable no-unused-vars */
+ let {
+ submitButtonText,
+ cancelButtonText,
+ isValid,
+ formReady,
+ onValidateForm,
+ isReadOnlyMode,
+ hasButtons,
+ onSubmit,
+ labledButtons,
+ onValidChange,
+ onValidityChanged,
+ onDataChanged,
+ children,
+ ...formProps
+ } = this.props;
+ /* eslint-enable no-unused-vars */
+ return (
+ <form
+ {...formProps}
+ ref={form => (this.form = form)}
+ onSubmit={event => this.handleFormValidation(event)}>
+ <div className="validation-form-content">{children}</div>
+ {hasButtons && (
+ <ValidationButtons
+ labledButtons={labledButtons}
+ submitButtonText={submitButtonText}
+ cancelButtonText={cancelButtonText}
+ ref={buttons => (this.buttons = buttons)}
+ isReadOnlyMode={isReadOnlyMode}
+ />
+ )}
+ </form>
+ );
+ }
}
export default Form;
diff --git a/openecomp-ui/src/nfvo-components/input/validation/Input.jsx b/openecomp-ui/src/nfvo-components/input/validation/Input.jsx
index 33cea933b5..a5d6f4fd7a 100644
--- a/openecomp-ui/src/nfvo-components/input/validation/Input.jsx
+++ b/openecomp-ui/src/nfvo-components/input/validation/Input.jsx
@@ -25,191 +25,249 @@ import Tooltip from 'react-bootstrap/lib/Tooltip.js';
import Datepicker from 'nfvo-components/datepicker/Datepicker.jsx';
class Input extends React.Component {
+ state = {
+ value: this.props.value,
+ checked: this.props.checked,
+ selectedValues: []
+ };
- state = {
- value: this.props.value,
- checked: this.props.checked,
- selectedValues: []
- };
+ render() {
+ /* eslint-disable no-unused-vars */
+ const {
+ label,
+ isReadOnlyMode,
+ value,
+ onBlur,
+ onKeyDown,
+ type,
+ disabled,
+ checked,
+ name
+ } = this.props;
+ const {
+ groupClassName,
+ isValid = true,
+ errorText,
+ isRequired,
+ overlayPos,
+ ...inputProps
+ } = this.props;
+ const {
+ dateFormat,
+ startDate,
+ endDate,
+ selectsStart,
+ selectsEnd
+ } = this.props; // Date Props
+ /* eslint-enable no-unused-vars */
+ let wrapperClassName =
+ type !== 'radio'
+ ? 'validation-input-wrapper'
+ : 'validation-radio-wrapper';
+ if (disabled) {
+ wrapperClassName += ' disabled';
+ }
+ return (
+ <div className={wrapperClassName}>
+ <FormGroup
+ className={classNames('form-group', [groupClassName], {
+ required: isRequired,
+ 'has-error': !isValid
+ })}>
+ {label &&
+ (type !== 'checkbox' && type !== 'radio') && (
+ <label className="control-label">{label}</label>
+ )}
+ {type === 'text' && (
+ <FormControl
+ bsClass={'form-control input-options-other'}
+ onChange={e => this.onChange(e)}
+ disabled={isReadOnlyMode || Boolean(disabled)}
+ onBlur={onBlur}
+ onKeyDown={onKeyDown}
+ value={value || ''}
+ inputRef={input => (this.input = input)}
+ type={type}
+ data-test-id={this.props['data-test-id']}
+ />
+ )}
+ {type === 'number' && (
+ <FormControl
+ bsClass={'form-control input-options-other'}
+ onChange={e => this.onChange(e)}
+ disabled={isReadOnlyMode || Boolean(disabled)}
+ onBlur={onBlur}
+ onKeyDown={onKeyDown}
+ value={value !== undefined ? value : ''}
+ inputRef={input => (this.input = input)}
+ type={type}
+ data-test-id={this.props['data-test-id']}
+ />
+ )}
- render() {
- const {label, isReadOnlyMode, value, onBlur, onKeyDown, type, disabled, checked, name} = this.props;
- // eslint-disable-next-line no-unused-vars
- const {groupClassName, isValid = true, errorText, isRequired, overlayPos, ...inputProps} = this.props;
- const {dateFormat, startDate, endDate, selectsStart, selectsEnd} = this.props; // Date Props
- let wrapperClassName = (type !== 'radio') ? 'validation-input-wrapper' : 'validation-radio-wrapper';
- if (disabled) {
- wrapperClassName += ' disabled';
- }
- return(
- <div className={wrapperClassName}>
- <FormGroup className={classNames('form-group', [groupClassName], {'required' : isRequired , 'has-error' : !isValid})} >
- {(label && (type !== 'checkbox' && type !== 'radio')) && <label className='control-label'>{label}</label>}
- {type === 'text' &&
- <FormControl
- bsClass={'form-control input-options-other'}
- onChange={(e) => this.onChange(e)}
- disabled={isReadOnlyMode || Boolean(disabled)}
- onBlur={onBlur}
- onKeyDown={onKeyDown}
- value={value || ''}
- inputRef={(input) => this.input = input}
- type={type}
- data-test-id={this.props['data-test-id']}/>}
- {type === 'number' &&
- <FormControl
- bsClass={'form-control input-options-other'}
- onChange={(e) => this.onChange(e)}
- disabled={isReadOnlyMode || Boolean(disabled)}
- onBlur={onBlur}
- onKeyDown={onKeyDown}
- value={(value !== undefined) ? value : ''}
- inputRef={(input) => this.input = input}
- type={type}
- data-test-id={this.props['data-test-id']}/>}
+ {type === 'textarea' && (
+ <FormControl
+ className="form-control input-options-other"
+ disabled={isReadOnlyMode || Boolean(disabled)}
+ value={value || ''}
+ onBlur={onBlur}
+ onKeyDown={onKeyDown}
+ componentClass={type}
+ onChange={e => this.onChange(e)}
+ inputRef={input => (this.input = input)}
+ data-test-id={this.props['data-test-id']}
+ />
+ )}
- {type === 'textarea' &&
- <FormControl
- className='form-control input-options-other'
- disabled={isReadOnlyMode || Boolean(disabled)}
- value={value || ''}
- onBlur={onBlur}
- onKeyDown={onKeyDown}
- componentClass={type}
- onChange={(e) => this.onChange(e)}
- inputRef={(input) => this.input = input}
- data-test-id={this.props['data-test-id']}/>}
+ {type === 'checkbox' && (
+ <Checkbox
+ className={classNames({
+ required: isRequired,
+ 'has-error': !isValid
+ })}
+ onChange={e => this.onChangeCheckBox(e)}
+ disabled={isReadOnlyMode || Boolean(disabled)}
+ checked={checked}
+ data-test-id={this.props['data-test-id']}>
+ {label}
+ </Checkbox>
+ )}
- {type === 'checkbox' &&
- <Checkbox
- className={classNames({'required' : isRequired , 'has-error' : !isValid})}
- onChange={(e)=>this.onChangeCheckBox(e)}
- disabled={isReadOnlyMode || Boolean(disabled)}
- checked={checked}
- data-test-id={this.props['data-test-id']}>{label}</Checkbox>}
+ {type === 'radio' && (
+ <Radio
+ name={name}
+ checked={checked}
+ disabled={isReadOnlyMode || Boolean(disabled)}
+ value={value}
+ onChange={isChecked =>
+ this.onChangeRadio(isChecked)
+ }
+ inputRef={input => (this.input = input)}
+ label={label}
+ data-test-id={this.props['data-test-id']}
+ />
+ )}
+ {type === 'select' && (
+ <FormControl
+ onClick={e => this.optionSelect(e)}
+ className="custom-select"
+ componentClass={type}
+ inputRef={input => (this.input = input)}
+ name={name}
+ {...inputProps}
+ data-test-id={this.props['data-test-id']}
+ />
+ )}
+ {type === 'date' && (
+ <Datepicker
+ date={value}
+ format={dateFormat}
+ startDate={startDate}
+ endDate={endDate}
+ inputRef={input => (this.input = input)}
+ onChange={this.props.onChange}
+ disabled={isReadOnlyMode || Boolean(disabled)}
+ data-test-id={this.props['data-test-id']}
+ selectsStart={selectsStart}
+ selectsEnd={selectsEnd}
+ />
+ )}
+ </FormGroup>
+ {this.renderErrorOverlay()}
+ </div>
+ );
+ }
- {type === 'radio' &&
- <Radio name={name}
- checked={checked}
- disabled={isReadOnlyMode || Boolean(disabled)}
- value={value}
- onChange={(isChecked)=>this.onChangeRadio(isChecked)}
- inputRef={(input) => this.input = input}
- label={label}
- data-test-id={this.props['data-test-id']} />}
- {type === 'select' &&
- <FormControl onClick={ (e) => this.optionSelect(e) }
- className='custom-select'
- componentClass={type}
- inputRef={(input) => this.input = input}
- name={name} {...inputProps}
- data-test-id={this.props['data-test-id']}/>}
- {type === 'date' &&
- <Datepicker
- date={value}
- format={dateFormat}
- startDate={startDate}
- endDate={endDate}
- inputRef={(input) => this.input = input}
- onChange={this.props.onChange}
- disabled={isReadOnlyMode || Boolean(disabled)}
- data-test-id={this.props['data-test-id']}
- selectsStart={selectsStart}
- selectsEnd={selectsEnd} />}
- </FormGroup>
- { this.renderErrorOverlay() }
- </div>
- );
- }
+ getValue() {
+ return this.props.type !== 'select'
+ ? this.state.value
+ : this.state.selectedValues;
+ }
- getValue() {
- return this.props.type !== 'select' ? this.state.value : this.state.selectedValues;
- }
+ getChecked() {
+ return this.state.checked;
+ }
- getChecked() {
- return this.state.checked;
- }
+ optionSelect(e) {
+ let selectedValues = [];
+ if (e.target.value) {
+ selectedValues.push(e.target.value);
+ }
+ this.setState({
+ selectedValues
+ });
+ }
- optionSelect(e) {
- let selectedValues = [];
- if (e.target.value) {
- selectedValues.push(e.target.value);
- }
- this.setState({
- selectedValues
- });
- }
+ onChange(e) {
+ const { onChange, type } = this.props;
+ let value = e.target.value;
+ if (type === 'number') {
+ if (value === '') {
+ value = undefined;
+ } else {
+ value = Number(value);
+ }
+ }
+ this.setState({
+ value
+ });
+ onChange(value);
+ }
- onChange(e) {
- const {onChange, type} = this.props;
- let value = e.target.value;
- if (type === 'number') {
- if (value === '') {
- value = undefined;
- } else {
- value = Number(value);
- }
- }
- this.setState({
- value
- });
- onChange(value);
- }
+ onChangeCheckBox(e) {
+ let { onChange } = this.props;
+ let checked = e.target.checked;
+ this.setState({
+ checked
+ });
+ onChange(checked);
+ }
- onChangeCheckBox(e) {
- let {onChange} = this.props;
- let checked = e.target.checked;
- this.setState({
- checked
- });
- onChange(checked);
- }
+ onChangeRadio(isChecked) {
+ let { onChange } = this.props;
+ this.setState({
+ checked: isChecked
+ });
+ onChange(this.state.value);
+ }
- onChangeRadio(isChecked) {
- let {onChange} = this.props;
- this.setState({
- checked: isChecked
- });
- onChange(this.state.value);
- }
+ focus() {
+ ReactDOM.findDOMNode(this.input).focus();
+ }
- focus() {
- ReactDOM.findDOMNode(this.input).focus();
- }
+ renderErrorOverlay() {
+ let position = 'right';
+ const { errorText = '', isValid = true, type, overlayPos } = this.props;
- renderErrorOverlay() {
- let position = 'right';
- const {errorText = '', isValid = true, type, overlayPos} = this.props;
-
- if (overlayPos) {
- position = overlayPos;
- }
- else if (type === 'text'
- || type === 'email'
- || type === 'number'
- || type === 'radio'
- || type === 'password'
- || type === 'date') {
- position = 'bottom';
- }
-
- return (
- <Overlay
- show={!isValid}
- placement={position}
- target={() => {
- let target = ReactDOM.findDOMNode(this.input);
- return target.offsetParent ? target : undefined;
- }}
- container={this}>
- <Tooltip
- id={`error-${errorText.replace(' ', '-')}`}
- className='validation-error-message'>
- {errorText}
- </Tooltip>
- </Overlay>
- );
- }
+ if (overlayPos) {
+ position = overlayPos;
+ } else if (
+ type === 'text' ||
+ type === 'email' ||
+ type === 'number' ||
+ type === 'radio' ||
+ type === 'password' ||
+ type === 'date'
+ ) {
+ position = 'bottom';
+ }
+ return (
+ <Overlay
+ show={!isValid}
+ placement={position}
+ target={() => {
+ let target = ReactDOM.findDOMNode(this.input);
+ return target.offsetParent ? target : undefined;
+ }}
+ container={this}>
+ <Tooltip
+ id={`error-${errorText.replace(' ', '-')}`}
+ className="validation-error-message">
+ {errorText}
+ </Tooltip>
+ </Overlay>
+ );
+ }
}
-export default Input;
+export default Input;
diff --git a/openecomp-ui/src/nfvo-components/input/validation/InputOptions.jsx b/openecomp-ui/src/nfvo-components/input/validation/InputOptions.jsx
index 11b07ba9da..019b6a5c70 100644
--- a/openecomp-ui/src/nfvo-components/input/validation/InputOptions.jsx
+++ b/openecomp-ui/src/nfvo-components/input/validation/InputOptions.jsx
@@ -22,260 +22,341 @@ import Select from 'nfvo-components/input/SelectInput.jsx';
import Overlay from 'react-bootstrap/lib/Overlay.js';
import Tooltip from 'react-bootstrap/lib/Tooltip.js';
-export const other = {OTHER: 'Other'};
+export const other = { OTHER: 'Other' };
class InputOptions extends React.Component {
+ static propTypes = {
+ values: PropTypes.arrayOf(
+ PropTypes.shape({
+ enum: PropTypes.string,
+ title: PropTypes.string
+ })
+ ),
+ isEnabledOther: PropTypes.bool,
+ label: PropTypes.string,
+ selectedValue: PropTypes.string,
+ multiSelectedEnum: PropTypes.oneOfType([
+ PropTypes.string,
+ PropTypes.array
+ ]),
+ selectedEnum: PropTypes.string,
+ otherValue: PropTypes.string,
+ overlayPos: PropTypes.string,
+ onEnumChange: PropTypes.func,
+ onOtherChange: PropTypes.func,
+ onBlur: PropTypes.func,
+ isRequired: PropTypes.bool,
+ isMultiSelect: PropTypes.bool,
+ isValid: PropTypes.bool,
+ disabled: PropTypes.bool
+ };
- static propTypes = {
- values: PropTypes.arrayOf(PropTypes.shape({
- enum: PropTypes.string,
- title: PropTypes.string
- })),
- isEnabledOther: PropTypes.bool,
- label: PropTypes.string,
- selectedValue: PropTypes.string,
- multiSelectedEnum: PropTypes.oneOfType([
- PropTypes.string,
- PropTypes.array
- ]),
- selectedEnum: PropTypes.string,
- otherValue: PropTypes.string,
- overlayPos: PropTypes.string,
- onEnumChange: PropTypes.func,
- onOtherChange: PropTypes.func,
- onBlur: PropTypes.func,
- isRequired: PropTypes.bool,
- isMultiSelect: PropTypes.bool,
- isValid: PropTypes.bool,
- disabled: PropTypes.bool
- };
+ state = {
+ otherInputDisabled: !this.props.otherValue
+ };
- state = {
- otherInputDisabled: !this.props.otherValue
- };
+ oldProps = {
+ selectedEnum: '',
+ otherValue: '',
+ multiSelectedEnum: []
+ };
- oldProps = {
- selectedEnum: '',
- otherValue: '',
- multiSelectedEnum: []
- };
+ render() {
+ let {
+ label,
+ isRequired,
+ values,
+ otherValue,
+ onOtherChange,
+ isMultiSelect,
+ onBlur,
+ multiSelectedEnum,
+ selectedEnum,
+ isValid,
+ children,
+ isReadOnlyMode
+ } = this.props;
+ const dataTestId = this.props['data-test-id']
+ ? { 'data-test-id': this.props['data-test-id'] }
+ : {};
+ let currentMultiSelectedEnum = [];
+ let currentSelectedEnum = '';
+ let otherInputDisabled =
+ (isMultiSelect &&
+ (multiSelectedEnum === undefined ||
+ multiSelectedEnum.length === 0 ||
+ multiSelectedEnum[0] !== other.OTHER)) ||
+ (!isMultiSelect &&
+ (selectedEnum === undefined || selectedEnum !== other.OTHER));
+ if (isMultiSelect) {
+ currentMultiSelectedEnum = multiSelectedEnum;
+ if (!otherInputDisabled) {
+ currentSelectedEnum = multiSelectedEnum
+ ? multiSelectedEnum.toString()
+ : undefined;
+ }
+ } else if (selectedEnum) {
+ currentSelectedEnum = selectedEnum;
+ }
+ if (!onBlur) {
+ onBlur = () => {};
+ }
- render() {
- let {label, isRequired, values, otherValue, onOtherChange, isMultiSelect, onBlur, multiSelectedEnum, selectedEnum, isValid, children, isReadOnlyMode} = this.props;
- const dataTestId = this.props['data-test-id'] ? {'data-test-id': this.props['data-test-id']} : {};
- let currentMultiSelectedEnum = [];
- let currentSelectedEnum = '';
- let otherInputDisabled = (isMultiSelect && (multiSelectedEnum === undefined || multiSelectedEnum.length === 0 || multiSelectedEnum[0] !== other.OTHER))
- || (!isMultiSelect && (selectedEnum === undefined || selectedEnum !== other.OTHER));
- if (isMultiSelect) {
- currentMultiSelectedEnum = multiSelectedEnum;
- if(!otherInputDisabled) {
- currentSelectedEnum = multiSelectedEnum ? multiSelectedEnum.toString() : undefined;
- }
- }
- else if(selectedEnum){
- currentSelectedEnum = selectedEnum;
- }
- if (!onBlur) {
- onBlur = () => {};
- }
+ return (
+ <div className="validation-input-wrapper">
+ <div
+ className={classNames('form-group', {
+ required: isRequired,
+ 'has-error': !isValid
+ })}>
+ {label && <label className="control-label">{label}</label>}
+ {isMultiSelect && otherInputDisabled ? (
+ <Select
+ {...dataTestId}
+ ref={input => (this.input = input)}
+ value={currentMultiSelectedEnum}
+ className="options-input"
+ clearable={false}
+ required={isRequired}
+ disabled={
+ isReadOnlyMode || Boolean(this.props.disabled)
+ }
+ onBlur={() => onBlur()}
+ onMultiSelectChanged={value =>
+ this.multiSelectEnumChanged(value)
+ }
+ options={this.renderMultiSelectOptions(values)}
+ multi
+ />
+ ) : (
+ <div
+ className={classNames('input-options', {
+ 'has-error': !isValid
+ })}>
+ <select
+ {...dataTestId}
+ ref={input => (this.input = input)}
+ label={label}
+ className="form-control input-options-select"
+ value={currentSelectedEnum}
+ style={{
+ width: otherInputDisabled ? '100%' : '100px'
+ }}
+ onBlur={() => onBlur()}
+ disabled={
+ isReadOnlyMode ||
+ Boolean(this.props.disabled)
+ }
+ onChange={value => this.enumChanged(value)}
+ type="select">
+ {children ||
+ (values &&
+ values.length &&
+ values.map((val, index) =>
+ this.renderOptions(val, index)
+ ))}
+ {onOtherChange && (
+ <option key="other" value={other.OTHER}>
+ {i18n(other.OTHER)}
+ </option>
+ )}
+ </select>
- return(
- <div className='validation-input-wrapper' >
- <div className={classNames('form-group', {'required' : isRequired, 'has-error' : !isValid})} >
- {label && <label className='control-label'>{label}</label>}
- {isMultiSelect && otherInputDisabled ?
- <Select
- {...dataTestId}
- ref={(input) => this.input = input}
- value={currentMultiSelectedEnum}
- className='options-input'
- clearable={false}
- required={isRequired}
- disabled={isReadOnlyMode || Boolean(this.props.disabled)}
- onBlur={() => onBlur()}
- onMultiSelectChanged={value => this.multiSelectEnumChanged(value)}
- options={this.renderMultiSelectOptions(values)}
- multi/> :
- <div className={classNames('input-options',{'has-error' : !isValid})} >
- <select
- {...dataTestId}
- ref={(input) => this.input = input}
- label={label}
- className='form-control input-options-select'
- value={currentSelectedEnum}
- style={{'width' : otherInputDisabled ? '100%' : '100px'}}
- onBlur={() => onBlur()}
- disabled={isReadOnlyMode || Boolean(this.props.disabled)}
- onChange={ value => this.enumChanged(value)}
- type='select'>
- {children || (values && values.length && values.map((val, index) => this.renderOptions(val, index)))}
- {onOtherChange && <option key='other' value={other.OTHER}>{i18n(other.OTHER)}</option>}
- </select>
+ {!otherInputDisabled && (
+ <div className="input-options-separator" />
+ )}
+ <input
+ className="form-control input-options-other"
+ placeholder={i18n('other')}
+ ref={otherValue =>
+ (this.otherValue = otherValue)
+ }
+ style={{
+ display: otherInputDisabled
+ ? 'none'
+ : 'block'
+ }}
+ disabled={
+ isReadOnlyMode ||
+ Boolean(this.props.disabled)
+ }
+ value={otherValue || ''}
+ onBlur={() => onBlur()}
+ onChange={() => this.changedOtherInput()}
+ />
+ </div>
+ )}
+ </div>
+ {this.renderErrorOverlay()}
+ </div>
+ );
+ }
- {!otherInputDisabled && <div className='input-options-separator'/>}
- <input
- className='form-control input-options-other'
- placeholder={i18n('other')}
- ref={(otherValue) => this.otherValue = otherValue}
- style={{'display' : otherInputDisabled ? 'none' : 'block'}}
- disabled={isReadOnlyMode || Boolean(this.props.disabled)}
- value={otherValue || ''}
- onBlur={() => onBlur()}
- onChange={() => this.changedOtherInput()}/>
- </div>
- }
- </div>
- { this.renderErrorOverlay() }
- </div>
- );
- }
+ renderOptions(val, index) {
+ return (
+ <option key={index} value={val.enum}>
+ {val.title}
+ </option>
+ );
+ }
- renderOptions(val, index){
- return (
- <option key={index} value={val.enum}>{val.title}</option>
- );
- }
+ renderMultiSelectOptions(values) {
+ let { onOtherChange } = this.props;
+ let optionsList = [];
+ if (onOtherChange) {
+ optionsList = values
+ .map(option => {
+ return {
+ label: option.title,
+ value: option.enum
+ };
+ })
+ .concat([
+ {
+ label: i18n(other.OTHER),
+ value: i18n(other.OTHER)
+ }
+ ]);
+ } else {
+ optionsList = values.map(option => {
+ return {
+ label: option.title,
+ value: option.enum
+ };
+ });
+ }
+ if (optionsList.length > 0 && optionsList[0].value === '') {
+ optionsList.shift();
+ }
+ return optionsList;
+ }
+ renderErrorOverlay() {
+ let position = 'right';
+ const { errorText = '', isValid = true, type, overlayPos } = this.props;
- renderMultiSelectOptions(values) {
- let {onOtherChange} = this.props;
- let optionsList = [];
- if (onOtherChange) {
- optionsList = values.map(option => {
- return {
- label: option.title,
- value: option.enum,
- };
- }).concat([{
- label: i18n(other.OTHER),
- value: i18n(other.OTHER),
- }]);
- }
- else {
- optionsList = values.map(option => {
- return {
- label: option.title,
- value: option.enum,
- };
- });
- }
- if (optionsList.length > 0 && optionsList[0].value === '') {
- optionsList.shift();
- }
- return optionsList;
- }
+ if (overlayPos) {
+ position = overlayPos;
+ } else if (
+ type === 'text' ||
+ type === 'email' ||
+ type === 'number' ||
+ type === 'password'
+ ) {
+ position = 'bottom';
+ }
- renderErrorOverlay() {
- let position = 'right';
- const {errorText = '', isValid = true, type, overlayPos} = this.props;
+ return (
+ <Overlay
+ show={!isValid}
+ placement={position}
+ target={() => {
+ let { otherInputDisabled } = this.state;
+ let target = otherInputDisabled
+ ? ReactDOM.findDOMNode(this.input)
+ : ReactDOM.findDOMNode(this.otherValue);
+ return target.offsetParent ? target : undefined;
+ }}
+ container={this}>
+ <Tooltip
+ id={`error-${errorText.replace(' ', '-')}`}
+ className="validation-error-message">
+ {errorText}
+ </Tooltip>
+ </Overlay>
+ );
+ }
- if (overlayPos) {
- position = overlayPos;
- }
- else if (type === 'text'
- || type === 'email'
- || type === 'number'
- || type === 'password') {
- position = 'bottom';
- }
+ getValue() {
+ let res = '';
+ let { isMultiSelect } = this.props;
+ let { otherInputDisabled } = this.state;
- return (
- <Overlay
- show={!isValid}
- placement={position}
- target={() => {
- let {otherInputDisabled} = this.state;
- let target = otherInputDisabled ? ReactDOM.findDOMNode(this.input) : ReactDOM.findDOMNode(this.otherValue);
- return target.offsetParent ? target : undefined;
- }}
- container={this}>
- <Tooltip
- id={`error-${errorText.replace(' ', '-')}`}
- className='validation-error-message'>
- {errorText}
- </Tooltip>
- </Overlay>
- );
- }
+ if (otherInputDisabled) {
+ res = isMultiSelect ? this.input.getValue() : this.input.value;
+ } else {
+ res = this.otherValue.value;
+ }
+ return res;
+ }
- getValue() {
- let res = '';
- let {isMultiSelect} = this.props;
- let {otherInputDisabled} = this.state;
+ enumChanged() {
+ let enumValue = this.input.value;
+ let {
+ onEnumChange,
+ onOtherChange,
+ isMultiSelect,
+ onChange
+ } = this.props;
+ this.setState({
+ otherInputDisabled:
+ !Boolean(onOtherChange) || enumValue !== other.OTHER
+ });
- if (otherInputDisabled) {
- res = isMultiSelect ? this.input.getValue() : this.input.value;
- } else {
- res = this.otherValue.value;
- }
- return res;
- }
+ let value = isMultiSelect ? [enumValue] : enumValue;
+ if (onEnumChange) {
+ onEnumChange(value);
+ }
+ if (onChange) {
+ onChange(value);
+ }
+ }
- enumChanged() {
- let enumValue = this.input.value;
- let {onEnumChange, onOtherChange, isMultiSelect, onChange} = this.props;
- this.setState({
- otherInputDisabled: !Boolean(onOtherChange) || enumValue !== other.OTHER
- });
+ multiSelectEnumChanged(enumValue) {
+ let { onEnumChange, onOtherChange } = this.props;
+ let selectedValues = enumValue.map(enumVal => {
+ return enumVal.value;
+ });
- let value = isMultiSelect ? [enumValue] : enumValue;
- if (onEnumChange) {
- onEnumChange(value);
- }
- if (onChange) {
- onChange(value);
- }
- }
+ if (this.state.otherInputDisabled === false) {
+ selectedValues.shift();
+ } else if (selectedValues.includes(i18n(other.OTHER))) {
+ selectedValues = [i18n(other.OTHER)];
+ }
- multiSelectEnumChanged(enumValue) {
- let {onEnumChange, onOtherChange} = this.props;
- let selectedValues = enumValue.map(enumVal => {
- return enumVal.value;
- });
+ this.setState({
+ otherInputDisabled:
+ !Boolean(onOtherChange) ||
+ !selectedValues.includes(i18n(other.OTHER))
+ });
+ onEnumChange(selectedValues);
+ }
- if (this.state.otherInputDisabled === false) {
- selectedValues.shift();
- }
- else if (selectedValues.includes(i18n(other.OTHER))) {
- selectedValues = [i18n(other.OTHER)];
- }
+ changedOtherInput() {
+ let { onOtherChange } = this.props;
+ onOtherChange(this.otherValue.value);
+ }
- this.setState({
- otherInputDisabled: !Boolean(onOtherChange) || !selectedValues.includes(i18n(other.OTHER))
- });
- onEnumChange(selectedValues);
- }
-
- changedOtherInput() {
- let {onOtherChange} = this.props;
- onOtherChange(this.otherValue.value);
- }
-
- componentDidUpdate() {
- let {otherValue, selectedEnum, onInputChange, multiSelectedEnum} = this.props;
- if (this.oldProps.otherValue !== otherValue
- || this.oldProps.selectedEnum !== selectedEnum
- || this.oldProps.multiSelectedEnum !== multiSelectedEnum) {
- this.oldProps = {
- otherValue,
- selectedEnum,
- multiSelectedEnum
- };
- onInputChange();
- }
- }
-
- static getTitleByName(values, name) {
- for (let key of Object.keys(values)) {
- let option = values[key].find(option => option.enum === name);
- if (option) {
- return option.title;
- }
- }
- return name;
- }
+ componentDidUpdate() {
+ let {
+ otherValue,
+ selectedEnum,
+ onInputChange,
+ multiSelectedEnum
+ } = this.props;
+ if (
+ this.oldProps.otherValue !== otherValue ||
+ this.oldProps.selectedEnum !== selectedEnum ||
+ this.oldProps.multiSelectedEnum !== multiSelectedEnum
+ ) {
+ this.oldProps = {
+ otherValue,
+ selectedEnum,
+ multiSelectedEnum
+ };
+ onInputChange();
+ }
+ }
+ static getTitleByName(values, name) {
+ for (let key of Object.keys(values)) {
+ let option = values[key].find(option => option.enum === name);
+ if (option) {
+ return option.title;
+ }
+ }
+ return name;
+ }
}
export default InputOptions;
diff --git a/openecomp-ui/src/nfvo-components/input/validation/InputWrapper.jsx b/openecomp-ui/src/nfvo-components/input/validation/InputWrapper.jsx
index e440fcda69..3e0bb32ca9 100644
--- a/openecomp-ui/src/nfvo-components/input/validation/InputWrapper.jsx
+++ b/openecomp-ui/src/nfvo-components/input/validation/InputWrapper.jsx
@@ -22,114 +22,149 @@ import FormGroup from 'react-bootstrap/lib/FormGroup.js';
import FormControl from 'react-bootstrap/lib/FormControl.js';
class InputWrapper extends React.Component {
-
- state = {
- value: this.props.value,
- checked: this.props.checked,
- selectedValues: []
- }
-
- render() {
- const {label, hasError, validations = {}, isReadOnlyMode, value, onBlur, onKeyDown, type, disabled, checked, name} = this.props;
- const {groupClassName, ...inputProps} = this.props;
- return(
- <FormGroup className={classNames('form-group', [groupClassName], {'required' : validations.required , 'has-error' : hasError})} >
- {(label && (type !== 'checkbox' && type !== 'radio')) && <label className='control-label'>{label}</label>}
- {(type === 'text' || type === 'number') &&
- <FormControl
- bsClass={'form-control input-options-other'}
- onChange={(e) => this.onChange(e)}
- disabled={isReadOnlyMode || Boolean(disabled)}
- onBlur={onBlur}
- onKeyDown={onKeyDown}
- value={value || ''}
- ref={(input) => this.inputWrapper = input}
- type={type}
- data-test-id={this.props['data-test-id']}/>}
-
- {type === 'textarea' &&
- <FormControl
- className='form-control input-options-other'
- disabled={isReadOnlyMode || Boolean(disabled)}
- value={value || ''}
- onBlur={onBlur}
- onKeyDown={onKeyDown}
- componentClass={type}
- onChange={(e) => this.onChange(e)}
- data-test-id={this.props['data-test-id']}/>}
-
- {type === 'checkbox' &&
- <Checkbox
- className={classNames({'required' : validations.required , 'has-error' : hasError})}
- onChange={(e)=>this.onChangeCheckBox(e)}
- disabled={isReadOnlyMode || Boolean(disabled)}
- checked={value}
- data-test-id={this.props['data-test-id']}>{label}</Checkbox>}
-
- {type === 'radio' &&
- <Radio name={name}
- checked={checked}
- disabled={isReadOnlyMode || Boolean(disabled)}
- value={value}
- ref={(input) => this.inputWrapper = input}
- onChange={(isChecked)=>this.onChangeRadio(isChecked)} label={label}
- data-test-id={this.props['data-test-id']} />}
- {type === 'select' &&
- <FormControl onClick={ (e) => this.optionSelect(e) }
- componentClass={type}
- name={name} {...inputProps}
- data-test-id={this.props['data-test-id']}/>}
-
- </FormGroup>
-
- );
- }
-
- getValue() {
- return this.props.type !== 'select' ? this.state.value : this.state.selectedValues;
- }
-
- getChecked() {
- return this.state.checked;
- }
-
- optionSelect(e) {
- let selectedValues = [];
- if (e.target.value) {
- selectedValues.push(e.target.value);
- }
- this.setState({
- selectedValues
- });
- }
-
- onChange(e) {
- let {onChange} = this.props;
- this.setState({
- value: e.target.value
- });
- onChange(e.target.value);
- }
-
- onChangeCheckBox(e) {
- let {onChange} = this.props;
- this.setState({
- checked: e.target.checked
- });
- onChange(e.target.checked);
- }
-
- onChangeRadio(isChecked) {
- let {onChange} = this.props;
- this.setState({
- checked: isChecked
- });
- onChange(this.state.value);
- }
-
- focus() {
- ReactDOM.findDOMNode(this.inputWrapper).focus();
- }
-
+ state = {
+ value: this.props.value,
+ checked: this.props.checked,
+ selectedValues: []
+ };
+
+ render() {
+ const {
+ label,
+ hasError,
+ validations = {},
+ isReadOnlyMode,
+ value,
+ onBlur,
+ onKeyDown,
+ type,
+ disabled,
+ checked,
+ name
+ } = this.props;
+ const { groupClassName, ...inputProps } = this.props;
+ return (
+ <FormGroup
+ className={classNames('form-group', [groupClassName], {
+ required: validations.required,
+ 'has-error': hasError
+ })}>
+ {label &&
+ (type !== 'checkbox' && type !== 'radio') && (
+ <label className="control-label">{label}</label>
+ )}
+ {(type === 'text' || type === 'number') && (
+ <FormControl
+ bsClass={'form-control input-options-other'}
+ onChange={e => this.onChange(e)}
+ disabled={isReadOnlyMode || Boolean(disabled)}
+ onBlur={onBlur}
+ onKeyDown={onKeyDown}
+ value={value || ''}
+ ref={input => (this.inputWrapper = input)}
+ type={type}
+ data-test-id={this.props['data-test-id']}
+ />
+ )}
+
+ {type === 'textarea' && (
+ <FormControl
+ className="form-control input-options-other"
+ disabled={isReadOnlyMode || Boolean(disabled)}
+ value={value || ''}
+ onBlur={onBlur}
+ onKeyDown={onKeyDown}
+ componentClass={type}
+ onChange={e => this.onChange(e)}
+ data-test-id={this.props['data-test-id']}
+ />
+ )}
+
+ {type === 'checkbox' && (
+ <Checkbox
+ className={classNames({
+ required: validations.required,
+ 'has-error': hasError
+ })}
+ onChange={e => this.onChangeCheckBox(e)}
+ disabled={isReadOnlyMode || Boolean(disabled)}
+ checked={value}
+ data-test-id={this.props['data-test-id']}>
+ {label}
+ </Checkbox>
+ )}
+
+ {type === 'radio' && (
+ <Radio
+ name={name}
+ checked={checked}
+ disabled={isReadOnlyMode || Boolean(disabled)}
+ value={value}
+ ref={input => (this.inputWrapper = input)}
+ onChange={isChecked => this.onChangeRadio(isChecked)}
+ label={label}
+ data-test-id={this.props['data-test-id']}
+ />
+ )}
+ {type === 'select' && (
+ <FormControl
+ onClick={e => this.optionSelect(e)}
+ componentClass={type}
+ name={name}
+ {...inputProps}
+ data-test-id={this.props['data-test-id']}
+ />
+ )}
+ </FormGroup>
+ );
+ }
+
+ getValue() {
+ return this.props.type !== 'select'
+ ? this.state.value
+ : this.state.selectedValues;
+ }
+
+ getChecked() {
+ return this.state.checked;
+ }
+
+ optionSelect(e) {
+ let selectedValues = [];
+ if (e.target.value) {
+ selectedValues.push(e.target.value);
+ }
+ this.setState({
+ selectedValues
+ });
+ }
+
+ onChange(e) {
+ let { onChange } = this.props;
+ this.setState({
+ value: e.target.value
+ });
+ onChange(e.target.value);
+ }
+
+ onChangeCheckBox(e) {
+ let { onChange } = this.props;
+ this.setState({
+ checked: e.target.checked
+ });
+ onChange(e.target.checked);
+ }
+
+ onChangeRadio(isChecked) {
+ let { onChange } = this.props;
+ this.setState({
+ checked: isChecked
+ });
+ onChange(this.state.value);
+ }
+
+ focus() {
+ ReactDOM.findDOMNode(this.inputWrapper).focus();
+ }
}
-export default InputWrapper;
+export default InputWrapper;
diff --git a/openecomp-ui/src/nfvo-components/input/validation/Tabs.jsx b/openecomp-ui/src/nfvo-components/input/validation/Tabs.jsx
index 0982c133e6..429985a902 100644
--- a/openecomp-ui/src/nfvo-components/input/validation/Tabs.jsx
+++ b/openecomp-ui/src/nfvo-components/input/validation/Tabs.jsx
@@ -16,64 +16,76 @@
import React from 'react';
import PropTypes from 'prop-types';
import ReactDOM from 'react-dom';
-import {default as SDCTabs} from 'sdc-ui/lib/react/Tabs.js';
+import { default as SDCTabs } from 'sdc-ui/lib/react/Tabs.js';
import Overlay from 'react-bootstrap/lib/Overlay.js';
import Tooltip from 'react-bootstrap/lib/Tooltip.js';
import i18n from 'nfvo-utils/i18n/i18n.js';
-export default
-class Tabs extends React.Component {
+export default class Tabs extends React.Component {
+ static propTypes = {
+ children: PropTypes.node
+ };
- static propTypes = {
- children: PropTypes.node
- };
+ cloneTab(element) {
+ const { invalidTabs } = this.props;
+ return React.cloneElement(element, {
+ key: element.props.tabId,
+ className:
+ invalidTabs.indexOf(element.props.tabId) > -1
+ ? 'invalid-tab'
+ : 'valid-tab'
+ });
+ }
- cloneTab(element) {
- const {invalidTabs} = this.props;
- return React.cloneElement(
- element,
- {
- key: element.props.tabId,
- className: invalidTabs.indexOf(element.props.tabId) > -1 ? 'invalid-tab' : 'valid-tab'
- }
- );
- }
+ showTabsError() {
+ const { invalidTabs } = this.props;
+ const showError =
+ (invalidTabs.length === 1 &&
+ invalidTabs[0] !== this.props.activeTab) ||
+ invalidTabs.length > 1;
+ return showError;
+ }
- showTabsError() {
- const {invalidTabs} = this.props;
- const showError = ((invalidTabs.length === 1 && invalidTabs[0] !== this.props.activeTab) || (invalidTabs.length > 1));
- return showError;
- }
-
- render() {
- // eslint-disable-next-line no-unused-vars
- let {invalidTabs, ...tabProps} = this.props;
- return (
- <div>
- <SDCTabs {...tabProps} ref='tabsList' id='tabsList' >
- {this.props.children.map(element => this.cloneTab(element))}
- </SDCTabs>
- <Overlay
- animation={false}
- show={this.showTabsError()}
- placement='bottom'
- target={() => {
- let target = ReactDOM.findDOMNode(this.refs.tabsList).querySelector('ul > li.invalid-tab:not(.sdc-tab-active):nth-of-type(n)');
- return target && target.offsetParent ? target : undefined;
- }
- }
- container={() => {
- let target = ReactDOM.findDOMNode(this.refs.tabsList).querySelector('ul > li.invalid-tab:not(.sdc-tab-active):nth-of-type(n)');
- return target && target.offsetParent ? target.offsetParent : this;
- }}>
- <Tooltip
- id='error-some-tabs-contain-errors'
- className='validation-error-message'>
- {i18n('One or more tabs are invalid')}
- </Tooltip>
- </Overlay>
- </div>
- );
- }
+ render() {
+ // eslint-disable-next-line no-unused-vars
+ let { invalidTabs, ...tabProps } = this.props;
+ return (
+ <div>
+ <SDCTabs {...tabProps} ref="tabsList" id="tabsList">
+ {this.props.children.map(element => this.cloneTab(element))}
+ </SDCTabs>
+ <Overlay
+ animation={false}
+ show={this.showTabsError()}
+ placement="bottom"
+ target={() => {
+ let target = ReactDOM.findDOMNode(
+ this.refs.tabsList
+ ).querySelector(
+ 'ul > li.invalid-tab:not(.sdc-tab-active):nth-of-type(n)'
+ );
+ return target && target.offsetParent
+ ? target
+ : undefined;
+ }}
+ container={() => {
+ let target = ReactDOM.findDOMNode(
+ this.refs.tabsList
+ ).querySelector(
+ 'ul > li.invalid-tab:not(.sdc-tab-active):nth-of-type(n)'
+ );
+ return target && target.offsetParent
+ ? target.offsetParent
+ : this;
+ }}>
+ <Tooltip
+ id="error-some-tabs-contain-errors"
+ className="validation-error-message">
+ {i18n('One or more tabs are invalid')}
+ </Tooltip>
+ </Overlay>
+ </div>
+ );
+ }
}
diff --git a/openecomp-ui/src/nfvo-components/input/validation/ValidationButtons.jsx b/openecomp-ui/src/nfvo-components/input/validation/ValidationButtons.jsx
index 151d3fe859..e460f68a98 100644
--- a/openecomp-ui/src/nfvo-components/input/validation/ValidationButtons.jsx
+++ b/openecomp-ui/src/nfvo-components/input/validation/ValidationButtons.jsx
@@ -27,32 +27,63 @@ import Button from 'sdc-ui/lib/react/Button.js';
import SVGIcon from 'sdc-ui/lib/react/SVGIcon.js';
class ValidationButtons extends React.Component {
+ static propTypes = {
+ labledButtons: PropTypes.bool.isRequired,
+ isReadOnlyMode: PropTypes.bool,
+ submitButtonText: PropTypes.string,
+ cancelButtonText: PropTypes.string
+ };
- static propTypes = {
- labledButtons: PropTypes.bool.isRequired,
- isReadOnlyMode: PropTypes.bool,
- submitButtonText: PropTypes.string,
- cancelButtonText: PropTypes.string
- };
+ state = {
+ isValid: this.props.formValid
+ };
- state = {
- isValid: this.props.formValid
- };
-
- render() {
- let submitBtn = this.props.labledButtons ? this.props.submitButtonText ? this.props.submitButtonText : i18n('Save') : <SVGIcon className='check' name='check'/>;
- let closeBtn = this.props.labledButtons ? this.props.cancelButtonText ? this.props.cancelButtonText : i18n('Cancel') : <SVGIcon className='close' name='close'/>;
- return (
- <div className='validation-buttons'>
- {!this.props.isReadOnlyMode ?
- <div>
- <Button type='submit' data-test-id='form-submit-button' disabled={!this.state.isValid}>{submitBtn}</Button>
- <Button btnType='outline' type='reset' data-test-id='form-close-button'>{closeBtn}</Button>
- </div>
- : <Button btnType='outline' type='reset' data-test-id='form-close-button'>{i18n('Close')}</Button>
- }
- </div>
- );
- }
+ render() {
+ let submitBtn = this.props.labledButtons ? (
+ this.props.submitButtonText ? (
+ this.props.submitButtonText
+ ) : (
+ i18n('Save')
+ )
+ ) : (
+ <SVGIcon className="check" name="check" />
+ );
+ let closeBtn = this.props.labledButtons ? (
+ this.props.cancelButtonText ? (
+ this.props.cancelButtonText
+ ) : (
+ i18n('Cancel')
+ )
+ ) : (
+ <SVGIcon className="close" name="close" />
+ );
+ return (
+ <div className="validation-buttons">
+ {!this.props.isReadOnlyMode ? (
+ <div>
+ <Button
+ type="submit"
+ data-test-id="form-submit-button"
+ disabled={!this.state.isValid}>
+ {submitBtn}
+ </Button>
+ <Button
+ btnType="outline"
+ type="reset"
+ data-test-id="form-close-button">
+ {closeBtn}
+ </Button>
+ </div>
+ ) : (
+ <Button
+ btnType="outline"
+ type="reset"
+ data-test-id="form-close-button">
+ {i18n('Close')}
+ </Button>
+ )}
+ </div>
+ );
+ }
}
export default ValidationButtons;
diff --git a/openecomp-ui/src/nfvo-components/listEditor/ListEditorItemView.jsx b/openecomp-ui/src/nfvo-components/listEditor/ListEditorItemView.jsx
index 60c559a3d1..359af9d3b8 100644
--- a/openecomp-ui/src/nfvo-components/listEditor/ListEditorItemView.jsx
+++ b/openecomp-ui/src/nfvo-components/listEditor/ListEditorItemView.jsx
@@ -19,50 +19,78 @@ import classnames from 'classnames';
import i18n from 'nfvo-utils/i18n/i18n.js';
import SVGIcon from 'sdc-ui/lib/react/SVGIcon.js';
import store from 'sdc-app/AppStore.js';
-import {actionTypes as modalActionTypes} from 'nfvo-components/modal/GlobalModalConstants.js';
+import { actionTypes as modalActionTypes } from 'nfvo-components/modal/GlobalModalConstants.js';
class ListEditorItem extends React.Component {
- static propTypes = {
- onSelect: PropTypes.oneOfType([PropTypes.func, PropTypes.bool]),
- onDelete: PropTypes.oneOfType([PropTypes.func, PropTypes.bool]),
- onEdit: PropTypes.oneOfType([PropTypes.func, PropTypes.bool]),
- children: PropTypes.node,
- isReadOnlyMode: PropTypes.bool
- };
+ static propTypes = {
+ onSelect: PropTypes.oneOfType([PropTypes.func, PropTypes.bool]),
+ onDelete: PropTypes.oneOfType([PropTypes.func, PropTypes.bool]),
+ onEdit: PropTypes.oneOfType([PropTypes.func, PropTypes.bool]),
+ children: PropTypes.node,
+ isReadOnlyMode: PropTypes.bool
+ };
- render() {
- let {onDelete, onSelect, onEdit, children, isReadOnlyMode} = this.props;
- let isAbilityToDelete = isReadOnlyMode === undefined ? true : !isReadOnlyMode;
- return (
- <div className={classnames('list-editor-item-view', {'selectable': Boolean(onSelect)})} data-test-id='list-editor-item'>
- <div className='list-editor-item-view-content' onClick={onSelect}>
- {children}
- </div>
- {(onEdit || onDelete) && <div className='list-editor-item-view-controller'>
- {onEdit && <SVGIcon name='sliders' onClick={() => this.onClickedItem(onEdit)}/>}
- {onDelete && isAbilityToDelete && <SVGIcon name='trashO' data-test-id='delete-list-item' onClick={() => this.onClickedItem(onDelete)}/>}
- </div>}
- </div>
- );
- }
+ render() {
+ let {
+ onDelete,
+ onSelect,
+ onEdit,
+ children,
+ isReadOnlyMode
+ } = this.props;
+ let isAbilityToDelete =
+ isReadOnlyMode === undefined ? true : !isReadOnlyMode;
+ return (
+ <div
+ className={classnames('list-editor-item-view', {
+ selectable: Boolean(onSelect)
+ })}
+ data-test-id="list-editor-item">
+ <div
+ className="list-editor-item-view-content"
+ onClick={onSelect}>
+ {children}
+ </div>
+ {(onEdit || onDelete) && (
+ <div className="list-editor-item-view-controller">
+ {onEdit && (
+ <SVGIcon
+ name="sliders"
+ onClick={() => this.onClickedItem(onEdit)}
+ />
+ )}
+ {onDelete &&
+ isAbilityToDelete && (
+ <SVGIcon
+ name="trashO"
+ data-test-id="delete-list-item"
+ onClick={() => this.onClickedItem(onDelete)}
+ />
+ )}
+ </div>
+ )}
+ </div>
+ );
+ }
- onClickedItem(callBackFunc) {
- if(typeof callBackFunc === 'function') {
- let {isCheckedOut} = this.props;
- if (isCheckedOut === false) {
- store.dispatch({
- type: modalActionTypes.GLOBAL_MODAL_WARNING,
- data: {
- title: i18n('Error'),
- msg: i18n('This item is checkedin/submitted, Click Check Out to continue')
- }
- });
- }
- else {
- callBackFunc();
- }
- }
- }
+ onClickedItem(callBackFunc) {
+ if (typeof callBackFunc === 'function') {
+ let { isCheckedOut } = this.props;
+ if (isCheckedOut === false) {
+ store.dispatch({
+ type: modalActionTypes.GLOBAL_MODAL_WARNING,
+ data: {
+ title: i18n('Error'),
+ msg: i18n(
+ 'This item is checkedin/submitted, Click Check Out to continue'
+ )
+ }
+ });
+ } else {
+ callBackFunc();
+ }
+ }
+ }
}
export default ListEditorItem;
diff --git a/openecomp-ui/src/nfvo-components/listEditor/ListEditorItemViewField.jsx b/openecomp-ui/src/nfvo-components/listEditor/ListEditorItemViewField.jsx
index 839f9a504a..509ea176a5 100644
--- a/openecomp-ui/src/nfvo-components/listEditor/ListEditorItemViewField.jsx
+++ b/openecomp-ui/src/nfvo-components/listEditor/ListEditorItemViewField.jsx
@@ -15,10 +15,8 @@
*/
import React from 'react';
-export const ListEditorItemViewField = ({children}) => (
- <div className='list-editor-item-view-field'>
- {children}
- </div>
+export const ListEditorItemViewField = ({ children }) => (
+ <div className="list-editor-item-view-field">{children}</div>
);
export default ListEditorItemViewField;
diff --git a/openecomp-ui/src/nfvo-components/listEditor/ListEditorView.jsx b/openecomp-ui/src/nfvo-components/listEditor/ListEditorView.jsx
index 16823b7dc5..f71372ce1a 100644
--- a/openecomp-ui/src/nfvo-components/listEditor/ListEditorView.jsx
+++ b/openecomp-ui/src/nfvo-components/listEditor/ListEditorView.jsx
@@ -19,69 +19,107 @@ import Button from 'sdc-ui/lib/react/Button.js';
import classnames from 'classnames';
import ExpandableInput from 'nfvo-components/input/ExpandableInput.jsx';
-const ListEditorHeader = ({onAdd, isReadOnlyMode, title, plusButtonTitle}) => {
- return (
- <div className='list-editor-view-header'>
- {title && <div className='list-editor-view-title'>{title}</div>}
- <div>
- { onAdd &&
- <Button data-test-id='add-button' iconName='plusThin' btnType='link' onClick={onAdd} disabled={isReadOnlyMode === true}>{plusButtonTitle}</Button>
- }
- </div>
- </div>
- );
+const ListEditorHeader = ({
+ onAdd,
+ isReadOnlyMode,
+ title,
+ plusButtonTitle
+}) => {
+ return (
+ <div className="list-editor-view-header">
+ {title && <div className="list-editor-view-title">{title}</div>}
+ <div>
+ {onAdd && (
+ <Button
+ data-test-id="add-button"
+ iconName="plusThin"
+ btnType="link"
+ onClick={onAdd}
+ disabled={isReadOnlyMode === true}>
+ {plusButtonTitle}
+ </Button>
+ )}
+ </div>
+ </div>
+ );
};
-const ListEditorScroller = ({children, twoColumns}) => {
- return (
- <div className='list-editor-view-list-scroller'>
- <div className={classnames('list-editor-view-list', {'two-columns': twoColumns})}>
- {children}
- </div>
- </div>
- );
+const ListEditorScroller = ({ children, twoColumns }) => {
+ return (
+ <div className="list-editor-view-list-scroller">
+ <div
+ className={classnames('list-editor-view-list', {
+ 'two-columns': twoColumns
+ })}>
+ {children}
+ </div>
+ </div>
+ );
};
-const FilterWrapper = ({onFilter, filterValue}) => {
- return (
- <div className='expandble-search-wrapper'>
- <ExpandableInput
- onChange={onFilter}
- iconType='search'
- value={filterValue}/>
- </div>
- );
+const FilterWrapper = ({ onFilter, filterValue }) => {
+ return (
+ <div className="expandble-search-wrapper">
+ <ExpandableInput
+ onChange={onFilter}
+ iconType="search"
+ value={filterValue}
+ />
+ </div>
+ );
};
class ListEditorView extends React.Component {
+ static defaultProps = {
+ className: '',
+ twoColumns: false
+ };
- static defaultProps = {
- className: '',
- twoColumns: false
- };
-
- static propTypes = {
- title: PropTypes.string,
- plusButtonTitle: PropTypes.string,
- children: PropTypes.node,
- filterValue: PropTypes.string,
- onFilter: PropTypes.func,
- className: PropTypes.string,
- isReadOnlyMode: PropTypes.bool,
- placeholder: PropTypes.string,
- twoColumns: PropTypes.bool
- };
-
- render() {
- let {title, plusButtonTitle, onAdd, children, onFilter, className, isReadOnlyMode, twoColumns, filterValue} = this.props;
- return (
- <div className={classnames('list-editor-view', className)}>
- <ListEditorHeader onAdd={onAdd} isReadOnlyMode={isReadOnlyMode} plusButtonTitle={plusButtonTitle} title={title}/>
- {onFilter && (children.length || filterValue) && <FilterWrapper onFilter={onFilter} filterValue={filterValue}/>}
- <ListEditorScroller children={children} twoColumns={twoColumns}/>
- </div>
- );
- }
+ static propTypes = {
+ title: PropTypes.string,
+ plusButtonTitle: PropTypes.string,
+ children: PropTypes.node,
+ filterValue: PropTypes.string,
+ onFilter: PropTypes.func,
+ className: PropTypes.string,
+ isReadOnlyMode: PropTypes.bool,
+ placeholder: PropTypes.string,
+ twoColumns: PropTypes.bool
+ };
+ render() {
+ let {
+ title,
+ plusButtonTitle,
+ onAdd,
+ children,
+ onFilter,
+ className,
+ isReadOnlyMode,
+ twoColumns,
+ filterValue
+ } = this.props;
+ return (
+ <div className={classnames('list-editor-view', className)}>
+ <ListEditorHeader
+ onAdd={onAdd}
+ isReadOnlyMode={isReadOnlyMode}
+ plusButtonTitle={plusButtonTitle}
+ title={title}
+ />
+ {onFilter &&
+ (children.length || filterValue) && (
+ <FilterWrapper
+ onFilter={onFilter}
+ filterValue={filterValue}
+ />
+ )}
+ <ListEditorScroller
+ children={children}
+ twoColumns={twoColumns}
+ />
+ </div>
+ );
+ }
}
export default ListEditorView;
diff --git a/openecomp-ui/src/nfvo-components/listEditor/listEditor.stories.js b/openecomp-ui/src/nfvo-components/listEditor/listEditor.stories.js
index 81125c84ba..67258c956d 100644
--- a/openecomp-ui/src/nfvo-components/listEditor/listEditor.stories.js
+++ b/openecomp-ui/src/nfvo-components/listEditor/listEditor.stories.js
@@ -1,27 +1,25 @@
import React from 'react';
-import {storiesOf, action} from '@kadira/storybook';
+import { storiesOf, action } from '@kadira/storybook';
import ListEditorView from './ListEditorView.jsx';
import ListEditorItemView from './ListEditorItemView.jsx';
import ListEditorItemField from './ListEditorItemViewField.jsx';
-import {text, number} from '@kadira/storybook-addon-knobs';
-import {withKnobs} from '@kadira/storybook-addon-knobs';
+import { text, number } from '@kadira/storybook-addon-knobs';
+import { withKnobs } from '@kadira/storybook-addon-knobs';
-function makeChildren({onEdit = false, onDelete = false} = {}) {
- return (
- [...Array(number('Items', 2)).keys()].map(index => (
- <ListEditorItemView
- key={index}
- onEdit={onEdit ? onEdit : undefined}
- onDelete={onDelete ? onDelete : undefined}>
- <ListEditorItemField>
- <div>{text('field 1', 'Lorum Ipsum')}</div>
- </ListEditorItemField>
- <ListEditorItemField>
- <div>{text('field 2', 'Lorum Ipsum')}</div>
- </ListEditorItemField>
- </ListEditorItemView>)
- )
- );
+function makeChildren({ onEdit = false, onDelete = false } = {}) {
+ return [...Array(number('Items', 2)).keys()].map(index => (
+ <ListEditorItemView
+ key={index}
+ onEdit={onEdit ? onEdit : undefined}
+ onDelete={onDelete ? onDelete : undefined}>
+ <ListEditorItemField>
+ <div>{text('field 1', 'Lorum Ipsum')}</div>
+ </ListEditorItemField>
+ <ListEditorItemField>
+ <div>{text('field 2', 'Lorum Ipsum')}</div>
+ </ListEditorItemField>
+ </ListEditorItemView>
+ ));
}
const stories = storiesOf('ListEditor', module);
@@ -29,32 +27,49 @@ stories.addDecorator(withKnobs);
stories
.add('regular', () => (
- <ListEditorView title='List Editor'>
- {makeChildren()}
- </ListEditorView>
+ <ListEditorView title="List Editor">{makeChildren()}</ListEditorView>
))
.add('two columns', () => (
- <ListEditorView title='List Editor' twoColumns>
+ <ListEditorView title="List Editor" twoColumns>
{makeChildren()}
</ListEditorView>
))
.add('with add', () => (
- <ListEditorView title='List Editor' onAdd={action('onAdd')} plusButtonTitle='Add' twoColumns>
- {makeChildren()}
+ <ListEditorView
+ title="List Editor"
+ onAdd={action('onAdd')}
+ plusButtonTitle="Add"
+ twoColumns>
+ {makeChildren()}
</ListEditorView>
))
.add('with delete', () => (
- <ListEditorView title='List Editor' onAdd={action('onAdd')} plusButtonTitle='Add' twoColumns>
- {makeChildren({onDelete: action('onDelete')})}
+ <ListEditorView
+ title="List Editor"
+ onAdd={action('onAdd')}
+ plusButtonTitle="Add"
+ twoColumns>
+ {makeChildren({ onDelete: action('onDelete') })}
</ListEditorView>
))
.add('with edit', () => (
- <ListEditorView title='List Editor' onAdd={action('onAdd')} plusButtonTitle='Add' twoColumns>
- {makeChildren({onEdit: action('onEdit')})}
+ <ListEditorView
+ title="List Editor"
+ onAdd={action('onAdd')}
+ plusButtonTitle="Add"
+ twoColumns>
+ {makeChildren({ onEdit: action('onEdit') })}
</ListEditorView>
))
.add('with edit and delete', () => (
- <ListEditorView title='List Editor' onAdd={action('onAdd')} plusButtonTitle='Add' twoColumns>
- {makeChildren({onDelete: action('onDelete'), onEdit: action('onEdit')})}
+ <ListEditorView
+ title="List Editor"
+ onAdd={action('onAdd')}
+ plusButtonTitle="Add"
+ twoColumns>
+ {makeChildren({
+ onDelete: action('onDelete'),
+ onEdit: action('onEdit')
+ })}
</ListEditorView>
));
diff --git a/openecomp-ui/src/nfvo-components/loader/Loader.jsx b/openecomp-ui/src/nfvo-components/loader/Loader.jsx
index 9ebe52dcfc..076351bf7a 100644
--- a/openecomp-ui/src/nfvo-components/loader/Loader.jsx
+++ b/openecomp-ui/src/nfvo-components/loader/Loader.jsx
@@ -16,40 +16,39 @@
import React from 'react';
import PropTypes from 'prop-types';
-import {connect} from 'react-redux';
+import { connect } from 'react-redux';
-const mapStateToProps = ({loader}) => {
- return {
- isLoading: loader.isLoading
- };
+const mapStateToProps = ({ loader }) => {
+ return {
+ isLoading: loader.isLoading
+ };
};
class Loader extends React.Component {
-
- static propTypes = {
- isLoading: PropTypes.bool.isRequired
- };
-
- static defaultProps = {
- isLoading: false
- };
-
- shouldComponentUpdate(nextProps) {
- return (nextProps.isLoading !== this.props.isLoading);
- }
-
- render() {
- let {isLoading} = this.props;
- return (
- <div className='onboarding-loader'>
- {
- isLoading && <div className='onboarding-loader-backdrop'>
- <div className='tlv-loader large'></div>
- </div>
- }
- </div>
- );
- }
+ static propTypes = {
+ isLoading: PropTypes.bool.isRequired
+ };
+
+ static defaultProps = {
+ isLoading: false
+ };
+
+ shouldComponentUpdate(nextProps) {
+ return nextProps.isLoading !== this.props.isLoading;
+ }
+
+ render() {
+ let { isLoading } = this.props;
+ return (
+ <div className="onboarding-loader">
+ {isLoading && (
+ <div className="onboarding-loader-backdrop">
+ <div className="tlv-loader large" />
+ </div>
+ )}
+ </div>
+ );
+ }
}
-export default connect(mapStateToProps) (Loader);
+export default connect(mapStateToProps)(Loader);
diff --git a/openecomp-ui/src/nfvo-components/loader/LoaderConstants.js b/openecomp-ui/src/nfvo-components/loader/LoaderConstants.js
index 2b531b08fa..e367a74352 100644
--- a/openecomp-ui/src/nfvo-components/loader/LoaderConstants.js
+++ b/openecomp-ui/src/nfvo-components/loader/LoaderConstants.js
@@ -16,9 +16,9 @@
import keyMirror from 'nfvo-utils/KeyMirror.js';
export const actionTypes = keyMirror({
- SHOW: null,
- HIDE: null,
+ SHOW: null,
+ HIDE: null,
- SEND_REQUEST: null,
- RECEIVE_RESPONSE: null
+ SEND_REQUEST: null,
+ RECEIVE_RESPONSE: null
});
diff --git a/openecomp-ui/src/nfvo-components/loader/LoaderReducer.js b/openecomp-ui/src/nfvo-components/loader/LoaderReducer.js
index 3afdad0573..1d0f6790e1 100644
--- a/openecomp-ui/src/nfvo-components/loader/LoaderReducer.js
+++ b/openecomp-ui/src/nfvo-components/loader/LoaderReducer.js
@@ -13,43 +13,54 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-import {actionTypes} from './LoaderConstants.js';
+import { actionTypes } from './LoaderConstants.js';
-export default (state = {fetchingRequests : 0, currentlyFetching : [], isLoading : false}, action) => {
- let fetchingRequests = state.fetchingRequests;
- let newArray;
- switch (action.type) {
- case actionTypes.SEND_REQUEST:
- fetchingRequests++;
- newArray = state.currentlyFetching.slice();
- newArray.splice(0, 0, action.url);
- if (DEBUG) {
- console.log('Loader SEND REQUEST url: ' + action.url);
- console.log('Loader SEND REQUEST number of fetching requests: ' + fetchingRequests);
- }
- return {
- fetchingRequests: fetchingRequests,
- currentlyFetching : newArray,
- isLoading: true
- };
- case actionTypes.RECEIVE_RESPONSE:
- fetchingRequests--;
+export default (
+ state = { fetchingRequests: 0, currentlyFetching: [], isLoading: false },
+ action
+) => {
+ let fetchingRequests = state.fetchingRequests;
+ let newArray;
+ switch (action.type) {
+ case actionTypes.SEND_REQUEST:
+ fetchingRequests++;
+ newArray = state.currentlyFetching.slice();
+ newArray.splice(0, 0, action.url);
+ if (DEBUG) {
+ console.log('Loader SEND REQUEST url: ' + action.url);
+ console.log(
+ 'Loader SEND REQUEST number of fetching requests: ' +
+ fetchingRequests
+ );
+ }
+ return {
+ fetchingRequests: fetchingRequests,
+ currentlyFetching: newArray,
+ isLoading: true
+ };
+ case actionTypes.RECEIVE_RESPONSE:
+ fetchingRequests--;
- newArray = state.currentlyFetching.filter((item) => {return item !== action.url;});
- if (DEBUG) {
- console.log('Loader RECEIVE_RESPONSE url: ' + action.url);
- console.log('Loader RECEIVE_RESPONSE: number of fetching requests: ' + fetchingRequests);
- }
- return {
- currentlyFetching : newArray,
- fetchingRequests: fetchingRequests,
- isLoading: (fetchingRequests !== 0)
- };
- case actionTypes.SHOW:
- return {isLoading: true};
- case actionTypes.HIDE:
- return {isLoading: false};
- default:
- return state;
- }
+ newArray = state.currentlyFetching.filter(item => {
+ return item !== action.url;
+ });
+ if (DEBUG) {
+ console.log('Loader RECEIVE_RESPONSE url: ' + action.url);
+ console.log(
+ 'Loader RECEIVE_RESPONSE: number of fetching requests: ' +
+ fetchingRequests
+ );
+ }
+ return {
+ currentlyFetching: newArray,
+ fetchingRequests: fetchingRequests,
+ isLoading: fetchingRequests !== 0
+ };
+ case actionTypes.SHOW:
+ return { isLoading: true };
+ case actionTypes.HIDE:
+ return { isLoading: false };
+ default:
+ return state;
+ }
};
diff --git a/openecomp-ui/src/nfvo-components/modal/GlobalModal.js b/openecomp-ui/src/nfvo-components/modal/GlobalModal.js
index 75b7983ac3..3f19bd76a3 100644
--- a/openecomp-ui/src/nfvo-components/modal/GlobalModal.js
+++ b/openecomp-ui/src/nfvo-components/modal/GlobalModal.js
@@ -16,145 +16,195 @@
import React from 'react';
import PropTypes from 'prop-types';
-import {connect} from 'react-redux';
+import { connect } from 'react-redux';
import Modal from 'nfvo-components/modal/Modal.jsx';
import Button from 'sdc-ui/lib/react/Button.js';
import i18n from 'nfvo-utils/i18n/i18n.js';
-import {modalContentComponents} from 'sdc-app/common/modal/ModalContentMapper.js';
-import {actionTypes, typeEnum} from './GlobalModalConstants.js';
-
+import { modalContentComponents } from 'sdc-app/common/modal/ModalContentMapper.js';
+import { actionTypes, typeEnum } from './GlobalModalConstants.js';
const typeClass = {
- 'default': 'primary',
- error: 'negative',
- warning: 'warning',
- success: 'positive'
+ default: 'primary',
+ error: 'negative',
+ warning: 'warning',
+ success: 'positive'
};
const type2HeaderColor = {
- 'default': 'primary',
- error: 'danger',
- warning: 'warning',
- success: 'success'
+ default: 'primary',
+ error: 'danger',
+ warning: 'warning',
+ success: 'success'
};
-
-const ModalFooter = ({type, onConfirmed, onDeclined, onClose, confirmationButtonText, cancelButtonText}) => {
- let myPropsForNoConfirmed = {};
- if (onConfirmed) {
- myPropsForNoConfirmed.btnType = 'outline';
- }
- return (
- <Modal.Footer>
- <div className='sdc-modal-footer'>
- {onConfirmed && <Button data-test-id='sdc-modal-confirm-button' color={typeClass[type]} onClick={() => {
- onConfirmed();
- onClose();
- }}>{confirmationButtonText}</Button>}
- <Button {...myPropsForNoConfirmed} data-test-id='sdc-modal-cancel-button' btnType='outline' color={typeClass[type]} onClick={onDeclined ? () => {
- onDeclined();
- onClose();} : () => onClose()}>
- {cancelButtonText}
- </Button>
- </div>
- </Modal.Footer>
- );
+const ModalFooter = ({
+ type,
+ onConfirmed,
+ onDeclined,
+ onClose,
+ confirmationButtonText,
+ cancelButtonText
+}) => {
+ let myPropsForNoConfirmed = {};
+ if (onConfirmed) {
+ myPropsForNoConfirmed.btnType = 'outline';
+ }
+ return (
+ <Modal.Footer>
+ <div className="sdc-modal-footer">
+ {onConfirmed && (
+ <Button
+ data-test-id="sdc-modal-confirm-button"
+ color={typeClass[type]}
+ onClick={() => {
+ onConfirmed();
+ onClose();
+ }}>
+ {confirmationButtonText}
+ </Button>
+ )}
+ <Button
+ {...myPropsForNoConfirmed}
+ data-test-id="sdc-modal-cancel-button"
+ btnType="outline"
+ color={typeClass[type]}
+ onClick={
+ onDeclined
+ ? () => {
+ onDeclined();
+ onClose();
+ }
+ : () => onClose()
+ }>
+ {cancelButtonText}
+ </Button>
+ </div>
+ </Modal.Footer>
+ );
};
ModalFooter.defaultProps = {
- type: 'default',
- confirmationButtonText: i18n('OK'),
- cancelButtonText: i18n('Cancel')
+ type: 'default',
+ confirmationButtonText: i18n('OK'),
+ cancelButtonText: i18n('Cancel')
};
ModalFooter.PropTypes = {
- type: PropTypes.string,
- confirmationButtonText: PropTypes.string,
- cancelButtonText: PropTypes.string
+ type: PropTypes.string,
+ confirmationButtonText: PropTypes.string,
+ cancelButtonText: PropTypes.string
};
-export const mapStateToProps = ({modal}) => {
- const show = !!modal;
- return {
- show,
- ...modal
- };
+export const mapStateToProps = ({ modal }) => {
+ const show = !!modal;
+ return {
+ show,
+ ...modal
+ };
};
-export const mapActionToProps = (dispatch) => {
- return {
- onClose: () => dispatch({type: actionTypes.GLOBAL_MODAL_CLOSE})
- };
+export const mapActionToProps = dispatch => {
+ return {
+ onClose: () => dispatch({ type: actionTypes.GLOBAL_MODAL_CLOSE })
+ };
};
-
-export class GlobalModalView extends React.Component {
-
- static propTypes = {
- show: PropTypes.bool,
- type: PropTypes.oneOf(['default', 'error', 'warning', 'success']),
- title: PropTypes.string,
- modalComponentProps: PropTypes.object,
- modalComponentName: PropTypes.string,
- onConfirmed: PropTypes.func,
- onDeclined: PropTypes.func,
- confirmationButtonText: PropTypes.string,
- cancelButtonText: PropTypes.string
- };
-
- static defaultProps = {
- show: false,
- type: 'default',
- title: ''
- };
-
- render() {
- let {title, type, show, modalComponentName, modalComponentProps,
- modalClassName, msg, onConfirmed, onDeclined, confirmationButtonText, cancelButtonText, onClose} = this.props;
- const ComponentToRender = modalContentComponents[modalComponentName];
- return (
- <Modal show={show} bsSize={modalComponentProps && modalComponentProps.size} className={`onborading-modal ${modalClassName || ''} ${type2HeaderColor[type]}`}>
- <Modal.Header>
- <Modal.Title>{title}</Modal.Title>
- </Modal.Header>
- <Modal.Body>
- {ComponentToRender ?
- <ComponentToRender {...modalComponentProps}/> :
- msg && typeof msg === 'string' ?
- <div> {msg.split('\n').map((txt, i) => <span key={i}> {txt} <br/> </span>)} </div> :
- msg
- }
- </Modal.Body>
- {(onConfirmed || onDeclined || type !== typeEnum.DEFAULT) &&
- <ModalFooter
- type={type}
- onConfirmed={onConfirmed}
- onDeclined={onDeclined}
- onClose={onClose}
- confirmationButtonText={confirmationButtonText}
- cancelButtonText={cancelButtonText}/>}
- </Modal>
- );
- }
-
- componentDidUpdate() {
- if (this.props.timeout) {
- setTimeout(this.props.onClose, this.props.timeout);
- }
- }
-};
+export class GlobalModalView extends React.Component {
+ static propTypes = {
+ show: PropTypes.bool,
+ type: PropTypes.oneOf(['default', 'error', 'warning', 'success']),
+ title: PropTypes.string,
+ modalComponentProps: PropTypes.object,
+ modalComponentName: PropTypes.string,
+ onConfirmed: PropTypes.func,
+ onDeclined: PropTypes.func,
+ confirmationButtonText: PropTypes.string,
+ cancelButtonText: PropTypes.string
+ };
+
+ static defaultProps = {
+ show: false,
+ type: 'default',
+ title: ''
+ };
+
+ render() {
+ let {
+ title,
+ type,
+ show,
+ modalComponentName,
+ modalComponentProps,
+ modalClassName,
+ msg,
+ onConfirmed,
+ onDeclined,
+ confirmationButtonText,
+ cancelButtonText,
+ onClose
+ } = this.props;
+ const ComponentToRender = modalContentComponents[modalComponentName];
+ return (
+ <Modal
+ show={show}
+ bsSize={modalComponentProps && modalComponentProps.size}
+ className={`onborading-modal ${modalClassName || ''} ${
+ type2HeaderColor[type]
+ }`}>
+ <Modal.Header>
+ <Modal.Title>{title}</Modal.Title>
+ </Modal.Header>
+ <Modal.Body>
+ {ComponentToRender ? (
+ <ComponentToRender {...modalComponentProps} />
+ ) : msg && typeof msg === 'string' ? (
+ <div>
+ {' '}
+ {msg.split('\n').map((txt, i) => (
+ <span key={i}>
+ {' '}
+ {txt} <br />{' '}
+ </span>
+ ))}{' '}
+ </div>
+ ) : (
+ msg
+ )}
+ </Modal.Body>
+ {(onConfirmed || onDeclined || type !== typeEnum.DEFAULT) && (
+ <ModalFooter
+ type={type}
+ onConfirmed={onConfirmed}
+ onDeclined={onDeclined}
+ onClose={onClose}
+ confirmationButtonText={confirmationButtonText}
+ cancelButtonText={cancelButtonText}
+ />
+ )}
+ </Modal>
+ );
+ }
+
+ componentDidUpdate() {
+ if (this.props.timeout) {
+ setTimeout(this.props.onClose, this.props.timeout);
+ }
+ }
+}
GlobalModalView.propTypes = {
- show: PropTypes.bool,
- type: PropTypes.oneOf(['default', 'error', 'warning', 'success']),
- title: PropTypes.string,
- modalComponentProps: PropTypes.object,
- modalComponentName: PropTypes.string,
- onConfirmed: PropTypes.func,
- onDeclined: PropTypes.func,
- confirmationButtonText: PropTypes.string,
- cancelButtonText: PropTypes.string
+ show: PropTypes.bool,
+ type: PropTypes.oneOf(['default', 'error', 'warning', 'success']),
+ title: PropTypes.string,
+ modalComponentProps: PropTypes.object,
+ modalComponentName: PropTypes.string,
+ onConfirmed: PropTypes.func,
+ onDeclined: PropTypes.func,
+ confirmationButtonText: PropTypes.string,
+ cancelButtonText: PropTypes.string
};
-export default connect(mapStateToProps, mapActionToProps, null, {withRef: true})(GlobalModalView);
+export default connect(mapStateToProps, mapActionToProps, null, {
+ withRef: true
+})(GlobalModalView);
diff --git a/openecomp-ui/src/nfvo-components/modal/GlobalModalConstants.js b/openecomp-ui/src/nfvo-components/modal/GlobalModalConstants.js
index 3e5545371a..e9c1853c97 100644
--- a/openecomp-ui/src/nfvo-components/modal/GlobalModalConstants.js
+++ b/openecomp-ui/src/nfvo-components/modal/GlobalModalConstants.js
@@ -16,23 +16,21 @@
import keyMirror from 'nfvo-utils/KeyMirror.js';
export const actionTypes = keyMirror({
- GLOBAL_MODAL_SHOW: null,
- GLOBAL_MODAL_CLOSE: null,
- GLOBAL_MODAL_ERROR: null,
- GLOBAL_MODAL_WARNING: null,
- GLOBAL_MODAL_SUCCESS: null,
-
+ GLOBAL_MODAL_SHOW: null,
+ GLOBAL_MODAL_CLOSE: null,
+ GLOBAL_MODAL_ERROR: null,
+ GLOBAL_MODAL_WARNING: null,
+ GLOBAL_MODAL_SUCCESS: null
});
-
export const typeEnum = {
- DEFAULT: 'default',
- ERROR: 'error',
- WARNING: 'warning',
- SUCCESS: 'success'
+ DEFAULT: 'default',
+ ERROR: 'error',
+ WARNING: 'warning',
+ SUCCESS: 'success'
};
-export const modalSizes = {
- LARGE: 'large',
- SMALL: 'small'
+export const modalSizes = {
+ LARGE: 'large',
+ SMALL: 'small'
};
diff --git a/openecomp-ui/src/nfvo-components/modal/GlobalModalReducer.js b/openecomp-ui/src/nfvo-components/modal/GlobalModalReducer.js
index 28674ea569..b2273fa7a7 100644
--- a/openecomp-ui/src/nfvo-components/modal/GlobalModalReducer.js
+++ b/openecomp-ui/src/nfvo-components/modal/GlobalModalReducer.js
@@ -14,37 +14,37 @@
* permissions and limitations under the License.
*/
-import {actionTypes, typeEnum} from './GlobalModalConstants.js';
+import { actionTypes, typeEnum } from './GlobalModalConstants.js';
export default (state = null, action) => {
- switch (action.type) {
- case actionTypes.GLOBAL_MODAL_SHOW:
- return {
- ...action.data
- };
- case actionTypes.GLOBAL_MODAL_ERROR:
- return {
- type: typeEnum.ERROR,
- modalClassName: 'notification-modal',
- ...action.data
- };
- case actionTypes.GLOBAL_MODAL_WARNING:
- return {
- type: typeEnum.WARNING,
- modalClassName: 'notification-modal',
- ...action.data
- };
+ switch (action.type) {
+ case actionTypes.GLOBAL_MODAL_SHOW:
+ return {
+ ...action.data
+ };
+ case actionTypes.GLOBAL_MODAL_ERROR:
+ return {
+ type: typeEnum.ERROR,
+ modalClassName: 'notification-modal',
+ ...action.data
+ };
+ case actionTypes.GLOBAL_MODAL_WARNING:
+ return {
+ type: typeEnum.WARNING,
+ modalClassName: 'notification-modal',
+ ...action.data
+ };
- case actionTypes.GLOBAL_MODAL_SUCCESS:
- return {
- type: typeEnum.SUCCESS,
- modalClassName: 'notification-modal',
- ...action.data
- };
+ case actionTypes.GLOBAL_MODAL_SUCCESS:
+ return {
+ type: typeEnum.SUCCESS,
+ modalClassName: 'notification-modal',
+ ...action.data
+ };
- case actionTypes.GLOBAL_MODAL_CLOSE:
- return null;
- default:
- return state;
- }
+ case actionTypes.GLOBAL_MODAL_CLOSE:
+ return null;
+ default:
+ return state;
+ }
};
diff --git a/openecomp-ui/src/nfvo-components/modal/Modal.jsx b/openecomp-ui/src/nfvo-components/modal/Modal.jsx
index b0f704dba9..cfd757501f 100644
--- a/openecomp-ui/src/nfvo-components/modal/Modal.jsx
+++ b/openecomp-ui/src/nfvo-components/modal/Modal.jsx
@@ -20,65 +20,63 @@ import BootstrapModal from 'react-bootstrap/lib/Modal.js';
let nextModalId = 0;
export default class Modal extends React.Component {
+ static Header = BootstrapModal.Header;
- static Header = BootstrapModal.Header;
+ static Title = BootstrapModal.Title;
- static Title = BootstrapModal.Title;
+ static Footer = BootstrapModal.Footer;
- static Footer = BootstrapModal.Footer;
+ static Body = class ModalBody extends React.Component {
+ render() {
+ let { children, ...props } = this.props;
+ return (
+ <BootstrapModal.Body {...props}>{children}</BootstrapModal.Body>
+ );
+ }
- static Body = class ModalBody extends React.Component {
+ componentDidMount() {
+ let element = ReactDOM.findDOMNode(this);
+ element.addEventListener('click', event => {
+ if (event.target.tagName === 'A') {
+ event.preventDefault();
+ }
+ });
+ ['wheel', 'mousewheel', 'DOMMouseScroll'].forEach(eventType =>
+ element.addEventListener(eventType, event =>
+ event.stopPropagation()
+ )
+ );
+ }
+ };
- render() {
- let {children, ...props} = this.props;
- return (
- <BootstrapModal.Body {...props}>
- {children}
- </BootstrapModal.Body>
- );
- }
+ componentWillMount() {
+ this.modalId = `dox-ui-modal-${nextModalId++}`;
+ }
- componentDidMount() {
- let element = ReactDOM.findDOMNode(this);
- element.addEventListener('click', event => {
- if (event.target.tagName === 'A') {
- event.preventDefault();
- }
- });
- ['wheel', 'mousewheel', 'DOMMouseScroll'].forEach(eventType =>
- element.addEventListener(eventType, event => event.stopPropagation())
- );
- }
- };
+ componentDidMount() {
+ this.ensureRootClass();
+ }
- componentWillMount() {
- this.modalId = `dox-ui-modal-${nextModalId++}`;
- }
+ componentDidUpdate() {
+ this.ensureRootClass();
+ }
- componentDidMount() {
- this.ensureRootClass();
- }
+ ensureRootClass() {
+ let element = document.getElementById(this.modalId);
+ while (element && !element.hasAttribute('data-reactroot')) {
+ element = element.parentElement;
+ }
+ if (element && !element.classList.contains('dox-ui')) {
+ element.classList.add('dox-ui');
+ }
+ }
- componentDidUpdate() {
- this.ensureRootClass();
- }
-
- ensureRootClass() {
- let element = document.getElementById(this.modalId);
- while(element && !element.hasAttribute('data-reactroot')) {
- element = element.parentElement;
- }
- if (element && !element.classList.contains('dox-ui')) {
- element.classList.add('dox-ui');
- }
- }
-
- render() {
- let {children, ...props} = this.props;
- return (
- <BootstrapModal {...props} id={this.modalId}>
- {children}
- </BootstrapModal>
- );
- }
+ render() {
+ let { children, ...props } = this.props;
+ return (
+ <BootstrapModal {...props} id={this.modalId}>
+ {children}
+ </BootstrapModal>
+ );
+ }
}
diff --git a/openecomp-ui/src/nfvo-components/overlay/Overlay.jsx b/openecomp-ui/src/nfvo-components/overlay/Overlay.jsx
index 054c1e2852..7ed898e593 100644
--- a/openecomp-ui/src/nfvo-components/overlay/Overlay.jsx
+++ b/openecomp-ui/src/nfvo-components/overlay/Overlay.jsx
@@ -18,23 +18,21 @@ import React from 'react';
import enhanceWithClickOutside from 'react-click-outside';
class Overlay extends React.Component {
+ handleClickOutside() {
+ if (this.props.onClose) {
+ this.props.onClose();
+ }
+ }
- handleClickOutside() {
- if (this.props.onClose) {
- this.props.onClose();
- }
- }
-
- render() {
- return (
- <div className='onboarding-overlay'>
- <div className='arrow-up'></div>
- <div className='arrow-border'/>
- {this.props.children}
- </div>
- );
- }
-
-};
+ render() {
+ return (
+ <div className="onboarding-overlay">
+ <div className="arrow-up" />
+ <div className="arrow-border" />
+ {this.props.children}
+ </div>
+ );
+ }
+}
export default enhanceWithClickOutside(Overlay);
diff --git a/openecomp-ui/src/nfvo-components/panel/NavigationSideBar.jsx b/openecomp-ui/src/nfvo-components/panel/NavigationSideBar.jsx
index 2eda7e69bf..61121df335 100644
--- a/openecomp-ui/src/nfvo-components/panel/NavigationSideBar.jsx
+++ b/openecomp-ui/src/nfvo-components/panel/NavigationSideBar.jsx
@@ -19,116 +19,159 @@ import classnames from 'classnames';
import Collapse from 'react-bootstrap/lib/Collapse.js';
class NavigationSideBar extends React.Component {
- static PropTypes = {
- activeItemId: PropTypes.string.isRequired,
- onSelect: PropTypes.func,
- onToggle: PropTypes.func,
- groups: PropTypes.array,
- disabled: PropTypes.bool
- };
+ static PropTypes = {
+ activeItemId: PropTypes.string.isRequired,
+ onSelect: PropTypes.func,
+ onToggle: PropTypes.func,
+ groups: PropTypes.array,
+ disabled: PropTypes.bool
+ };
- constructor(props) {
- super(props);
- this.state = {
- activeItemId: null
- };
- this.handleItemClicked = this.handleItemClicked.bind(this);
- }
+ constructor(props) {
+ super(props);
+ this.state = {
+ activeItemId: null
+ };
+ this.handleItemClicked = this.handleItemClicked.bind(this);
+ }
- render() {
- let {groups, activeItemId, disabled = false} = this.props;
+ render() {
+ let { groups, activeItemId, disabled = false } = this.props;
- return (
- <div className={`navigation-side-content ${disabled ? 'disabled' : ''}`}>
- {groups.map(group => (
- <NavigationMenu menu={group} activeItemId={activeItemId} onNavigationItemClick={this.handleItemClicked} key={'menu_' + group.id} />
- ))}
- </div>
- );
- }
+ return (
+ <div
+ className={`navigation-side-content ${
+ disabled ? 'disabled' : ''
+ }`}>
+ {groups.map(group => (
+ <NavigationMenu
+ menu={group}
+ activeItemId={activeItemId}
+ onNavigationItemClick={this.handleItemClicked}
+ key={'menu_' + group.id}
+ />
+ ))}
+ </div>
+ );
+ }
- handleItemClicked(event, item) {
- event.stopPropagation();
- if(this.props.onToggle) {
- this.props.onToggle(this.props.groups, item.id);
- }
- if(item.onSelect) {
- item.onSelect();
- }
- if(this.props.onSelect) {
- this.props.onSelect(item);
- }
- }
+ handleItemClicked(event, item) {
+ event.stopPropagation();
+ if (this.props.onToggle) {
+ this.props.onToggle(this.props.groups, item.id);
+ }
+ if (item.onSelect) {
+ item.onSelect();
+ }
+ if (this.props.onSelect) {
+ this.props.onSelect(item);
+ }
+ }
}
class NavigationMenu extends React.Component {
- static PropTypes = {
- activeItemId: PropTypes.string.isRequired,
- onNavigationItemClick: PropTypes.func,
- menu: PropTypes.array
- };
+ static PropTypes = {
+ activeItemId: PropTypes.string.isRequired,
+ onNavigationItemClick: PropTypes.func,
+ menu: PropTypes.array
+ };
- render() {
- const {menu, activeItemId, onNavigationItemClick} = this.props;
- return (
- <div className='navigation-group' key={menu.id}>
- <NavigationMenuHeader title={menu.name} />
- <NavigationMenuItems items={menu.items} activeItemId={activeItemId} onNavigationItemClick={onNavigationItemClick} />
- </div>);
- }
+ render() {
+ const { menu, activeItemId, onNavigationItemClick } = this.props;
+ return (
+ <div className="navigation-group" key={menu.id}>
+ <NavigationMenuHeader title={menu.name} />
+ <NavigationMenuItems
+ items={menu.items}
+ activeItemId={activeItemId}
+ onNavigationItemClick={onNavigationItemClick}
+ />
+ </div>
+ );
+ }
}
function NavigationMenuHeader(props) {
- return <div className='group-name' data-test-id='navbar-group-name'>{props.title}</div>;
+ return (
+ <div className="group-name" data-test-id="navbar-group-name">
+ {props.title}
+ </div>
+ );
}
function getItemDataTestId(itemId) {
- return itemId.split('|')[0];
+ return itemId.split('|')[0];
}
function NavigationMenuItems(props) {
- const {items, activeItemId, onNavigationItemClick} = props;
- return (
- <div className='navigation-group-items'>
- {
- items && items.map(item => (<NavigationMenuItem key={'menuItem_' + item.id} item={item} activeItemId={activeItemId} onNavigationItemClick={onNavigationItemClick} />))
- }
- </div>
- );
+ const { items, activeItemId, onNavigationItemClick } = props;
+ return (
+ <div className="navigation-group-items">
+ {items &&
+ items.map(item => (
+ <NavigationMenuItem
+ key={'menuItem_' + item.id}
+ item={item}
+ activeItemId={activeItemId}
+ onNavigationItemClick={onNavigationItemClick}
+ />
+ ))}
+ </div>
+ );
}
function NavigationMenuItem(props) {
- const {onNavigationItemClick, item, activeItemId} = props;
- const isGroup = item.items && item.items.length > 0;
- return (
- <div className={classnames('navigation-group-item', {'selected-item': item.id === activeItemId})} key={'item_' + item.id}>
- <NavigationLink item={item} activeItemId={activeItemId} onClick={onNavigationItemClick} />
- {isGroup && <Collapse in={item.expanded} data-test-id={'navigation-group-' + getItemDataTestId(item.id)}>
- <div>
- {item.items.map(subItem => (<NavigationMenuItem key={'menuItem_' + subItem.id} item={subItem} onNavigationItemClick={onNavigationItemClick} activeItemId={activeItemId} />)) }
- </div>
- </Collapse>
- }
- </div>
- );
+ const { onNavigationItemClick, item, activeItemId } = props;
+ const isGroup = item.items && item.items.length > 0;
+ return (
+ <div
+ className={classnames('navigation-group-item', {
+ 'selected-item': item.id === activeItemId
+ })}
+ key={'item_' + item.id}>
+ <NavigationLink
+ item={item}
+ activeItemId={activeItemId}
+ onClick={onNavigationItemClick}
+ />
+ {isGroup && (
+ <Collapse
+ in={item.expanded}
+ data-test-id={
+ 'navigation-group-' + getItemDataTestId(item.id)
+ }>
+ <div>
+ {item.items.map(subItem => (
+ <NavigationMenuItem
+ key={'menuItem_' + subItem.id}
+ item={subItem}
+ onNavigationItemClick={onNavigationItemClick}
+ activeItemId={activeItemId}
+ />
+ ))}
+ </div>
+ </Collapse>
+ )}
+ </div>
+ );
}
function NavigationLink(props) {
- const {item, activeItemId, onClick} = props;
- // todo should this be button
- return (
- <div
- key={'navAction_' + item.id}
- className={classnames('navigation-group-item-name', {
- 'selected': item.id === activeItemId,
- 'disabled': item.disabled,
- 'bold-name': item.expanded,
- 'hidden': item.hidden
- })}
- onClick={(event) => onClick(event, item)}
- data-test-id={'navbar-group-item-' + getItemDataTestId(item.id)}>
- {item.name}
- </div>
- );
+ const { item, activeItemId, onClick } = props;
+ // todo should this be button
+ return (
+ <div
+ key={'navAction_' + item.id}
+ className={classnames('navigation-group-item-name', {
+ selected: item.id === activeItemId,
+ disabled: item.disabled,
+ 'bold-name': item.expanded,
+ hidden: item.hidden
+ })}
+ onClick={event => onClick(event, item)}
+ data-test-id={'navbar-group-item-' + getItemDataTestId(item.id)}>
+ {item.name}
+ </div>
+ );
}
export default NavigationSideBar;
diff --git a/openecomp-ui/src/nfvo-components/panel/versionController/VersionController.jsx b/openecomp-ui/src/nfvo-components/panel/versionController/VersionController.jsx
index 57fa86f561..c9c5789622 100644
--- a/openecomp-ui/src/nfvo-components/panel/versionController/VersionController.jsx
+++ b/openecomp-ui/src/nfvo-components/panel/versionController/VersionController.jsx
@@ -17,125 +17,224 @@ import React from 'react';
import PropTypes from 'prop-types';
import i18n from 'nfvo-utils/i18n/i18n.js';
-import {actionsEnum} from './VersionControllerConstants.js';
+import { actionsEnum } from './VersionControllerConstants.js';
import ActionButtons from './components/ActionButtons.jsx';
import NotificationsView from 'sdc-app/onboarding/userNotifications/NotificationsView.jsx';
-
class VersionController extends React.Component {
-
- static propTypes = {
- version: PropTypes.object,
- viewableVersions: PropTypes.array,
- onVersionSwitching: PropTypes.func,
- callVCAction: PropTypes.func,
- onSave: PropTypes.func,
- onClose: PropTypes.func,
- isFormDataValid: PropTypes.bool,
- onOpenCommentCommitModal: PropTypes.func,
- isReadOnlyMode: PropTypes.bool
- };
-
- state = {
- showPermissions: false,
- showRevisions: false
- };
-
- render() {
- let {version = {}, viewableVersions = [], onVersionSwitching, onMoreVersionsClick, callVCAction, onSave, isReadOnlyMode, itemPermission,
- isFormDataValid, onClose, onManagePermissions, permissions = {}, userInfo, usersList, itemName,
- onOpenCommentCommitModal, onOpenRevisionsModal, isManual, candidateInProcess, isArchived} = this.props;
- return (
- <div className='version-controller-bar'>
- <div className={`vc-container ${candidateInProcess ? 'disabled' : ''}`}>
- <div className='version-status-container'>
- <VersionSelector
- viewableVersions={viewableVersions}
- version={version}
- onVersionSwitching={onVersionSwitching}
- onMoreVersionsClick={() => onMoreVersionsClick({itemName, users: usersList})}/>
- {isArchived && <div className='depricated-item-status'>{i18n('Archived')}</div>}
- </div>
- <div className='save-submit-cancel-container'>
- <ActionButtons onSubmit={callVCAction ? () => this.submit(callVCAction, version) : undefined}
- onRevert={callVCAction ? () => this.revert(callVCAction, version) : undefined}
- onOpenRevisionsModal={onOpenRevisionsModal}
- onSave={onSave ? () => onSave() : undefined}
- permissions={permissions}
- userInfo={userInfo}
- onManagePermissions={onManagePermissions}
- showPermissions={this.state.showPermissions}
- onClosePermissions={()=>this.setState({showPermissions: false})}
- onClickPermissions={() => this.onClickPermissions()}
- onSync={callVCAction ? () => this.sync(callVCAction, version) : undefined}
- onOpenCommentCommitModal={onOpenCommentCommitModal}
- onCommit={callVCAction ? (comment) => this.commit(callVCAction, version, comment) : undefined}
- isFormDataValid={isFormDataValid}
- itemPermissions={itemPermission}
- isArchived={isArchived}
- isReadOnlyMode={isReadOnlyMode || candidateInProcess}
- isManual={isManual} />
- <div className='vc-separator'></div>
- <NotificationsView />
- {onClose && <div className='vc-nav-item-close' onClick={() => onClose()} data-test-id='vc-cancel-btn'> X</div>}
- </div>
- </div>
- </div>
- );
- }
-
- onClickPermissions() {
- let {onOpenPermissions, usersList} = this.props;
- let {showPermissions} = this.state;
- let promise = showPermissions ? Promise.resolve() : onOpenPermissions({users: usersList});
- promise.then(() => this.setState({showPermissions: !showPermissions}));
- }
-
-
- submit(callVCAction, version) {
- const action = actionsEnum.SUBMIT;
- callVCAction(action, version);
- }
-
- revert(callVCAction, version) {
- const action = actionsEnum.REVERT;
- callVCAction(action, version);
- }
-
- sync(callVCAction, version) {
- const action = actionsEnum.SYNC;
- callVCAction(action, version);
- }
-
- commit(callVCAction, version, comment) {
- const action = actionsEnum.COMMIT;
- callVCAction(action, version, comment);
- }
-
- permissions() {
-
- }
+ static propTypes = {
+ version: PropTypes.object,
+ viewableVersions: PropTypes.array,
+ onVersionSwitching: PropTypes.func,
+ callVCAction: PropTypes.func,
+ onSave: PropTypes.func,
+ onClose: PropTypes.func,
+ isFormDataValid: PropTypes.bool,
+ onOpenCommentCommitModal: PropTypes.func,
+ isReadOnlyMode: PropTypes.bool
+ };
+
+ state = {
+ showPermissions: false,
+ showRevisions: false
+ };
+
+ render() {
+ let {
+ version = {},
+ viewableVersions = [],
+ onVersionSwitching,
+ onMoreVersionsClick,
+ callVCAction,
+ onSave,
+ isReadOnlyMode,
+ itemPermission,
+ isFormDataValid,
+ onClose,
+ onManagePermissions,
+ permissions = {},
+ userInfo,
+ usersList,
+ itemName,
+ onOpenCommentCommitModal,
+ onOpenRevisionsModal,
+ isManual,
+ candidateInProcess,
+ isArchived
+ } = this.props;
+ return (
+ <div className="version-controller-bar">
+ <div
+ className={`vc-container ${
+ candidateInProcess ? 'disabled' : ''
+ }`}>
+ <div className="version-status-container">
+ <VersionSelector
+ viewableVersions={viewableVersions}
+ version={version}
+ onVersionSwitching={onVersionSwitching}
+ onMoreVersionsClick={() =>
+ onMoreVersionsClick({
+ itemName,
+ users: usersList
+ })
+ }
+ />
+ {isArchived && (
+ <div className="depricated-item-status">
+ {i18n('Archived')}
+ </div>
+ )}
+ </div>
+ <div className="save-submit-cancel-container">
+ <ActionButtons
+ onSubmit={
+ callVCAction
+ ? () => this.submit(callVCAction, version)
+ : undefined
+ }
+ onRevert={
+ callVCAction
+ ? () => this.revert(callVCAction, version)
+ : undefined
+ }
+ onOpenRevisionsModal={onOpenRevisionsModal}
+ onSave={onSave ? () => onSave() : undefined}
+ permissions={permissions}
+ userInfo={userInfo}
+ onManagePermissions={onManagePermissions}
+ showPermissions={this.state.showPermissions}
+ onClosePermissions={() =>
+ this.setState({ showPermissions: false })
+ }
+ onClickPermissions={() => this.onClickPermissions()}
+ onSync={
+ callVCAction
+ ? () => this.sync(callVCAction, version)
+ : undefined
+ }
+ onOpenCommentCommitModal={onOpenCommentCommitModal}
+ onCommit={
+ callVCAction
+ ? comment =>
+ this.commit(
+ callVCAction,
+ version,
+ comment
+ )
+ : undefined
+ }
+ isFormDataValid={isFormDataValid}
+ itemPermissions={itemPermission}
+ isArchived={isArchived}
+ isReadOnlyMode={
+ isReadOnlyMode || candidateInProcess
+ }
+ isManual={isManual}
+ />
+ <div className="vc-separator" />
+ <NotificationsView />
+ {onClose && (
+ <div
+ className="vc-nav-item-close"
+ onClick={() => onClose()}
+ data-test-id="vc-cancel-btn">
+ {' '}
+ X
+ </div>
+ )}
+ </div>
+ </div>
+ </div>
+ );
+ }
+
+ onClickPermissions() {
+ let { onOpenPermissions, usersList } = this.props;
+ let { showPermissions } = this.state;
+ let promise = showPermissions
+ ? Promise.resolve()
+ : onOpenPermissions({ users: usersList });
+ promise.then(() =>
+ this.setState({ showPermissions: !showPermissions })
+ );
+ }
+
+ submit(callVCAction, version) {
+ const action = actionsEnum.SUBMIT;
+ callVCAction(action, version);
+ }
+
+ revert(callVCAction, version) {
+ const action = actionsEnum.REVERT;
+ callVCAction(action, version);
+ }
+
+ sync(callVCAction, version) {
+ const action = actionsEnum.SYNC;
+ callVCAction(action, version);
+ }
+
+ commit(callVCAction, version, comment) {
+ const action = actionsEnum.COMMIT;
+ callVCAction(action, version, comment);
+ }
+
+ permissions() {}
}
function VersionSelector(props) {
- let {version = {}, onMoreVersionsClick, viewableVersions = [], onVersionSwitching} = props;
- const includedVersions = viewableVersions.filter(ver => {return ver.id === version.id;});
- return (<div className='version-section-wrapper'>
- <select className='version-selector'
- onChange={ev => onVersionSwitching && onVersionSwitching(viewableVersions.find(version => version.id === ev.target.value))}
- value={version.id}
- data-test-id='vc-versions-select-box'>
- {viewableVersions && viewableVersions.map(viewVersion => {
- return (
- <option key={viewVersion.id} value={viewVersion.id} data-test-id='vc-version-option'>{`V ${viewVersion.name} ${viewVersion.status}`}</option>
- );
- })
- }
- {!includedVersions.length &&
- <option key={version.id} value={version.id} data-test-id='vc-selected-version-option'>{`V ${version.name} ${version.status}`}</option>}
- </select>
- <span onClick={onMoreVersionsClick} className='version-selector-more-versions' data-test-id='vc-versions-page-link'>{i18n('Versions Page')}</span>
- </div>);
+ let {
+ version = {},
+ onMoreVersionsClick,
+ viewableVersions = [],
+ onVersionSwitching
+ } = props;
+ const includedVersions = viewableVersions.filter(ver => {
+ return ver.id === version.id;
+ });
+ return (
+ <div className="version-section-wrapper">
+ <select
+ className="version-selector"
+ onChange={ev =>
+ onVersionSwitching &&
+ onVersionSwitching(
+ viewableVersions.find(
+ version => version.id === ev.target.value
+ )
+ )
+ }
+ value={version.id}
+ data-test-id="vc-versions-select-box">
+ {viewableVersions &&
+ viewableVersions.map(viewVersion => {
+ return (
+ <option
+ key={viewVersion.id}
+ value={viewVersion.id}
+ data-test-id="vc-version-option">{`V ${
+ viewVersion.name
+ } ${viewVersion.status}`}</option>
+ );
+ })}
+ {!includedVersions.length && (
+ <option
+ key={version.id}
+ value={version.id}
+ data-test-id="vc-selected-version-option">{`V ${
+ version.name
+ } ${version.status}`}</option>
+ )}
+ </select>
+ <span
+ onClick={onMoreVersionsClick}
+ className="version-selector-more-versions"
+ data-test-id="vc-versions-page-link">
+ {i18n('Versions Page')}
+ </span>
+ </div>
+ );
}
export default VersionController;
diff --git a/openecomp-ui/src/nfvo-components/panel/versionController/VersionControllerConstants.js b/openecomp-ui/src/nfvo-components/panel/versionController/VersionControllerConstants.js
index ddb428a1e9..54f10c1acf 100644
--- a/openecomp-ui/src/nfvo-components/panel/versionController/VersionControllerConstants.js
+++ b/openecomp-ui/src/nfvo-components/panel/versionController/VersionControllerConstants.js
@@ -16,9 +16,9 @@
import keyMirror from 'nfvo-utils/KeyMirror.js';
export const actionsEnum = keyMirror({
- REVERT: 'Revert',
- SYNC: 'Sync',
- SUBMIT: 'Submit',
- COMMIT: 'Commit',
- CREATE_PACKAGE: 'Create_Package'
+ REVERT: 'Revert',
+ SYNC: 'Sync',
+ SUBMIT: 'Submit',
+ COMMIT: 'Commit',
+ CREATE_PACKAGE: 'Create_Package'
});
diff --git a/openecomp-ui/src/nfvo-components/panel/versionController/components/ActionButtons.jsx b/openecomp-ui/src/nfvo-components/panel/versionController/components/ActionButtons.jsx
index b5750817ba..4dfa117803 100644
--- a/openecomp-ui/src/nfvo-components/panel/versionController/components/ActionButtons.jsx
+++ b/openecomp-ui/src/nfvo-components/panel/versionController/components/ActionButtons.jsx
@@ -13,7 +13,7 @@
* 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 enhanceWithClickOutside from 'react-click-outside';
import i18n from 'nfvo-utils/i18n/i18n.js';
@@ -22,88 +22,171 @@ import Overlay from 'nfvo-components/overlay/Overlay.jsx';
import Permissions from './Permissions.jsx';
class ClickOutsideWrapper extends Component {
- handleClickOutside() {
- this.props.onClose();
- }
- render() {
- return <div>{this.props.children}</div>;
- }
+ handleClickOutside() {
+ this.props.onClose();
+ }
+ render() {
+ return <div>{this.props.children}</div>;
+ }
}
-const EnhancedClickOutsideWrapper = enhanceWithClickOutside(ClickOutsideWrapper);
+const EnhancedClickOutsideWrapper = enhanceWithClickOutside(
+ ClickOutsideWrapper
+);
-const VCButton = ({name, tooltipText, disabled, onClick, dataTestId}) => {
- let onClickAction = disabled ? ()=>{} : onClick;
- return (
- <div className={`action-button-wrapper ${disabled ? 'disabled' : 'clickable'}`} onClick={onClickAction}>
- <div className='action-buttons-svg'>
- <SVGIcon label={tooltipText} labelPosition='bottom' labelClassName='action-button-label'
- data-test-id={dataTestId} name={name} disabled={disabled}/>
- </div>
- </div>
- );
+const VCButton = ({ name, tooltipText, disabled, onClick, dataTestId }) => {
+ let onClickAction = disabled ? () => {} : onClick;
+ return (
+ <div
+ className={`action-button-wrapper ${
+ disabled ? 'disabled' : 'clickable'
+ }`}
+ onClick={onClickAction}>
+ <div className="action-buttons-svg">
+ <SVGIcon
+ label={tooltipText}
+ labelPosition="bottom"
+ labelClassName="action-button-label"
+ data-test-id={dataTestId}
+ name={name}
+ disabled={disabled}
+ />
+ </div>
+ </div>
+ );
};
-const Separator = () => (<div className='vc-separator'></div>);
+const Separator = () => <div className="vc-separator" />;
-const SubmitButton = ({onClick, disabled}) => (
- <div onClick={()=>onClick()} data-test-id='vc-submit-btn' className={`vc-submit-button ${disabled ? 'disabled' : ''}`}>
- <SVGIcon name='check' iconClassName='vc-v-submit' disabled={disabled} />
- {i18n('Submit')}
- </div>
+const SubmitButton = ({ onClick, disabled }) => (
+ <div
+ onClick={() => onClick()}
+ data-test-id="vc-submit-btn"
+ className={`vc-submit-button ${disabled ? 'disabled' : ''}`}>
+ <SVGIcon name="check" iconClassName="vc-v-submit" disabled={disabled} />
+ {i18n('Submit')}
+ </div>
);
-
-const ActionButtons = ({isReadOnlyMode, onSubmit, onRevert, onSave, isFormDataValid, onClickPermissions, onSync, onCommit, isArchived,
- onOpenCommentCommitModal, showPermissions, onClosePermissions, permissions, onManagePermissions, userInfo, onOpenRevisionsModal, isManual,
- itemPermissions: {isCertified, isCollaborator, isDirty, isOutOfSync, isUpToDate}}) => (
- <div className='action-buttons'>
- <EnhancedClickOutsideWrapper onClose={onClosePermissions}>
- <VCButton disabled={isManual} dataTestId='vc-permission-btn' onClick={onClickPermissions}
- name='version-controller-permissions' tooltipText={i18n('Permissons')} />
- {showPermissions &&
- <Overlay>
- <Permissions userInfo={userInfo} onManagePermissions={onManagePermissions} permissions={permissions} onClosePermissions={onClosePermissions}/>
- </Overlay>
- }
- </EnhancedClickOutsideWrapper>
- {isCollaborator && !isArchived && <div className='collaborator-action-buttons'>
- <Separator />
- {onSave && <div className='vc-save-section'>
- <VCButton dataTestId='vc-save-btn' onClick={() => onSave()}
- name='version-controller-save' tooltipText={i18n('Save')} disabled={isReadOnlyMode || !isFormDataValid} />
- <Separator />
- </div>
- }
- <VCButton dataTestId='vc-sync-btn' onClick={onSync}
- name='version-controller-sync' tooltipText={i18n('Sync')} disabled={!isCollaborator || isUpToDate || isCertified} />
- <VCButton dataTestId='vc-commit-btn' onClick={() => onOpenCommentCommitModal({onCommit, title: i18n('Commit')})}
- name='version-controller-commit' tooltipText={i18n('Share')} disabled={isReadOnlyMode || !isDirty || isOutOfSync} />
- {onRevert &&
- <VCButton dataTestId='vc-revert-btn' onClick={onOpenRevisionsModal}
- name='version-controller-revert' tooltipText={i18n('Revert')} disabled={isReadOnlyMode || isOutOfSync} />
- }
- {onSubmit &&
- <div className='vc-submit-section'>
- <Separator />
- <SubmitButton onClick={onSubmit}
- disabled={isReadOnlyMode || isOutOfSync || !isUpToDate || isCertified} />
- </div>
- }
- </div>}
- </div>
+const ActionButtons = ({
+ isReadOnlyMode,
+ onSubmit,
+ onRevert,
+ onSave,
+ isFormDataValid,
+ onClickPermissions,
+ onSync,
+ onCommit,
+ isArchived,
+ onOpenCommentCommitModal,
+ showPermissions,
+ onClosePermissions,
+ permissions,
+ onManagePermissions,
+ userInfo,
+ onOpenRevisionsModal,
+ isManual,
+ itemPermissions: {
+ isCertified,
+ isCollaborator,
+ isDirty,
+ isOutOfSync,
+ isUpToDate
+ }
+}) => (
+ <div className="action-buttons">
+ <EnhancedClickOutsideWrapper onClose={onClosePermissions}>
+ <VCButton
+ disabled={isManual}
+ dataTestId="vc-permission-btn"
+ onClick={onClickPermissions}
+ name="version-controller-permissions"
+ tooltipText={i18n('Permissons')}
+ />
+ {showPermissions && (
+ <Overlay>
+ <Permissions
+ userInfo={userInfo}
+ onManagePermissions={onManagePermissions}
+ permissions={permissions}
+ onClosePermissions={onClosePermissions}
+ />
+ </Overlay>
+ )}
+ </EnhancedClickOutsideWrapper>
+ {isCollaborator &&
+ !isArchived && (
+ <div className="collaborator-action-buttons">
+ <Separator />
+ {onSave && (
+ <div className="vc-save-section">
+ <VCButton
+ dataTestId="vc-save-btn"
+ onClick={() => onSave()}
+ name="version-controller-save"
+ tooltipText={i18n('Save')}
+ disabled={isReadOnlyMode || !isFormDataValid}
+ />
+ <Separator />
+ </div>
+ )}
+ <VCButton
+ dataTestId="vc-sync-btn"
+ onClick={onSync}
+ name="version-controller-sync"
+ tooltipText={i18n('Sync')}
+ disabled={!isCollaborator || isUpToDate || isCertified}
+ />
+ <VCButton
+ dataTestId="vc-commit-btn"
+ onClick={() =>
+ onOpenCommentCommitModal({
+ onCommit,
+ title: i18n('Commit')
+ })
+ }
+ name="version-controller-commit"
+ tooltipText={i18n('Share')}
+ disabled={isReadOnlyMode || !isDirty || isOutOfSync}
+ />
+ {onRevert && (
+ <VCButton
+ dataTestId="vc-revert-btn"
+ onClick={onOpenRevisionsModal}
+ name="version-controller-revert"
+ tooltipText={i18n('Revert')}
+ disabled={isReadOnlyMode || isOutOfSync}
+ />
+ )}
+ {onSubmit && (
+ <div className="vc-submit-section">
+ <Separator />
+ <SubmitButton
+ onClick={onSubmit}
+ disabled={
+ isReadOnlyMode ||
+ isOutOfSync ||
+ !isUpToDate ||
+ isCertified
+ }
+ />
+ </div>
+ )}
+ </div>
+ )}
+ </div>
);
ActionButtons.propTypes = {
- version: PropTypes.object,
- onSubmit: PropTypes.func,
- onRevert: PropTypes.func,
- onSave: PropTypes.func,
- isLatestVersion: PropTypes.bool,
- isCheckedIn: PropTypes.bool,
- isCheckedOut: PropTypes.bool,
- isFormDataValid: PropTypes.bool,
- isReadOnlyMode: PropTypes.bool
+ version: PropTypes.object,
+ onSubmit: PropTypes.func,
+ onRevert: PropTypes.func,
+ onSave: PropTypes.func,
+ isLatestVersion: PropTypes.bool,
+ isCheckedIn: PropTypes.bool,
+ isCheckedOut: PropTypes.bool,
+ isFormDataValid: PropTypes.bool,
+ isReadOnlyMode: PropTypes.bool
};
export default ActionButtons;
diff --git a/openecomp-ui/src/nfvo-components/panel/versionController/components/CommitCommentModal.jsx b/openecomp-ui/src/nfvo-components/panel/versionController/components/CommitCommentModal.jsx
index 600eaeefaa..ae0913f3a9 100644
--- a/openecomp-ui/src/nfvo-components/panel/versionController/components/CommitCommentModal.jsx
+++ b/openecomp-ui/src/nfvo-components/panel/versionController/components/CommitCommentModal.jsx
@@ -15,59 +15,66 @@
*/
import React from 'react';
-import {connect} from 'react-redux';
+import { connect } from 'react-redux';
import i18n from 'nfvo-utils/i18n/i18n.js';
import Form from 'nfvo-components/input/validation/Form.jsx';
import Input from 'nfvo-components/input/validation/Input.jsx';
-import {actionTypes as modalActionTypes} from 'nfvo-components/modal/GlobalModalConstants.js';
+import { actionTypes as modalActionTypes } from 'nfvo-components/modal/GlobalModalConstants.js';
import keyMirror from 'nfvo-utils/KeyMirror.js';
export const CommitModalType = keyMirror({
- COMMIT: null,
- COMMIT_SUBMIT: null
-
+ COMMIT: null,
+ COMMIT_SUBMIT: null
});
-export const mapActionToProps = (dispatch) => {
- return {
- onClose: () => dispatch({
- type: modalActionTypes.GLOBAL_MODAL_CLOSE
- })
- };
+export const mapActionToProps = dispatch => {
+ return {
+ onClose: () =>
+ dispatch({
+ type: modalActionTypes.GLOBAL_MODAL_CLOSE
+ })
+ };
};
class CommitCommentModal extends React.Component {
+ state = {
+ comment: ''
+ };
- state = {
- comment: ''
- };
-
- render() {
- const {onCommit, onClose, type} = this.props;
- const [commitButtonText, descriptionText] = type === CommitModalType.COMMIT ?
- [i18n('Commit'), i18n('You are about to commit your version')] :
- [i18n('Commit & Submit'), i18n('You must commit your changes before the submit')];
+ render() {
+ const { onCommit, onClose, type } = this.props;
+ const [commitButtonText, descriptionText] =
+ type === CommitModalType.COMMIT
+ ? [i18n('Commit'), i18n('You are about to commit your version')]
+ : [
+ i18n('Commit & Submit'),
+ i18n('You must commit your changes before the submit')
+ ];
- return (
- <Form
- ref='validationForm'
- hasButtons={true}
- onSubmit={ () => {onCommit(this.state.comment); onClose();} }
- onReset={onClose}
- submitButtonText={commitButtonText}
- labledButtons={true}
- isValid={true}
- className='comment-commit-form'>
- <div className='commit-modal-text'>{descriptionText}</div>
- <Input
- data-test-id='commit-comment-text'
- onChange={comment => this.setState({comment: comment})}
- label={i18n('Enter Commit Comment:')}
- value={this.state.comment}
- type='textarea'/>
- </Form>
- );
- }
+ return (
+ <Form
+ ref="validationForm"
+ hasButtons={true}
+ onSubmit={() => {
+ onCommit(this.state.comment);
+ onClose();
+ }}
+ onReset={onClose}
+ submitButtonText={commitButtonText}
+ labledButtons={true}
+ isValid={true}
+ className="comment-commit-form">
+ <div className="commit-modal-text">{descriptionText}</div>
+ <Input
+ data-test-id="commit-comment-text"
+ onChange={comment => this.setState({ comment: comment })}
+ label={i18n('Enter Commit Comment:')}
+ value={this.state.comment}
+ type="textarea"
+ />
+ </Form>
+ );
+ }
}
export default connect(null, mapActionToProps)(CommitCommentModal);
diff --git a/openecomp-ui/src/nfvo-components/panel/versionController/components/Permissions.jsx b/openecomp-ui/src/nfvo-components/panel/versionController/components/Permissions.jsx
index 952bd4fb58..6e0ae8187b 100644
--- a/openecomp-ui/src/nfvo-components/panel/versionController/components/Permissions.jsx
+++ b/openecomp-ui/src/nfvo-components/panel/versionController/components/Permissions.jsx
@@ -18,48 +18,76 @@ import React from 'react';
import i18n from 'nfvo-utils/i18n/i18n.js';
import SVGIcon from 'sdc-ui/lib/react/SVGIcon.js';
-const Contributor = ({name, role, id, userInfo}) => {
+const Contributor = ({ name, role, id, userInfo }) => {
+ const selected = id === userInfo.userId ? 'selected' : '';
- const selected = id === userInfo.userId ? 'selected' : '';
-
- return(
- <div className='contributor'>
- <div className='contributor-content'>
- <div className={`contributor-icon-circle ${selected}`}>
- <div className={`contributer-icon ${selected}`}>
- <SVGIcon name='user'/>
- </div>
- </div>
- <div className='contributer-info'>
- <div className='contributer-name'>{name}</div>
- <div className='contributer-role'><p>{role}</p></div>
- </div>
- </div>
- </div>
- );
+ return (
+ <div className="contributor">
+ <div className="contributor-content">
+ <div className={`contributor-icon-circle ${selected}`}>
+ <div className={`contributer-icon ${selected}`}>
+ <SVGIcon name="user" />
+ </div>
+ </div>
+ <div className="contributer-info">
+ <div className="contributer-name">{name}</div>
+ <div className="contributer-role">
+ <p>{role}</p>
+ </div>
+ </div>
+ </div>
+ </div>
+ );
};
-const Permissions = ({permissions: {owner, contributors}, onManagePermissions, userInfo, onClosePermissions}) => {
-
- return (
- <div className='permissions-overlay'>
- <div className='permissions-overlay-header'>
- <h4 className='permissions-overlay-header-title'>{i18n('PERMISSIONS')}</h4>
- </div>
- <div className='permissions-overlay-content'>
- <Contributor userInfo={userInfo} id={owner.userId} key={owner.fullName} name={owner.fullName} role={owner.role}/>
- {contributors.map(item => item.userId !== owner.userId && <Contributor userInfo={userInfo} id={item.userId} key={item.fullName} name={item.fullName} role={item.role}/>)}
- </div>
- <div className='permissions-overlay-footer'>
- {
- owner.userId === userInfo.userId &&
- <div onClick={() => { onClosePermissions(); onManagePermissions(); }} className='manage-permissions-btn'>
- {i18n('Manage Permissions')}
- </div>
- }
- </div>
- </div>
- );
+const Permissions = ({
+ permissions: { owner, contributors },
+ onManagePermissions,
+ userInfo,
+ onClosePermissions
+}) => {
+ return (
+ <div className="permissions-overlay">
+ <div className="permissions-overlay-header">
+ <h4 className="permissions-overlay-header-title">
+ {i18n('PERMISSIONS')}
+ </h4>
+ </div>
+ <div className="permissions-overlay-content">
+ <Contributor
+ userInfo={userInfo}
+ id={owner.userId}
+ key={owner.fullName}
+ name={owner.fullName}
+ role={owner.role}
+ />
+ {contributors.map(
+ item =>
+ item.userId !== owner.userId && (
+ <Contributor
+ userInfo={userInfo}
+ id={item.userId}
+ key={item.fullName}
+ name={item.fullName}
+ role={item.role}
+ />
+ )
+ )}
+ </div>
+ <div className="permissions-overlay-footer">
+ {owner.userId === userInfo.userId && (
+ <div
+ onClick={() => {
+ onClosePermissions();
+ onManagePermissions();
+ }}
+ className="manage-permissions-btn">
+ {i18n('Manage Permissions')}
+ </div>
+ )}
+ </div>
+ </div>
+ );
};
export default Permissions;
diff --git a/openecomp-ui/src/nfvo-components/progressBar/ProgressBar.jsx b/openecomp-ui/src/nfvo-components/progressBar/ProgressBar.jsx
index ca5cb3d765..cb10bb565e 100644
--- a/openecomp-ui/src/nfvo-components/progressBar/ProgressBar.jsx
+++ b/openecomp-ui/src/nfvo-components/progressBar/ProgressBar.jsx
@@ -17,22 +17,25 @@ import React from 'react';
import PropTypes from 'prop-types';
class ProgressBar extends React.Component {
- static propTypes = {
- label: PropTypes.string,
- now: PropTypes.string.isRequired
- }
- render() {
- let {label, now} = this.props;
+ static propTypes = {
+ label: PropTypes.string,
+ now: PropTypes.string.isRequired
+ };
+ render() {
+ let { label, now } = this.props;
- return(
- <div className='progress-bar-view'>
- <div className='progress-bar-outside'>
- <div style={{width: now + '%'}} className='progress-bar-inside'></div>
- </div>
- <div className='progress-bar-view-label'>{label}</div>
- </div>
- );
- }
+ return (
+ <div className="progress-bar-view">
+ <div className="progress-bar-outside">
+ <div
+ style={{ width: now + '%' }}
+ className="progress-bar-inside"
+ />
+ </div>
+ <div className="progress-bar-view-label">{label}</div>
+ </div>
+ );
+ }
}
export default ProgressBar;
diff --git a/openecomp-ui/src/nfvo-components/table/SelectActionTable.jsx b/openecomp-ui/src/nfvo-components/table/SelectActionTable.jsx
index 3f8dbba53a..ee8a9dca45 100644
--- a/openecomp-ui/src/nfvo-components/table/SelectActionTable.jsx
+++ b/openecomp-ui/src/nfvo-components/table/SelectActionTable.jsx
@@ -5,26 +5,57 @@ import Button from 'sdc-ui/lib/react/Button.js';
import uuid from 'uuid-js';
export default class SelectActionTable extends React.Component {
-
- render() {
- let {columns, onAdd, isReadOnlyMode, children, onAddItem, numOfIcons} = this.props;
- return (
- <div className={`select-action-table-view ${isReadOnlyMode ? 'disabled' : ''}`}>
- <div className='select-action-table-controllers'>
- {onAdd && onAddItem &&
- <Button btnType='link' disabled={isReadOnlyMode === true} color='primary' iconName='plus' data-test-id='select-action-table-add' onClick={onAdd}>{onAddItem}</Button>}
- <SVGIcon name='trashO' className='dummy-icon' />
- </div>
- <div className='select-action-table'>
- <div className='select-action-table-headers'>
- {columns.map(column => <div key={uuid.create()} className='select-action-table-header'>{i18n(column)}</div>)}
- {Array(numOfIcons).fill().map((e, i) => <SVGIcon name='trash-o' key={i} className='dummy-icon' />)}
- </div>
- <div className='select-action-table-body'>
- {children}
- </div>
- </div>
- </div>
- );
- }
+ render() {
+ let {
+ columns,
+ onAdd,
+ isReadOnlyMode,
+ children,
+ onAddItem,
+ numOfIcons
+ } = this.props;
+ return (
+ <div
+ className={`select-action-table-view ${
+ isReadOnlyMode ? 'disabled' : ''
+ }`}>
+ <div className="select-action-table-controllers">
+ {onAdd &&
+ onAddItem && (
+ <Button
+ btnType="link"
+ disabled={isReadOnlyMode === true}
+ color="primary"
+ iconName="plus"
+ data-test-id="select-action-table-add"
+ onClick={onAdd}>
+ {onAddItem}
+ </Button>
+ )}
+ <SVGIcon name="trashO" className="dummy-icon" />
+ </div>
+ <div className="select-action-table">
+ <div className="select-action-table-headers">
+ {columns.map(column => (
+ <div
+ key={uuid.create()}
+ className="select-action-table-header">
+ {i18n(column)}
+ </div>
+ ))}
+ {Array(numOfIcons)
+ .fill()
+ .map((e, i) => (
+ <SVGIcon
+ name="trash-o"
+ key={i}
+ className="dummy-icon"
+ />
+ ))}
+ </div>
+ <div className="select-action-table-body">{children}</div>
+ </div>
+ </div>
+ );
+ }
}
diff --git a/openecomp-ui/src/nfvo-components/table/SelectActionTableCell.jsx b/openecomp-ui/src/nfvo-components/table/SelectActionTableCell.jsx
index 2664c8e944..20e4f2413c 100644
--- a/openecomp-ui/src/nfvo-components/table/SelectActionTableCell.jsx
+++ b/openecomp-ui/src/nfvo-components/table/SelectActionTableCell.jsx
@@ -1,20 +1,28 @@
import React from 'react';
import SelectInput from 'nfvo-components/input/SelectInput.jsx';
-const SelectActionTableCell = ({options, selected, disabled, onChange, clearable = true, placeholder}) => {
- return (
- <div className='select-action-table-cell'>
- <SelectInput
- placeholder={placeholder}
- type='select'
- value={selected}
- data-test-id='select-action-table-dropdown'
- disabled={disabled}
- onChange={option => onChange(option ? option.value : null)}
- clearable={clearable}
- options={options} />
- </div>
- );
+const SelectActionTableCell = ({
+ options,
+ selected,
+ disabled,
+ onChange,
+ clearable = true,
+ placeholder
+}) => {
+ return (
+ <div className="select-action-table-cell">
+ <SelectInput
+ placeholder={placeholder}
+ type="select"
+ value={selected}
+ data-test-id="select-action-table-dropdown"
+ disabled={disabled}
+ onChange={option => onChange(option ? option.value : null)}
+ clearable={clearable}
+ options={options}
+ />
+ </div>
+ );
};
export default SelectActionTableCell;
diff --git a/openecomp-ui/src/nfvo-components/table/SelectActionTableRow.jsx b/openecomp-ui/src/nfvo-components/table/SelectActionTableRow.jsx
index 260d39d31c..1c2c1529f2 100644
--- a/openecomp-ui/src/nfvo-components/table/SelectActionTableRow.jsx
+++ b/openecomp-ui/src/nfvo-components/table/SelectActionTableRow.jsx
@@ -3,38 +3,65 @@ import SVGIcon from 'sdc-ui/lib/react/SVGIcon.js';
import OverlayTrigger from 'react-bootstrap/lib/OverlayTrigger.js';
import Tooltip from 'react-bootstrap/lib/Tooltip.js';
-function tooltip (msg) {
- return (
- <Tooltip className='select-action-table-error-tooltip' id='error-tooltip'>{msg}</Tooltip>
- );
-};
+function tooltip(msg) {
+ return (
+ <Tooltip
+ className="select-action-table-error-tooltip"
+ id="error-tooltip">
+ {msg}
+ </Tooltip>
+ );
+}
-const IconWithOverlay = ({overlayMsg}) => (
- <OverlayTrigger placement='bottom' overlay={tooltip(overlayMsg)}>
- <SVGIcon name='errorCircle' color='negative'/>
- </OverlayTrigger>
+const IconWithOverlay = ({ overlayMsg }) => (
+ <OverlayTrigger placement="bottom" overlay={tooltip(overlayMsg)}>
+ <SVGIcon name="errorCircle" color="negative" />
+ </OverlayTrigger>
);
-function renderErrorOrCheck({hasError, overlayMsg}) {
- if (hasError === undefined) {
- return <SVGIcon name='angleRight' className='dummy-icon' />;
- }
+function renderErrorOrCheck({ hasError, overlayMsg }) {
+ if (hasError === undefined) {
+ return <SVGIcon name="angleRight" className="dummy-icon" />;
+ }
- if (hasError) {
- return overlayMsg ? <IconWithOverlay overlayMsg={overlayMsg}/> : <SVGIcon color='negative' name='errorCircle'/>;
- }
+ if (hasError) {
+ return overlayMsg ? (
+ <IconWithOverlay overlayMsg={overlayMsg} />
+ ) : (
+ <SVGIcon color="negative" name="errorCircle" />
+ );
+ }
- return <SVGIcon name='checkCircle' color='positive'/>;
+ return <SVGIcon name="checkCircle" color="positive" />;
}
-const SelectActionTableRow = ({children, actionIcon, onAction, showAction, hasError, hasErrorIndication, overlayMsg}) => (
- <div className='select-action-table-row-wrapper'>
- <div className={`select-action-table-row ${hasError ? 'has-error' : ''}`}>
- {children}
- </div>
- {onAction && <SVGIcon color='secondary' name={actionIcon} data-test-id={`select-action-table-${actionIcon}`} onClick={onAction} iconClassName={(showAction) ? '' : 'hideDelete'}/>}
- {hasErrorIndication && renderErrorOrCheck({hasError, overlayMsg})}
- </div>
+const SelectActionTableRow = ({
+ children,
+ actionIcon,
+ onAction,
+ showAction,
+ hasError,
+ hasErrorIndication,
+ overlayMsg
+}) => (
+ <div className="select-action-table-row-wrapper">
+ <div
+ className={`select-action-table-row ${
+ hasError ? 'has-error' : ''
+ }`}>
+ {children}
+ </div>
+ {onAction && (
+ <SVGIcon
+ color="secondary"
+ name={actionIcon}
+ data-test-id={`select-action-table-${actionIcon}`}
+ onClick={onAction}
+ iconClassName={showAction ? '' : 'hideDelete'}
+ />
+ )}
+ {hasErrorIndication && renderErrorOrCheck({ hasError, overlayMsg })}
+ </div>
);
export default SelectActionTableRow;
diff --git a/openecomp-ui/src/nfvo-components/tree/Tree.jsx b/openecomp-ui/src/nfvo-components/tree/Tree.jsx
index 682f3b6d50..39434fcdf1 100644
--- a/openecomp-ui/src/nfvo-components/tree/Tree.jsx
+++ b/openecomp-ui/src/nfvo-components/tree/Tree.jsx
@@ -1,16 +1,28 @@
-import React, {Component} from 'react';
+import React, { Component } from 'react';
import PropTypes from 'prop-types';
-import {select} from 'd3-selection';
-import {tree, stratify} from 'd3-hierarchy';
-
+import { select } from 'd3-selection';
+import { tree, stratify } from 'd3-hierarchy';
function diagonal(d) {
-
- const offset = 50;
- return 'M' + d.y + ',' + d.x
- + 'C' + (d.parent.y + offset) + ',' + d.x
- + ' ' + (d.parent.y + offset) + ',' + d.parent.x
- + ' ' + d.parent.y + ',' + d.parent.x;
+ const offset = 50;
+ return (
+ 'M' +
+ d.y +
+ ',' +
+ d.x +
+ 'C' +
+ (d.parent.y + offset) +
+ ',' +
+ d.x +
+ ' ' +
+ (d.parent.y + offset) +
+ ',' +
+ d.parent.x +
+ ' ' +
+ d.parent.y +
+ ',' +
+ d.parent.x
+ );
}
const nodeRadius = 8;
@@ -18,164 +30,226 @@ const verticalSpaceBetweenNodes = 70;
const NARROW_HORIZONTAL_SPACES = 47;
const WIDE_HORIZONTAL_SPACES = 65;
-const stratifyFn = stratify().id(d => d.id).parentId(d => d.parent);
+const stratifyFn = stratify()
+ .id(d => d.id)
+ .parentId(d => d.parent);
class Tree extends Component {
-
- // state = {
- // startingCoordinates: null,
- // isDown: false
- // }
-
- static propTypes = {
- name: PropTypes.string,
- width: PropTypes.number,
- allowScaleWidth: PropTypes.bool,
- nodes: PropTypes.arrayOf(PropTypes.shape({
- id: PropTypes.string,
- name: PropTypes.string,
- parent: PropTypes.string
- })),
- selectedNodeId: PropTypes.string,
- onNodeClick: PropTypes.func,
- onRenderedBeyondWidth: PropTypes.func
- };
-
- static defaultProps = {
- width: 500,
- allowScaleWidth : true,
- name: 'default-name'
- };
-
- render() {
- let {width, name, scrollable = false} = this.props;
- return (
- <div
- className={`tree-view ${name}-container ${scrollable ? 'scrollable' : ''}`}>
- <svg width={width} className={name}></svg>
- </div>
- );
- }
-
- componentDidMount() {
- this.renderTree();
- }
-
- // handleMouseMove(e) {
- // if (!this.state.isDown) {
- // return;
- // }
- // const container = select(`.tree-view.${this.props.name}-container`);
- // let coordinates = this.getCoordinates(e);
- // container.property('scrollLeft' , container.property('scrollLeft') + coordinates.x - this.state.startingCoordinates.x);
- // container.property('scrollTop' , container.property('scrollTop') + coordinates.y - this.state.startingCoordinates.y);
- // }
-
- // handleMouseDown(e) {
- // let startingCoordinates = this.getCoordinates(e);
- // this.setState({
- // startingCoordinates,
- // isDown: true
- // });
- // }
-
- // handleMouseUp() {
- // this.setState({
- // startingCorrdinates: null,
- // isDown: false
- // });
- // }
-
- // getCoordinates(e) {
- // var bounds = e.target.getBoundingClientRect();
- // var x = e.clientX - bounds.left;
- // var y = e.clientY - bounds.top;
- // return {x, y};
- // }
-
- componentDidUpdate(prevProps) {
- if (this.props.nodes.length !== prevProps.nodes.length ||
- this.props.selectedNodeId !== prevProps.selectedNodeId) {
- console.log('update');
- this.renderTree();
- }
- }
-
- renderTree() {
- let {width, nodes, name, allowScaleWidth, selectedNodeId, onRenderedBeyondWidth, toWiden} = this.props;
- if (nodes.length > 0) {
-
- let horizontalSpaceBetweenLeaves = toWiden ? WIDE_HORIZONTAL_SPACES : NARROW_HORIZONTAL_SPACES;
- const treeFn = tree().nodeSize([horizontalSpaceBetweenLeaves, verticalSpaceBetweenNodes]);//.size([width - 50, height - 50])
- let root = stratifyFn(nodes).sort((a, b) => a.data.name.localeCompare(b.data.name));
- let svgHeight = verticalSpaceBetweenNodes * root.height + nodeRadius * 6;
-
- treeFn(root);
-
- let nodesXValue = root.descendants().map(node => node.x);
- let maxX = Math.max(...nodesXValue);
- let minX = Math.min(...nodesXValue);
-
- let svgTempWidth = (maxX - minX) / 30 * (horizontalSpaceBetweenLeaves);
- let svgWidth = svgTempWidth < width ? (width - 5) : svgTempWidth;
- const svgEL = select(`svg.${name}`);
- const container = select(`.tree-view.${name}-container`);
- svgEL.html('');
- svgEL.attr('height', svgHeight);
- let canvasWidth = width;
- if (svgTempWidth > width) {
- if (allowScaleWidth) {
- canvasWidth = svgTempWidth;
- }
- // we seems to have a margin of 25px that we can still see with text
- if (((svgTempWidth - 25) > width) && onRenderedBeyondWidth !== undefined) {
- onRenderedBeyondWidth();
- }
- };
- svgEL.attr('width', canvasWidth);
- let rootGroup = svgEL.append('g').attr('transform', `translate(${svgWidth / 2 + nodeRadius},${nodeRadius * 4}) rotate(90)`);
-
- // handle link
- rootGroup.selectAll('.link')
- .data(root.descendants().slice(1))
- .enter().append('path')
- .attr('class', 'link')
- .attr('d', diagonal);
-
- let node = rootGroup.selectAll('.node')
- .data(root.descendants())
- .enter().append('g')
- .attr('class', node => `node ${node.children ? ' has-children' : ' leaf'} ${node.id === selectedNodeId ? 'selectedNode' : ''} ${this.props.onNodeClick ? 'clickable' : ''}`)
- .attr('transform', node => 'translate(' + node.y + ',' + node.x + ')')
- .on('click', node => this.onNodeClick(node));
-
- node.append('circle').attr('r', nodeRadius).attr('class', 'outer-circle');
- node.append('circle').attr('r', nodeRadius - 3).attr('class', 'inner-circle');
-
- node.append('text')
- .attr('y', nodeRadius / 4 + 1)
- .attr('x', - nodeRadius * 1.8)
- .text(node => node.data.name)
- .attr('transform', 'rotate(-90)');
-
- let selectedNode = selectedNodeId ? root.descendants().find(node => node.id === selectedNodeId) : null;
- if (selectedNode) {
-
- container.property('scrollLeft', (svgWidth / 4) + (svgWidth / 4 - 100) - (selectedNode.x / 30 * horizontalSpaceBetweenLeaves));
- container.property('scrollTop', (selectedNode.y / 100 * verticalSpaceBetweenNodes));
-
- } else {
- container.property('scrollLeft', (svgWidth / 4) + (svgWidth / 4 - 100));
- }
- }
- }
-
- onNodeClick(node) {
- if (this.props.onNodeClick) {
- this.props.onNodeClick(node.data);
- }
- }
-
+ // state = {
+ // startingCoordinates: null,
+ // isDown: false
+ // }
+
+ static propTypes = {
+ name: PropTypes.string,
+ width: PropTypes.number,
+ allowScaleWidth: PropTypes.bool,
+ nodes: PropTypes.arrayOf(
+ PropTypes.shape({
+ id: PropTypes.string,
+ name: PropTypes.string,
+ parent: PropTypes.string
+ })
+ ),
+ selectedNodeId: PropTypes.string,
+ onNodeClick: PropTypes.func,
+ onRenderedBeyondWidth: PropTypes.func
+ };
+
+ static defaultProps = {
+ width: 500,
+ allowScaleWidth: true,
+ name: 'default-name'
+ };
+
+ render() {
+ let { width, name, scrollable = false } = this.props;
+ return (
+ <div
+ className={`tree-view ${name}-container ${
+ scrollable ? 'scrollable' : ''
+ }`}>
+ <svg width={width} className={name} />
+ </div>
+ );
+ }
+
+ componentDidMount() {
+ this.renderTree();
+ }
+
+ // handleMouseMove(e) {
+ // if (!this.state.isDown) {
+ // return;
+ // }
+ // const container = select(`.tree-view.${this.props.name}-container`);
+ // let coordinates = this.getCoordinates(e);
+ // container.property('scrollLeft' , container.property('scrollLeft') + coordinates.x - this.state.startingCoordinates.x);
+ // container.property('scrollTop' , container.property('scrollTop') + coordinates.y - this.state.startingCoordinates.y);
+ // }
+
+ // handleMouseDown(e) {
+ // let startingCoordinates = this.getCoordinates(e);
+ // this.setState({
+ // startingCoordinates,
+ // isDown: true
+ // });
+ // }
+
+ // handleMouseUp() {
+ // this.setState({
+ // startingCorrdinates: null,
+ // isDown: false
+ // });
+ // }
+
+ // getCoordinates(e) {
+ // var bounds = e.target.getBoundingClientRect();
+ // var x = e.clientX - bounds.left;
+ // var y = e.clientY - bounds.top;
+ // return {x, y};
+ // }
+
+ componentDidUpdate(prevProps) {
+ if (
+ this.props.nodes.length !== prevProps.nodes.length ||
+ this.props.selectedNodeId !== prevProps.selectedNodeId
+ ) {
+ console.log('update');
+ this.renderTree();
+ }
+ }
+
+ renderTree() {
+ let {
+ width,
+ nodes,
+ name,
+ allowScaleWidth,
+ selectedNodeId,
+ onRenderedBeyondWidth,
+ toWiden
+ } = this.props;
+ if (nodes.length > 0) {
+ let horizontalSpaceBetweenLeaves = toWiden
+ ? WIDE_HORIZONTAL_SPACES
+ : NARROW_HORIZONTAL_SPACES;
+ const treeFn = tree().nodeSize([
+ horizontalSpaceBetweenLeaves,
+ verticalSpaceBetweenNodes
+ ]); //.size([width - 50, height - 50])
+ let root = stratifyFn(nodes).sort((a, b) =>
+ a.data.name.localeCompare(b.data.name)
+ );
+ let svgHeight =
+ verticalSpaceBetweenNodes * root.height + nodeRadius * 6;
+
+ treeFn(root);
+
+ let nodesXValue = root.descendants().map(node => node.x);
+ let maxX = Math.max(...nodesXValue);
+ let minX = Math.min(...nodesXValue);
+
+ let svgTempWidth =
+ (maxX - minX) / 30 * horizontalSpaceBetweenLeaves;
+ let svgWidth = svgTempWidth < width ? width - 5 : svgTempWidth;
+ const svgEL = select(`svg.${name}`);
+ const container = select(`.tree-view.${name}-container`);
+ svgEL.html('');
+ svgEL.attr('height', svgHeight);
+ let canvasWidth = width;
+ if (svgTempWidth > width) {
+ if (allowScaleWidth) {
+ canvasWidth = svgTempWidth;
+ }
+ // we seems to have a margin of 25px that we can still see with text
+ if (
+ svgTempWidth - 25 > width &&
+ onRenderedBeyondWidth !== undefined
+ ) {
+ onRenderedBeyondWidth();
+ }
+ }
+ svgEL.attr('width', canvasWidth);
+ let rootGroup = svgEL
+ .append('g')
+ .attr(
+ 'transform',
+ `translate(${svgWidth / 2 + nodeRadius},${nodeRadius *
+ 4}) rotate(90)`
+ );
+
+ // handle link
+ rootGroup
+ .selectAll('.link')
+ .data(root.descendants().slice(1))
+ .enter()
+ .append('path')
+ .attr('class', 'link')
+ .attr('d', diagonal);
+
+ let node = rootGroup
+ .selectAll('.node')
+ .data(root.descendants())
+ .enter()
+ .append('g')
+ .attr(
+ 'class',
+ node =>
+ `node ${node.children ? ' has-children' : ' leaf'} ${
+ node.id === selectedNodeId ? 'selectedNode' : ''
+ } ${this.props.onNodeClick ? 'clickable' : ''}`
+ )
+ .attr(
+ 'transform',
+ node => 'translate(' + node.y + ',' + node.x + ')'
+ )
+ .on('click', node => this.onNodeClick(node));
+
+ node
+ .append('circle')
+ .attr('r', nodeRadius)
+ .attr('class', 'outer-circle');
+ node
+ .append('circle')
+ .attr('r', nodeRadius - 3)
+ .attr('class', 'inner-circle');
+
+ node
+ .append('text')
+ .attr('y', nodeRadius / 4 + 1)
+ .attr('x', -nodeRadius * 1.8)
+ .text(node => node.data.name)
+ .attr('transform', 'rotate(-90)');
+
+ let selectedNode = selectedNodeId
+ ? root.descendants().find(node => node.id === selectedNodeId)
+ : null;
+ if (selectedNode) {
+ container.property(
+ 'scrollLeft',
+ svgWidth / 4 +
+ (svgWidth / 4 - 100) -
+ selectedNode.x / 30 * horizontalSpaceBetweenLeaves
+ );
+ container.property(
+ 'scrollTop',
+ selectedNode.y / 100 * verticalSpaceBetweenNodes
+ );
+ } else {
+ container.property(
+ 'scrollLeft',
+ svgWidth / 4 + (svgWidth / 4 - 100)
+ );
+ }
+ }
+ }
+
+ onNodeClick(node) {
+ if (this.props.onNodeClick) {
+ this.props.onNodeClick(node.data);
+ }
+ }
}
export default Tree;
diff --git a/openecomp-ui/src/nfvo-components/tree/Tree.stories.js b/openecomp-ui/src/nfvo-components/tree/Tree.stories.js
index b29920b3ec..aca1a13402 100644
--- a/openecomp-ui/src/nfvo-components/tree/Tree.stories.js
+++ b/openecomp-ui/src/nfvo-components/tree/Tree.stories.js
@@ -1,119 +1,141 @@
import React from 'react';
-import {storiesOf} from '@kadira/storybook';
-import {withKnobs} from '@kadira/storybook-addon-knobs';
+import { storiesOf } from '@kadira/storybook';
+import { withKnobs } from '@kadira/storybook-addon-knobs';
import Tree from './Tree.jsx';
-import SVGIcon from 'sdc-ui/lib/react/SVGIcon.js';
const stories = storiesOf('Version Tree', module);
stories.addDecorator(withKnobs);
const response = {
- listCount: 6,
- results: [
- {
- 'id': '123',
- 'name': '1.0',
- 'description': 'string',
- 'baseId': '',
- 'status': 'Draft',
- 'creationTime': '2017-06-08T08:55:37.831Z',
- 'modificationTime': '2017-06-08T08:55:37.831Z'
- },
- {
- 'id': '1234',
- 'name': '1.1',
- 'description': 'string',
- 'baseId': '123',
- 'status': 'Draft',
- 'creationTime': '2017-06-08T08:55:37.831Z',
- 'modificationTime': '2017-06-08T08:55:37.831Z'
- },
- {
- 'id': '12345',
- 'name': '2.0',
- 'description': 'string',
- 'baseId': '123',
- 'status': 'Draft',
- 'creationTime': '2017-06-08T08:55:37.831Z',
- 'modificationTime': '2017-06-08T08:55:37.831Z'
- },
- {
- 'id': '123456',
- 'name': '3.0',
- 'description': 'string',
- 'baseId': '12345',
- 'status': 'Draft',
- 'creationTime': '2017-06-08T08:55:37.831Z',
- 'modificationTime': '2017-06-08T08:55:37.831Z'
- },
- {
- 'id': '1234567',
- 'name': '1.2',
- 'description': 'string',
- 'baseId': '1234',
- 'status': 'Draft',
- 'creationTime': '2017-06-08T08:55:37.831Z',
- 'modificationTime': '2017-06-08T08:55:37.831Z'
- },
- {
- 'id': '12345678',
- 'name': '2.1',
- 'description': 'string',
- 'baseId': '12345',
- 'status': 'Draft',
- 'creationTime': '2017-06-08T08:55:37.831Z',
- 'modificationTime': '2017-06-08T08:55:37.831Z'
- },
- {
- 'id': '123456789',
- 'name': '4.0',
- 'description': 'string',
- 'baseId': '123456',
- 'status': 'Draft',
- 'creationTime': '2017-06-08T08:55:37.831Z',
- 'modificationTime': '2017-06-08T08:55:37.831Z'
- },
- {
- 'id': '12345678910',
- 'name': '3.1',
- 'description': 'string',
- 'baseId': '123456',
- 'status': 'Draft',
- 'creationTime': '2017-06-08T08:55:37.831Z',
- 'modificationTime': '2017-06-08T08:55:37.831Z'
- }
- ]
+ listCount: 6,
+ results: [
+ {
+ id: '123',
+ name: '1.0',
+ description: 'string',
+ baseId: '',
+ status: 'Draft',
+ creationTime: '2017-06-08T08:55:37.831Z',
+ modificationTime: '2017-06-08T08:55:37.831Z'
+ },
+ {
+ id: '1234',
+ name: '1.1',
+ description: 'string',
+ baseId: '123',
+ status: 'Draft',
+ creationTime: '2017-06-08T08:55:37.831Z',
+ modificationTime: '2017-06-08T08:55:37.831Z'
+ },
+ {
+ id: '12345',
+ name: '2.0',
+ description: 'string',
+ baseId: '123',
+ status: 'Draft',
+ creationTime: '2017-06-08T08:55:37.831Z',
+ modificationTime: '2017-06-08T08:55:37.831Z'
+ },
+ {
+ id: '123456',
+ name: '3.0',
+ description: 'string',
+ baseId: '12345',
+ status: 'Draft',
+ creationTime: '2017-06-08T08:55:37.831Z',
+ modificationTime: '2017-06-08T08:55:37.831Z'
+ },
+ {
+ id: '1234567',
+ name: '1.2',
+ description: 'string',
+ baseId: '1234',
+ status: 'Draft',
+ creationTime: '2017-06-08T08:55:37.831Z',
+ modificationTime: '2017-06-08T08:55:37.831Z'
+ },
+ {
+ id: '12345678',
+ name: '2.1',
+ description: 'string',
+ baseId: '12345',
+ status: 'Draft',
+ creationTime: '2017-06-08T08:55:37.831Z',
+ modificationTime: '2017-06-08T08:55:37.831Z'
+ },
+ {
+ id: '123456789',
+ name: '4.0',
+ description: 'string',
+ baseId: '123456',
+ status: 'Draft',
+ creationTime: '2017-06-08T08:55:37.831Z',
+ modificationTime: '2017-06-08T08:55:37.831Z'
+ },
+ {
+ id: '12345678910',
+ name: '3.1',
+ description: 'string',
+ baseId: '123456',
+ status: 'Draft',
+ creationTime: '2017-06-08T08:55:37.831Z',
+ modificationTime: '2017-06-08T08:55:37.831Z'
+ }
+ ]
};
-const divStyle = { width: '200px', borderStyle: 'solid', borderColor: 'black', border: '1px solid black'};
-const tree = response.results.map(item => ({id: item.id, name: item.name, parent: item.baseId}));
-const nodeClickHandler = function (node) {
- window.alert(node.name);
+const divStyle = {
+ width: '200px',
+ borderStyle: 'solid',
+ borderColor: 'black',
+ border: '1px solid black'
};
-stories.add('Classic Version Tree', () => (
- <div>
- <Tree nodes={tree} onNodeClick={nodeClickHandler} selectedNodeId={'1234'}/>
- </div>
-)).add('Single Version Tree', () => (
- <div>
- <Tree nodes={[tree[0]]} onNodeClick={nodeClickHandler}/>
- </div>
-)).add('Single Path Version Tree', () => (
- <div>
- <Tree nodes={[tree[0], tree[1]]} onNodeClick={nodeClickHandler}/>
- </div>
-)).add('Empty Tree', () => (
- <div>
- <Tree nodes={[]}/>
- </div>
-)).add('Add Tree in Version Page Frame', () => (
- <div style={divStyle}>
- Tree wider than frame<br/><br/><br/>
- <Tree
- name={'versions-tree'}
- width={200}
- nodes={tree}
- onRenderedBeyondWidth={() => {console.log('rendered beyond width')}}
- allowScaleWidth={false}
- onNodeClick={nodeClickHandler}/>
- </div>
-));
+const tree = response.results.map(item => ({
+ id: item.id,
+ name: item.name,
+ parent: item.baseId
+}));
+const nodeClickHandler = function(node) {
+ window.alert(node.name);
+};
+stories
+ .add('Classic Version Tree', () => (
+ <div>
+ <Tree
+ nodes={tree}
+ onNodeClick={nodeClickHandler}
+ selectedNodeId={'1234'}
+ />
+ </div>
+ ))
+ .add('Single Version Tree', () => (
+ <div>
+ <Tree nodes={[tree[0]]} onNodeClick={nodeClickHandler} />
+ </div>
+ ))
+ .add('Single Path Version Tree', () => (
+ <div>
+ <Tree nodes={[tree[0], tree[1]]} onNodeClick={nodeClickHandler} />
+ </div>
+ ))
+ .add('Empty Tree', () => (
+ <div>
+ <Tree nodes={[]} />
+ </div>
+ ))
+ .add('Add Tree in Version Page Frame', () => (
+ <div style={divStyle}>
+ Tree wider than frame<br />
+ <br />
+ <br />
+ <Tree
+ name={'versions-tree'}
+ width={200}
+ nodes={tree}
+ onRenderedBeyondWidth={() => {
+ console.log('rendered beyond width');
+ }}
+ allowScaleWidth={false}
+ onNodeClick={nodeClickHandler}
+ />
+ </div>
+ ));