/*
* 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 (
);
}
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;