@@ -8,6 +8,7 @@ import {uniqBy, uniq, get, countBy, isNil, xor} from 'lodash';
8
8
9
9
10
10
import { CheckboxGroupInputField } from './CheckboxGroupInputField.jsx' ;
11
+ import { RadioGroupInputField } from './RadioGroupInputField.jsx' ;
11
12
import { CollapsiblePanel } from '../ui/panel/CollapsiblePanel.jsx' ;
12
13
import FieldGroupUtils , { getFieldVal } from '../fieldGroup/FieldGroupUtils.js' ;
13
14
import { dispatchComponentStateChange } from '../core/ComponentCntlr.js' ;
@@ -25,7 +26,7 @@ export class ImageSelect extends PureComponent {
25
26
}
26
27
27
28
render ( ) {
28
- const { style, imageMasterData, groupKey} = this . props ;
29
+ const { style, imageMasterData, groupKey, multiSelect = true } = this . props ;
29
30
imageMasterData . forEach ( ( d ) => {
30
31
[ 'missionId' , 'project' , 'subProject' ] . forEach ( ( k ) => d [ k ] = d [ k ] || '' ) ;
31
32
} ) ;
@@ -46,12 +47,26 @@ export class ImageSelect extends PureComponent {
46
47
return (
47
48
< div style = { style } className = 'ImageSelect' >
48
49
< FilterPanel { ...{ imageMasterData} } />
49
- < DataProductList { ...{ filteredImageData, groupKey, onChange : ( ) => this . setState ( { lastMod :new Date ( ) . getTime ( ) } ) } } />
50
+ < DataProductList { ...{ filteredImageData, groupKey, multiSelect , onChange : ( ) => this . setState ( { lastMod :new Date ( ) . getTime ( ) } ) } } />
50
51
</ div >
51
52
) ;
52
53
}
53
-
54
54
}
55
+
56
+ ImageSelect . propTypes = {
57
+ imageMasterData : PropTypes . arrayOf ( PropTypes . object ) . isRequired ,
58
+ groupKey : PropTypes . string . isRequired ,
59
+ // this component needs to be wrapped by a FieldGroup. User of this component need to provide
60
+ // a function so this component can handle field change event from reducing function.
61
+ addChangeListener : PropTypes . func . isRequired ,
62
+ style : PropTypes . object ,
63
+ title : PropTypes . string ,
64
+ multiSelect : PropTypes . bool
65
+ } ;
66
+
67
+ const toFilterSelectAry = ( groupKey , s ) => getFieldVal ( groupKey , `Filter_${ s } ` , '' ) . split ( ',' ) . map ( ( d ) => d . trim ( ) ) . filter ( ( d ) => d ) ;
68
+
69
+
55
70
function fieldsReducer ( imageMasterData = { } ) {
56
71
return ( inFields , action ) => {
57
72
const { fieldKey= '' , options= { } , value= '' } = action . payload ;
@@ -72,7 +87,7 @@ function fieldsReducer(imageMasterData={}) {
72
87
} else if ( fieldKey . startsWith ( 'IMAGES_' ) ) {
73
88
// one item changed, update project selectAll checkbox
74
89
const matcher = fieldKey . split ( '||' ) [ 0 ] ;
75
- const cbGroups = Object . values ( inFields ) . filter ( ( f ) => f . fieldKey . startsWith ( matcher ) ) ; // array of subproject in this project
90
+ const cbGroups = Object . values ( inFields ) . filter ( ( f ) => get ( f , ' fieldKey' , '' ) . startsWith ( matcher ) ) ; // array of subproject in this project
76
91
const allSelected = cbGroups . reduce ( ( p , f ) => {
77
92
const selAry = get ( f , 'value' , '' ) . split ( ',' ) ;
78
93
const allAry = get ( f , 'options' , [ ] ) . map ( ( o ) => o . value ) ;
@@ -87,18 +102,6 @@ function fieldsReducer(imageMasterData={}) {
87
102
}
88
103
89
104
90
- ImageSelect . propTypes = {
91
- imageMasterData : PropTypes . arrayOf ( PropTypes . object ) . isRequired ,
92
- groupKey : PropTypes . string . isRequired ,
93
- // this component needs to be wrapped by a FieldGroup. User of this component need to provide
94
- // a function so this component can handle field change even from reducing function.
95
- addChangeListener : PropTypes . func . isRequired ,
96
- style : PropTypes . object ,
97
- title : PropTypes . string
98
- } ;
99
-
100
- const toFilterSelectAry = ( groupKey , s ) => getFieldVal ( groupKey , `Filter_${ s } ` , '' ) . split ( ',' ) . map ( ( d ) => d . trim ( ) ) . filter ( ( d ) => d ) ;
101
-
102
105
103
106
/*--------------------------- Filter Panel ---------------------------------------------*/
104
107
@@ -214,7 +217,7 @@ const toFilterSummary = (master, key, desc) => Object.entries(countBy(master, (d
214
217
/*--------------------------- Data Product List ---------------------------------------*/
215
218
216
219
// eslint-disable-next-line
217
- function DataProductList ( { filteredImageData, groupKey, onChange} ) {
220
+ function DataProductList ( { filteredImageData, groupKey, multiSelect , onChange} ) {
218
221
const projects = uniqBy ( filteredImageData , 'project' ) . map ( ( d ) => d . project ) ;
219
222
const setDSListMode = ( flg ) => {
220
223
projects . forEach ( ( k ) => dispatchComponentStateChange ( k , { isOpen :flg } ) ) ;
@@ -230,7 +233,7 @@ function DataProductList({filteredImageData, groupKey, onChange}) {
230
233
< div className = 'DataProductList__view' >
231
234
{
232
235
projects . map ( ( p ) =>
233
- < DataProduct key = { p } { ...{ groupKey, project :p , filteredImageData} } />
236
+ < DataProduct key = { p } { ...{ groupKey, project :p , filteredImageData, multiSelect } } />
234
237
)
235
238
}
236
239
</ div >
@@ -239,7 +242,7 @@ function DataProductList({filteredImageData, groupKey, onChange}) {
239
242
}
240
243
241
244
// eslint-disable-next-line
242
- function DataProduct ( { groupKey, project, filteredImageData} ) {
245
+ function DataProduct ( { groupKey, project, filteredImageData, multiSelect } ) {
243
246
244
247
// filter projects ... projects is like dataproduct or dataset.. i.e SEIP
245
248
const projectData = filteredImageData . filter ( ( d ) => d . project === project ) ;
@@ -249,11 +252,11 @@ function DataProduct({groupKey, project, filteredImageData}) {
249
252
250
253
return (
251
254
< div className = 'DataProductList__item' >
252
- < CollapsiblePanel componentKey = { project } header = { < Header { ...{ project} } /> } isOpen = { isOpen } >
255
+ < CollapsiblePanel componentKey = { project } header = { < Header { ...{ project, multiSelect } } /> } isOpen = { isOpen } >
253
256
< div className = 'DataProductList__item--details' >
254
257
{
255
258
subProjects . map ( ( sp ) =>
256
- < BandSelect key = { 'sub_' + sp } { ...{ subProject :sp , projectData, labelMaxWidth} } />
259
+ < BandSelect key = { 'sub_' + sp } { ...{ groupKey , subProject :sp , projectData, labelMaxWidth, multiSelect } } />
257
260
)
258
261
}
259
262
</ div >
@@ -263,8 +266,10 @@ function DataProduct({groupKey, project, filteredImageData}) {
263
266
264
267
}
265
268
266
- function Header ( { project} ) {
269
+ function Header ( { project, multiSelect } ) {
267
270
const fieldKey = `PROJ_ALL_${ project } ` ;
271
+
272
+ if ( ! multiSelect ) return < div style = { { display : 'inline-block' } } > { project } </ div > ;
268
273
return (
269
274
< div className = 'DataProductList__item--header' onClick = { ( e ) => e . stopPropagation ( ) } >
270
275
< CheckboxGroupInputField
@@ -285,12 +290,12 @@ function Header({project}) {
285
290
286
291
const hasImageSelection = ( groupKey , proj ) => {
287
292
const fields = FieldGroupUtils . getGroupFields ( groupKey ) || { } ;
288
- return Object . values ( fields ) . some ( ( fld ) => fld . fieldKey . startsWith ( `IMAGES_${ proj } ` ) && fld . value ) ;
293
+ return Object . values ( fields ) . some ( ( fld ) => get ( fld , ' fieldKey' , '' ) . startsWith ( `IMAGES_${ proj } ` ) && fld . value ) ;
289
294
} ;
290
295
291
296
292
297
// eslint-disable-next-line
293
- function BandSelect ( { subProject, projectData, labelMaxWidth} ) {
298
+ function BandSelect ( { groupKey , subProject, projectData, labelMaxWidth, multiSelect } ) {
294
299
subProject = isNil ( subProject ) ? '' : subProject ;
295
300
const fieldKey = `IMAGES_${ get ( projectData , [ 0 , 'project' ] ) } ||${ subProject } ` ;
296
301
const options = toImageOptions ( projectData . filter ( ( p ) => p . subProject === subProject ) ) ;
@@ -300,24 +305,46 @@ function BandSelect({subProject, projectData, labelMaxWidth}) {
300
305
className = 'DataProductList__item--bandLabel' > { subProject } </ div >
301
306
< span > :</ span >
302
307
</ div > ) ;
303
- return (
304
- < div className = 'DataProductList__item--band' >
305
- { label }
306
- < CheckboxGroupInputField
307
- key = { fieldKey }
308
- fieldKey = { fieldKey }
309
- initialState = { {
308
+ if ( multiSelect ) {
309
+ return (
310
+ < div className = 'DataProductList__item--band' >
311
+ { label }
312
+ < CheckboxGroupInputField
313
+ key = { fieldKey }
314
+ fieldKey = { fieldKey }
315
+ initialState = { {
310
316
options, // Note: values in initialState are saved into fieldgroup. options are used in the reducer above to determine what 'all' means.
311
317
value : '' ,
312
318
tooltip : 'Please select some boxes' ,
313
319
label : '' } }
314
- options = { options }
315
- alignment = 'horizontal'
316
- labelWidth = { 35 }
317
- wrapperStyle = { { whiteSpace : 'normal' } }
318
- />
319
- </ div >
320
- ) ;
320
+ options = { options }
321
+ alignment = 'horizontal'
322
+ labelWidth = { 35 }
323
+ wrapperStyle = { { whiteSpace : 'normal' } }
324
+ />
325
+ </ div >
326
+ ) ;
327
+ } else {
328
+ return (
329
+ < div className = 'DataProductList__item--band' >
330
+ { label }
331
+ < RadioGroupInputField
332
+ key = { fieldKey }
333
+ fieldKey = { `IMAGES_${ groupKey } ` }
334
+ initialState = { {
335
+ options, // Note: values in initialState are saved into fieldgroup. options are used in the reducer above to determine what 'all' means.
336
+ value : '' ,
337
+ tooltip : 'Please select some boxes' ,
338
+ label : '' } }
339
+ options = { options }
340
+ defaultValue = ''
341
+ alignment = 'horizontal'
342
+ labelWidth = { 35 }
343
+ wrapperStyle = { { whiteSpace : 'normal' } }
344
+ />
345
+ </ div >
346
+ ) ;
347
+ }
321
348
}
322
349
323
350
const toImageOptions = ( a ) => a . map ( ( d ) => ( { label : d . title , value : d . imageId } ) ) ;
0 commit comments