diff options
author | Shawn Severin <shawn.severin@amdocs.com> | 2017-12-20 16:27:35 -0500 |
---|---|---|
committer | Shawn Severin <shawn.severin@amdocs.com> | 2017-12-21 15:29:08 -0500 |
commit | bca1bdc7d52b01ede5c0e85f06cd6c64e5aaab57 (patch) | |
tree | 846b787ece0982ebc2419e4600e6ecd3329a625a /src/generic-components/input/validation | |
parent | d4fd54113808e9efa637719719b2831e0597996e (diff) |
Updating versions of Sparky FE files
Updating versions of Sparky FE files as previous ones were out-dated
Issue-ID: AAI-543
Change-Id: Idc7d09e0efabaa5ef82db126cf7563fc8370f4f9
Signed-off-by: Shawn Severin <shawn.severin@amdocs.com>
Diffstat (limited to 'src/generic-components/input/validation')
5 files changed, 0 insertions, 830 deletions
diff --git a/src/generic-components/input/validation/ValidationButtons.jsx b/src/generic-components/input/validation/ValidationButtons.jsx deleted file mode 100644 index 1568a57..0000000 --- a/src/generic-components/input/validation/ValidationButtons.jsx +++ /dev/null @@ -1,66 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * Copyright © 2017 Amdocs - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - * - * ECOMP is a trademark and service mark of AT&T Intellectual Property. - */ -/** - * Holds the buttons for save/reset for forms. - * Used by the ValidationForm that changes the state of the buttons according - * to its own state. - * - * properties: - * labledButtons - whether or not to use labeled buttons or icons only - */ -import React from 'react'; -import i18n from 'utils/i18n/i18n.js'; -import Button from 'react-bootstrap/lib/Button.js'; -import FontAwesome from 'react-fontawesome'; - -class ValidationButtons extends React.Component { - - static propTypes = { - labledButtons: React.PropTypes.bool.isRequired, - isReadOnlyMode: React.PropTypes.bool - }; - - state = { - isValid: this.props.formValid - }; - - render() { - var submitBtn = this.props.labledButtons ? i18n('Save') : - <FontAwesome className='check' name='check'/>; - var closeBtn = this.props.labledButtons ? i18n('Cancel') : - <FontAwesome className='close' name='close'/>; - return ( - <div className='validation-buttons'> - {!this.props.isReadOnlyMode ? - <div> - <Button bsStyle='primary' ref='submitbutton' type='submit' - disabled={!this.state.isValid}>{submitBtn}</Button> - <Button type='reset'>{closeBtn}</Button> - </div> - : <Button type='reset'>{i18n('Close')}</Button> - } - </div> - ); - } -} -export default ValidationButtons; diff --git a/src/generic-components/input/validation/ValidationForm.jsx b/src/generic-components/input/validation/ValidationForm.jsx deleted file mode 100644 index af4001e..0000000 --- a/src/generic-components/input/validation/ValidationForm.jsx +++ /dev/null @@ -1,170 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * Copyright © 2017 Amdocs - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - * - * ECOMP is a trademark and service mark of AT&T Intellectual Property. - */ -/** - * ValidationForm should be used in order to have a form that handles it's - * internal validation state. All ValidationInputs inside the form are checked - * for validity and the styling and submit buttons are updated accordingly. - * - * The properties that ahould be given to the form: - * labledButtons - whether or not use icons only as the form default buttons or - * use buttons with labels onSubmit - function for click on the submit button - * onReset - function for click on the reset button - */ -import React from 'react'; -import ValidationButtons from './ValidationButtons.jsx'; - -class ValidationForm extends React.Component { - - static childContextTypes = { - validationParent: React.PropTypes.any, - isReadOnlyMode: React.PropTypes.bool - }; - - static defaultProps = { - hasButtons: true, - onSubmit: null, - onReset: null, - labledButtons: true, - onValidChange: null, - isValid: true - }; - - static propTypes = { - isValid: React.PropTypes.bool, - hasButtons: React.PropTypes.bool, - onSubmit: React.PropTypes.func, - onReset: React.PropTypes.func, - labledButtons: React.PropTypes.bool, - onValidChange: React.PropTypes.func - }; - - state = { - isValid: this.props.isValid - }; - - constructor(props) { - super(props); - this.validationComponents = []; - } - - render() { - var buttons = (this.props.hasButtons) ? - <ValidationButtons labledButtons={this.props.labledButtons} - ref='buttons' - isReadOnlyMode={this.props.isReadOnlyMode}/> - : null; - return ( - <form {...this.props} onSubmit={event => this.handleFormSubmit(event)}> - <div className='validation-form-content'>{this.props.children}</div> - {buttons} - </form> - ); - } - - handleFormSubmit(event) { - event.preventDefault(); - let isFormValid = true; - this.validationComponents.forEach(validationComponent => { - const isInputValid = validationComponent.validate().isValid; - isFormValid = isInputValid && isFormValid; - }); - if (isFormValid && this.props.onSubmit) { - this.props.onSubmit(event); - } else if (!isFormValid) { - this.setState({isValid: false}); - } - }; - - componentDidUpdate(prevProps, prevState) { - // 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.refs.buttons.setState({isValid: this.state.isValid}); - } - } else if (this.state.isValid !== prevState.isValid) { - if (this.props.hasButtons) { - this.refs.buttons.setState({isValid: this.state.isValid}); - } - // callback in case form is part of bigger picture in view - if (this.props.onValidChange) { - this.props.onValidChange(this.state.isValid); - } - } - } - - componentDidMount() { - if (this.props.hasButtons) { - this.refs.buttons.setState({isValid: this.state.isValid}); - } - } - - - getChildContext() { - return { - validationParent: this, - isReadOnlyMode: this.props.isReadOnlyMode - }; - } - - - /*** - * Used by ValidationInput in order to let the (parent) form know - * the valid state. If there is a change in the state of the form, - * the buttons will be updated. - * - * @param validationComponent - * @param isValid - */ - childValidStateChanged(validationComponent, isValid) { - if (isValid !== this.state.isValid) { - let oldState = this.state.isValid; - let newState = isValid && - this.validationComponents.filter( - otherValidationComponent => validationComponent !== - otherValidationComponent).every(otherValidationComponent => { - return otherValidationComponent.isValid(); - }); - - if (oldState !== newState) { - this.setState({isValid: newState}); - } - } - } - - register(validationComponent) { - this.validationComponents.push(validationComponent); - } - - unregister(validationComponent) { - this.childValidStateChanged(validationComponent, true); - this.validationComponents = - this.validationComponents.filter( - otherValidationComponent => validationComponent !== - otherValidationComponent); - } -} - - -export default ValidationForm; diff --git a/src/generic-components/input/validation/ValidationInput.jsx b/src/generic-components/input/validation/ValidationInput.jsx deleted file mode 100644 index 7c3c2a8..0000000 --- a/src/generic-components/input/validation/ValidationInput.jsx +++ /dev/null @@ -1,351 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * Copyright © 2017 Amdocs - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - * - * ECOMP is a trademark and service mark of AT&T Intellectual Property. - */ -/** - * Used for inputs on a validation form. - * All properties will be passed on to the input element. - * - * The following properties can be set for OOB validations and callbacks: - - required: Boolean: Should be set to true if the input must have a value - - numeric: Boolean : Should be set to true id the input should be an integer - - onChange : Function : Will be called to validate the value if the default validations are not sufficient, should return a boolean value - indicating whether the value is valid - - didUpdateCallback :Function: Will be called after the state has been updated and the component has rerendered. This can be used if - there are dependencies between inputs in a form. - * - * The following properties of the state can be set to determine - * the state of the input from outside components: - - isValid : Boolean - whether the value is valid - - value : value for the input field, - - disabled : Boolean, - - required : Boolean - whether the input value must be filled out. - */ -import React from 'react'; -import ReactDOM from 'react-dom'; -import Validator from 'validator'; -import Input from 'react-bootstrap/lib/Input.js'; -import Overlay from 'react-bootstrap/lib/Overlay.js'; -import Tooltip from 'react-bootstrap/lib/Tooltip.js'; -import isEqual from 'lodash/lang/isEqual.js'; -import i18n from 'utils/i18n/i18n.js'; - -import InputOptions from '../inputOptions/InputOptions.jsx'; - -const globalValidationFunctions = { - required: value => value !== '', - maxLength: (value, length) => Validator.isLength(value, {max: length}), - minLength: (value, length) => Validator.isLength(value, {min: length}), - pattern: (value, pattern) => Validator.matches(value, pattern), - numeric: value => Validator.isNumeric(value), - maxValue: (value, maxValue) => value < maxValue, - alphanumeric: value => Validator.isAlphanumeric(value), - alphanumericWithSpaces: value => Validator.isAlphanumeric( - value.replace(/ /g, '')), - validateName: value => Validator.isAlphanumeric( - value.replace(/\s|\.|\_|\-/g, ''), 'en-US'), - validateVendorName: value => Validator.isAlphanumeric( - value.replace(/[\x7F-\xFF]|\s/g, ''), 'en-US'), - freeEnglishText: value => Validator.isAlphanumeric( - value.replace(/\s|\.|\_|\-|\,|\(|\)|\?/g, ''), 'en-US'), - email: value => Validator.isEmail(value), - ip: value => Validator.isIP(value), - url: value => Validator.isURL(value) -}; - -const globalValidationMessagingFunctions = { - required: () => i18n('Field is required'), - maxLength: (value, maxLength) => i18n( - 'Field value has exceeded it\'s limit, {maxLength}. current length: {length}', - { - length: value.length, - maxLength - }), - minLength: (value, minLength) => i18n( - 'Field value should contain at least {minLength} characters.', {minLength}), - pattern: (value, pattern) => i18n( - 'Field value should match the pattern: {pattern}.', {pattern}), - numeric: () => i18n('Field value should contain numbers only.'), - maxValue: (value, maxValue) => i18n( - 'Field value should be less then: {maxValue}.', {maxValue}), - alphanumeric: () => i18n( - 'Field value should contain letters or digits only.'), - alphanumericWithSpaces: () => i18n( - 'Field value should contain letters, digits or spaces only.'), - validateName: ()=> i18n( - 'Field value should contain English letters, digits , spaces, underscores, dashes and dots only.'), - validateVendorName: ()=> i18n( - 'Field value should contain English letters digits and spaces only.'), - freeEnglishText: ()=> i18n( - 'Field value should contain English letters, digits , spaces, underscores, dashes and dots only.'), - email: () => i18n('Field value should be a valid email address.'), - ip: () => i18n('Field value should be a valid ip address.'), - url: () => i18n('Field value should be a valid url address.'), - general: () => i18n('Field value is invalid.') -}; - -class ValidationInput extends React.Component { - - static contextTypes = { - validationParent: React.PropTypes.any, - isReadOnlyMode: React.PropTypes.bool - }; - - static defaultProps = { - onChange: null, - disabled: null, - didUpdateCallback: null, - validations: {}, - value: '' - }; - - static propTypes = { - onChange: React.PropTypes.func, - disabled: React.PropTypes.bool, - didUpdateCallback: React.PropTypes.func, - validations: React.PropTypes.object - }; - - - state = { - isValid: true, - style: null, - value: this.props.value, - error: {}, - previousErrorMessage: '', - wasInvalid: false - }; - - componentWillReceiveProps({value: nextValue, validations: nextValidaions}) { - if (this.state.wasInvalid) { - const {validations, value} = this.props; - if (value !== nextValue || !isEqual(validations, nextValidaions)) { - this.validate(nextValue, nextValidaions); - } - } else if (this.props.value !== nextValue) { - this.setState({value: nextValue}); - } - } - - render() { - let {isMultiSelect, onOtherChange, type} = this.props; - - let groupClasses = this.props.groupClassName || ''; - if (this.props.validations.required) { - groupClasses += ' required'; - } - let isReadOnlyMode = this.context.isReadOnlyMode; - - return ( - <div className='validation-input-wrapper'> - { - !isMultiSelect && !onOtherChange && type !== 'select' - && <Input - {...this.props} - groupClassName={groupClasses} - ref={'_myInput'} - value={this.state.value} - disabled={isReadOnlyMode || Boolean(this.props.disabled)} - bsStyle={this.state.style} - onChange={() => this.changedInput()} - onBlur={() => this.blurInput()}> - {this.props.children} - </Input> - } - { - (isMultiSelect || onOtherChange || type === 'select') - && <InputOptions onInputChange={() => this.changedInput()} - onBlur={() => this.blurInput()} - hasError={!this.state.isValid} - ref={'_myInput'} {...this.props} /> - } - {this.renderOverlay()} - </div> - ); - } - - renderOverlay() { - let position = 'right'; - if (this.props.type === 'text' - || this.props.type === 'email' - || this.props.type === 'number' - || this.props.type === 'password' - - ) { - position = 'bottom'; - } - - let validationMessage = this.state.error.message || - this.state.previousErrorMessage; - return ( - <Overlay - show={!this.state.isValid} - placement={position} - target={() => {let target = ReactDOM.findDOMNode(this.refs._myInput); return target.offsetParent ? target : undefined;}} - container={this}> - <Tooltip - id={`error-${validationMessage.replace(' ','-')}`} - className='validation-error-message'> - {validationMessage} - </Tooltip> - </Overlay> - ); - } - - componentDidMount() { - if (this.context.validationParent) { - this.context.validationParent.register(this); - } - } - - componentDidUpdate(prevProps, prevState) { - if (this.context.validationParent) { - if (prevState.isValid !== this.state.isValid) { - this.context.validationParent.childValidStateChanged(this, - this.state.isValid); - } - } - if (this.props.didUpdateCallback) { - this.props.didUpdateCallback(); - } - - } - - componentWillUnmount() { - if (this.context.validationParent) { - this.context.validationParent.unregister(this); - } - } - - /*** - * Adding same method as the actual input component - * @returns {*} - */ - getValue() { - if (this.props.type === 'checkbox') { - return this.refs._myInput.getChecked(); - } - return this.refs._myInput.getValue(); - } - - resetValue() { - this.setState({value: this.props.value}); - } - - - /*** - * internal method that validated the value. includes callback to the - * onChange method - * @param value - * @param validations - map containing validation id and the limitation - * describing the validation. - * @returns {object} - */ - validateValue = (value, validations) => { - let {customValidationFunction} = validations; - let error = {}; - let isValid = true; - for (let validation in validations) { - if ('customValidationFunction' !== validation) { - if (validations[validation]) { - if (!globalValidationFunctions[validation](value, - validations[validation])) { - error.id = validation; - error.message = - globalValidationMessagingFunctions[validation](value, - validations[validation]); - isValid = false; - break; - } - } - } else { - let customValidationResult = customValidationFunction(value); - - if (customValidationResult !== true) { - error.id = 'custom'; - isValid = false; - if (typeof customValidationResult === 'string') {//custom validation error message supplied. - error.message = customValidationResult; - } else { - error.message = globalValidationMessagingFunctions.general(); - } - break; - } - - - } - } - - return { - isValid, - error - }; - }; - - /*** - * Internal method that handles the change event of the input. validates and - * updates the state. - */ - changedInput() { - - let {isValid, error} = this.state.wasInvalid ? this.validate() : this.state; - let onChange = this.props.onChange; - if (onChange) { - onChange(this.getValue(), isValid, error); - } - }; - - blurInput() { - if (!this.state.wasInvalid) { - this.setState({wasInvalid: true}); - } - - let {isValid, error} = !this.state.wasInvalid - ? this.validate() - : this.state; - let onBlur = this.props.onBlur; - if (onBlur) { - onBlur(this.getValue(), isValid, error); - } - }; - - validate(value = this.getValue(), validations = this.props.validations) { - let validationStatus = this.validateValue(value, validations); - let {isValid, error} = validationStatus; - let _style = isValid ? null : 'error'; - this.setState({ - isValid, - error, - value, - previousErrorMessage: this.state.error.message || '', - style: _style, - wasInvalid: !isValid || this.state.wasInvalid - }); - - return validationStatus; - } - - isValid() { - return this.state.isValid; - } - -} -export default ValidationInput; diff --git a/src/generic-components/input/validation/ValidationTab.jsx b/src/generic-components/input/validation/ValidationTab.jsx deleted file mode 100644 index 385d585..0000000 --- a/src/generic-components/input/validation/ValidationTab.jsx +++ /dev/null @@ -1,141 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * Copyright © 2017 Amdocs - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - * - * ECOMP is a trademark and service mark of AT&T Intellectual Property. - */ -import React from 'react'; -import Tab from 'react-bootstrap/lib/Tab.js'; - -export default -class ValidationTab extends React.Component { - - static propTypes = { - children: React.PropTypes.node, - eventKey: React.PropTypes.any.isRequired, - onValidationStateChange: React.PropTypes.func //This property is assigned - // dynamically via - // React.cloneElement. lookup - // ValidationTabs.jsx. - // therefore it cannot be - // stated as required! - }; - - constructor(props) { - super(props); - this.validationComponents = []; - } - - static childContextTypes = { - validationParent: React.PropTypes.any - }; - - static contextTypes = { - validationParent: React.PropTypes.any - }; - - getChildContext() { - return {validationParent: this}; - } - - state = { - isValid: true, - notifyParent: false - }; - - componentDidMount() { - let validationParent = this.context.validationParent; - if (validationParent) { - validationParent.register(this); - } - } - - componentWillUnmount() { - let validationParent = this.context.validationParent; - if (validationParent) { - validationParent.unregister(this); - } - } - - register(validationComponent) { - this.validationComponents.push(validationComponent); - } - - unregister(validationComponent) { - this.childValidStateChanged(validationComponent, true); - this.validationComponents = - this.validationComponents.filter( - otherValidationComponent => validationComponent !== - otherValidationComponent); - } - - notifyValidStateChangedToParent(isValid) { - - let validationParent = this.context.validationParent; - if (validationParent) { - validationParent.childValidStateChanged(this, isValid); - } - } - - childValidStateChanged(validationComponent, isValid) { - - const currentValidState = this.state.isValid; - if (isValid !== currentValidState) { - let filteredValidationComponents = this.validationComponents.filter( - otherValidationComponent => validationComponent !== - otherValidationComponent); - let newValidState = isValid && - filteredValidationComponents.every(otherValidationComponent => { - return otherValidationComponent.isValid(); - }); - this.setState({isValid: newValidState, notifyParent: true}); - } - } - - validate() { - let isValid = true; - this.validationComponents.forEach(validationComponent => { - const isValidationComponentValid = validationComponent.validate().isValid; - isValid = isValidationComponentValid && isValid; - }); - this.setState({isValid, notifyParent: false}); - return {isValid}; - } - - componentDidUpdate(prevProps, prevState) { - if (prevState.isValid !== this.state.isValid) { - if (this.state.notifyParent) { - this.notifyValidStateChangedToParent(this.state.isValid); - } - this.props.onValidationStateChange(this.props.eventKey, - this.state.isValid); - } - } - - isValid() { - return this.state.isValid; - } - - render() { - let {children, ...tabProps} = this.props; - return ( - <Tab {...tabProps}>{children}</Tab> - ); - } -} diff --git a/src/generic-components/input/validation/ValidationTabs.jsx b/src/generic-components/input/validation/ValidationTabs.jsx deleted file mode 100644 index 64dd365..0000000 --- a/src/generic-components/input/validation/ValidationTabs.jsx +++ /dev/null @@ -1,102 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * Copyright © 2017 Amdocs - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - * - * ECOMP is a trademark and service mark of AT&T Intellectual Property. - */ -import React from 'react'; -import ReactDOM from 'react-dom'; -import Tabs from 'react-bootstrap/lib/Tabs.js'; -import Overlay from 'react-bootstrap/lib/Overlay.js'; -import Tooltip from 'react-bootstrap/lib/Tooltip.js'; - -import i18n from 'utils/i18n/i18n.js'; - -export default -class ValidationTab extends React.Component { - - static propTypes = { - children: React.PropTypes.node - }; - - state = { - invalidTabs: [] - }; - - cloneTab(element) { - const {invalidTabs} = this.state; - return React.cloneElement( - element, - { - key: element.props.eventKey, - tabClassName: invalidTabs.indexOf(element.props.eventKey) > -1 - ? 'invalid-tab' - : 'valid-tab', - onValidationStateChange: ( - eventKey, isValid) => this.validTabStateChanged(eventKey, isValid) - } - ); - } - - validTabStateChanged(eventKey, isValid) { - let {invalidTabs} = this.state; - let invalidTabIndex = invalidTabs.indexOf(eventKey); - if (isValid && invalidTabIndex > -1) { - this.setState({ - invalidTabs: invalidTabs.filter( - otherEventKey => eventKey !== otherEventKey) - }); - } else if (!isValid && invalidTabIndex === -1) { - this.setState({invalidTabs: [...invalidTabs, eventKey]}); - } - } - - showTabsError() { - const {invalidTabs} = this.state; - return invalidTabs.length > - 0 && - (invalidTabs.length > 1 || invalidTabs[0] !== this.props.activeKey); - } - - render() { - return ( - <div> - <Tabs {...this.props} ref='tabsList'> - {this.props.children.map(element => this.cloneTab(element))} - </Tabs> - <Overlay - animation={false} - show={this.showTabsError()} - placement='bottom' - target={() => { - let target = ReactDOM.findDOMNode(this.refs.tabsList).querySelector('ul > li.invalid-tab:not(.active):nth-of-type(n)'); - return target && target.offsetParent ? target : undefined; - } - } - container={this}> - <Tooltip - id='error-some-tabs-contain-errors' - className='validation-error-message'> - {i18n('One or more tabs are invalid')} - </Tooltip> - </Overlay> - </div> - ); - } -} |