/* * Copyright © 2016-2018 European Support Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import React from 'react'; import PropTypes from 'prop-types'; import SVGIcon from 'sdc-ui/lib/react/SVGIcon.js'; import Input from 'nfvo-components/input/validation/Input.jsx'; class DualListboxView extends React.Component { constructor(props) { super(props); this.availableListRef = React.createRef(); this.availableListFilterRef = React.createRef(); this.selectedValuesListFilterRef = React.createRef(); this.selectedValuesRef = React.createRef(); } 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) => availableList.indexOf(a.id) - availableList.indexOf(b.id) ); return (
{this.renderListbox( filterTitle.left, unselectedList, { value: availableListFilter, ref: this.availableListFilterRef, disabled: isReadOnlyMode, onChange: value => this.setState({ availableListFilter: value }) }, { ref: this.availableListRef, disabled: isReadOnlyMode, testId: 'available' } )} {this.renderOperationsBar(isReadOnlyMode)} {this.renderListbox( filterTitle.right, selectedList, { value: selectedValuesListFilter, ref: this.selectedValuesListFilterRef, disabled: isReadOnlyMode, onChange: value => this.setState({ selectedValuesListFilter: value }) }, { ref: this.selectedValuesRef, disabled: isReadOnlyMode, testId: 'selected' } )}
); } 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 (

{filterTitle}

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 && ( )} {unMatchedItems.map(item => this.renderOption(item.id, item.name) )}
); } onSelectItems(selectedOptions) { let selectedValues = Object.keys(selectedOptions).map( k => selectedOptions[k].value ); this.setState({ selectedValues }); } renderOption(value, name) { return ( ); } renderOperationsBar(isReadOnlyMode) { return (
{this.renderOperationBarButton( () => this.addToSelectedList(), 'angleRight' )} {this.renderOperationBarButton( () => this.removeFromSelectedList(), 'angleLeft' )} {this.renderOperationBarButton( () => this.addAllToSelectedList(), 'angleDoubleRight' )} {this.renderOperationBarButton( () => this.removeAllFromSelectedList(), 'angleDoubleLeft' )}
); } renderOperationBarButton(onClick, iconName) { return (
); } 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([]); } // fix for auto-selection of first value in the list on the first render componentDidMount() { this.availableListRef.current.input.value = ''; this.selectedValuesRef.current.input.value = ''; } } export default DualListboxView;