1
- import React from 'react' ;
1
+ import React , { useState } from 'react' ;
2
2
import PropTypes from 'prop-types' ;
3
3
import { DualListSelector } from '@patternfly/react-core' ;
4
4
import { useFieldApi } from '@data-driven-forms/react-form-renderer' ;
5
5
import isEqual from 'lodash/isEqual' ;
6
6
7
7
import './dual-list-select.scss' ;
8
8
import FormGroup from '../common/form-group' ;
9
+ import DualListContext from './dual-list-context' ;
9
10
10
11
const DualList = ( props ) => {
11
- const { label, isRequired, helperText, meta, description, hideLabel, id, input, FormGroupProps, options, getValueFromNode, ...rest } = useFieldApi ( {
12
+ const {
13
+ label,
14
+ isRequired,
15
+ helperText,
16
+ meta,
17
+ description,
18
+ hideLabel,
19
+ id,
20
+ input,
21
+ FormGroupProps,
22
+ options,
23
+ getValueFromNode,
24
+ isSearchable,
25
+ isSortable,
26
+ ...rest
27
+ } = useFieldApi ( {
12
28
...props ,
13
29
isEqual : ( current , initial ) => isEqual ( [ ...( current || [ ] ) ] . sort ( ) , [ ...( initial || [ ] ) ] . sort ( ) )
14
30
} ) ;
15
31
32
+ const [ sortConfig , setSortConfig ] = useState ( ( ) => ( { left : isSortable && 'asc' , right : isSortable && 'asc' } ) ) ;
33
+
16
34
const value = input . value || [ ] ;
17
35
18
36
let leftOptions ;
@@ -46,6 +64,18 @@ const DualList = (props) => {
46
64
filterOption = ( option , input ) => ( option . value ? option . value . includes ( input ) : getValueFromNode ( option ) . includes ( input ) ) ;
47
65
}
48
66
67
+ if ( isSortable ) {
68
+ const sort = ( direction , a , b ) => ( direction === 'asc' ? a . localeCompare ( b ) : b . localeCompare ( a ) ) ;
69
+
70
+ if ( ! getValueFromNode ) {
71
+ leftOptions = leftOptions . sort ( ( a , b ) => sort ( sortConfig . left , a . label || a , b . label || b ) ) ;
72
+ rightOptions = rightOptions . sort ( ( a , b ) => sort ( sortConfig . right , a . label || a , b . label || b ) ) ;
73
+ } else {
74
+ leftOptions = leftOptions . sort ( ( a , b ) => sort ( sortConfig . left , getValueFromNode ( a . label || a ) , getValueFromNode ( b . label || b ) ) ) ;
75
+ rightOptions = rightOptions . sort ( ( a , b ) => sort ( sortConfig . right , getValueFromNode ( a . label || a ) , getValueFromNode ( b . label || b ) ) ) ;
76
+ }
77
+ }
78
+
49
79
return (
50
80
< FormGroup
51
81
label = { label }
@@ -57,23 +87,24 @@ const DualList = (props) => {
57
87
id = { id || input . name }
58
88
FormGroupProps = { FormGroupProps }
59
89
>
60
- < DualListSelector
61
- availableOptions = { leftOptions }
62
- chosenOptions = { rightOptions }
63
- onListChange = { onListChange }
64
- id = { id || input . name }
65
- isSearchable
66
- { ...( getValueFromNode && {
67
- addAll : onListChange ,
68
- addSelected : onListChange ,
69
- filterOption,
70
- onOptionSelect : onListChange ,
71
- removeAll : onListChange ,
72
- removeSelected : onListChange
73
- } ) }
74
- { ...rest }
75
- />
76
- { JSON . stringify ( input . value , null , 2 ) }
90
+ < DualListContext . Provider value = { { sortConfig, setSortConfig } } >
91
+ < DualListSelector
92
+ availableOptions = { leftOptions }
93
+ chosenOptions = { rightOptions }
94
+ onListChange = { onListChange }
95
+ id = { id || input . name }
96
+ isSearchable = { isSearchable }
97
+ { ...( getValueFromNode && {
98
+ addAll : onListChange ,
99
+ addSelected : onListChange ,
100
+ filterOption,
101
+ onOptionSelect : onListChange ,
102
+ removeAll : onListChange ,
103
+ removeSelected : onListChange
104
+ } ) }
105
+ { ...rest }
106
+ />
107
+ </ DualListContext . Provider >
77
108
</ FormGroup >
78
109
) ;
79
110
} ;
@@ -85,7 +116,9 @@ DualList.propTypes = {
85
116
description : PropTypes . node ,
86
117
hideLabel : PropTypes . bool ,
87
118
id : PropTypes . string ,
88
- getValueFromNode : PropTypes . func
119
+ getValueFromNode : PropTypes . func ,
120
+ isSearchable : PropTypes . bool ,
121
+ isSortable : PropTypes . bool
89
122
} ;
90
123
91
124
export default DualList ;
0 commit comments