Add new code new version
[sdc.git] / openecomp-ui / src / nfvo-components / input / dualListbox / DualListboxView.jsx
1 import React from 'react';
2 import FontAwesome from 'react-fontawesome';
3 import Input from 'react-bootstrap/lib/Input.js';
4
5 class DualListboxView extends React.Component {
6
7         static propTypes = {
8
9                 availableList: React.PropTypes.arrayOf(React.PropTypes.shape({
10                         id: React.PropTypes.string.isRequired,
11                         name: React.PropTypes.string.isRequired
12                 })),
13                 filterTitle: React.PropTypes.shape({
14                         left: React.PropTypes.string,
15                         right: React.PropTypes.string
16                 }),
17                 selectedValuesList: React.PropTypes.arrayOf(React.PropTypes.string),
18
19                 onChange: React.PropTypes.func.isRequired
20         };
21
22         static defaultProps = {
23                 selectedValuesList: [],
24                 availableList: [],
25                 filterTitle: {
26                         left: '',
27                         right: ''
28                 }
29         };
30
31         state = {
32                 availableListFilter: '',
33                 selectedValuesListFilter: ''
34         };
35
36         static contextTypes = {
37                 isReadOnlyMode: React.PropTypes.bool
38         };
39
40         render() {
41                 let {availableList, selectedValuesList, filterTitle} = this.props;
42                 let {availableListFilter, selectedValuesListFilter} = this.state;
43                 let isReadOnlyMode = this.context.isReadOnlyMode;
44
45                 let unselectedList = availableList.filter(availableItem => !selectedValuesList.find(value => value === availableItem.id));
46                 let selectedList = availableList.filter(availableItem => selectedValuesList.find(value => value === availableItem.id));
47                 selectedList = selectedList.sort((a, b) => selectedValuesList.indexOf(a.id) - selectedValuesList.indexOf(b.id));
48
49                 return (
50                         <div className='dual-list-box'>
51                                 {this.renderListbox(filterTitle.left, unselectedList, {
52                                         value: availableListFilter,
53                                         ref: 'availableListFilter',
54                                         disabled: isReadOnlyMode,
55                                         onChange: () => this.setState({availableListFilter: this.refs.availableListFilter.getValue()})
56                                 }, {ref: 'availableValues', disabled: isReadOnlyMode})}
57                                 {this.renderOperationsBar(isReadOnlyMode)}
58                                 {this.renderListbox(filterTitle.right, selectedList, {
59                                         value: selectedValuesListFilter,
60                                         ref: 'selectedValuesListFilter',
61                                         disabled: isReadOnlyMode,
62                                         onChange: () => this.setState({selectedValuesListFilter: this.refs.selectedValuesListFilter.getValue()})
63                                 }, {ref: 'selectedValues', disabled: isReadOnlyMode})}
64                         </div>
65                 );
66         }
67
68         renderListbox(filterTitle, list, filterProps, props) {
69                 let regExFilter = new RegExp(escape(filterProps.value), 'i');
70                 let matchedItems = list.filter(item => item.name.match(regExFilter));
71                 let unMatchedItems = list.filter(item => !item.name.match(regExFilter));
72
73
74                 return (
75                         <div className='dual-search-multi-select-section'>
76                                 <p>{filterTitle}</p>
77                                 <div className='dual-text-box-search search-wrapper'>
78                                         <Input name='search-input-control' type='text' groupClassName='search-input-control' {...filterProps}/>
79                                         <FontAwesome name='search' className='search-icon'/>
80                                 </div>
81                                 <Input
82                                         multiple
83                                         groupClassName='dual-list-box-multi-select'
84                                         type='select'
85                                         name='dual-list-box-multi-select'
86                                         {...props}>
87                                         {matchedItems.map(item => this.renderOption(item.id, item.name))}
88                                         {matchedItems.length && unMatchedItems.length && <option style={{pointerEvents: 'none'}}>--------------------</option>}
89                                         {unMatchedItems.map(item => this.renderOption(item.id, item.name))}
90                                 </Input>
91                         </div>
92                 );
93         }
94
95         renderOption(value, name) {
96                 return (<option className='dual-list-box-multi-select-text' key={value} value={value}>{name}</option>);
97         }
98
99         renderOperationsBar(isReadOnlyMode) {
100                 return (
101                         <div className={`dual-list-options-bar${isReadOnlyMode ? ' disabled' : ''}`}>
102                                 {this.renderOperationBarButton(() => this.addToSelectedList(), 'angle-right')}
103                                 {this.renderOperationBarButton(() => this.removeFromSelectedList(), 'angle-left')}
104                                 {this.renderOperationBarButton(() => this.addAllToSelectedList(), 'angle-double-right')}
105                                 {this.renderOperationBarButton(() => this.removeAllFromSelectedList(), 'angle-double-left')}
106                         </div>
107                 );
108         }
109
110         renderOperationBarButton(onClick, fontAwesomeIconName){
111                 return (<div className='dual-list-option' onClick={onClick}><FontAwesome name={fontAwesomeIconName}/></div>);
112         }
113
114         addToSelectedList() {
115                 this.props.onChange(this.props.selectedValuesList.concat(this.refs.availableValues.getValue()));
116         }
117
118         removeFromSelectedList() {
119                 const selectedValues = this.refs.selectedValues.getValue();
120                 this.props.onChange(this.props.selectedValuesList.filter(value => !selectedValues.find(selectedValue => selectedValue === value)));
121         }
122
123         addAllToSelectedList() {
124                 this.props.onChange(this.props.availableList.map(item => item.id));
125         }
126
127         removeAllFromSelectedList() {
128                 this.props.onChange([]);
129         }
130 }
131
132 export default DualListboxView;