@wordpress/dataviews 0.6.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +9 -0
- package/README.md +48 -15
- package/build/add-filter.js +0 -2
- package/build/add-filter.js.map +1 -1
- package/build/bulk-actions.js +41 -3
- package/build/bulk-actions.js.map +1 -1
- package/build/constants.js +28 -7
- package/build/constants.js.map +1 -1
- package/build/dataviews.js +34 -21
- package/build/dataviews.js.map +1 -1
- package/build/filter-summary.js +33 -12
- package/build/filter-summary.js.map +1 -1
- package/build/filters.js +10 -2
- package/build/filters.js.map +1 -1
- package/build/item-actions.js +20 -39
- package/build/item-actions.js.map +1 -1
- package/build/pagination.js +4 -3
- package/build/pagination.js.map +1 -1
- package/build/reset-filters.js +2 -1
- package/build/reset-filters.js.map +1 -1
- package/build/search-widget.js +117 -8
- package/build/search-widget.js.map +1 -1
- package/build/single-selection-checkbox.js +7 -2
- package/build/single-selection-checkbox.js.map +1 -1
- package/build/utils.js +24 -2
- package/build/utils.js.map +1 -1
- package/build/view-actions.js.map +1 -1
- package/build/view-grid.js +12 -13
- package/build/view-grid.js.map +1 -1
- package/build/view-list.js +1 -1
- package/build/view-list.js.map +1 -1
- package/build/view-table.js +111 -47
- package/build/view-table.js.map +1 -1
- package/build-module/add-filter.js +0 -2
- package/build-module/add-filter.js.map +1 -1
- package/build-module/bulk-actions.js +40 -4
- package/build-module/bulk-actions.js.map +1 -1
- package/build-module/constants.js +27 -6
- package/build-module/constants.js.map +1 -1
- package/build-module/dataviews.js +35 -22
- package/build-module/dataviews.js.map +1 -1
- package/build-module/filter-summary.js +34 -13
- package/build-module/filter-summary.js.map +1 -1
- package/build-module/filters.js +11 -3
- package/build-module/filters.js.map +1 -1
- package/build-module/item-actions.js +20 -39
- package/build-module/item-actions.js.map +1 -1
- package/build-module/pagination.js +4 -3
- package/build-module/pagination.js.map +1 -1
- package/build-module/reset-filters.js +2 -1
- package/build-module/reset-filters.js.map +1 -1
- package/build-module/search-widget.js +120 -11
- package/build-module/search-widget.js.map +1 -1
- package/build-module/single-selection-checkbox.js +7 -2
- package/build-module/single-selection-checkbox.js.map +1 -1
- package/build-module/utils.js +25 -3
- package/build-module/utils.js.map +1 -1
- package/build-module/view-actions.js.map +1 -1
- package/build-module/view-grid.js +13 -14
- package/build-module/view-grid.js.map +1 -1
- package/build-module/view-list.js +2 -2
- package/build-module/view-list.js.map +1 -1
- package/build-module/view-table.js +113 -49
- package/build-module/view-table.js.map +1 -1
- package/build-style/style-rtl.css +76 -46
- package/build-style/style.css +76 -46
- package/package.json +11 -11
- package/src/add-filter.js +0 -2
- package/src/bulk-actions.js +54 -4
- package/src/constants.js +35 -6
- package/src/dataviews.js +66 -49
- package/src/filter-summary.js +76 -23
- package/src/filters.js +16 -5
- package/src/item-actions.js +19 -55
- package/src/pagination.js +8 -3
- package/src/reset-filters.js +2 -1
- package/src/search-widget.js +182 -15
- package/src/single-selection-checkbox.js +7 -1
- package/src/stories/fixtures.js +12 -1
- package/src/stories/index.story.js +43 -4
- package/src/style.scss +108 -73
- package/src/utils.js +38 -4
- package/src/view-actions.js +1 -1
- package/src/view-grid.js +13 -12
- package/src/view-list.js +2 -1
- package/src/view-table.js +162 -81
package/src/view-table.js
CHANGED
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
Icon,
|
|
15
15
|
privateApis as componentsPrivateApis,
|
|
16
16
|
CheckboxControl,
|
|
17
|
+
Spinner,
|
|
17
18
|
} from '@wordpress/components';
|
|
18
19
|
import {
|
|
19
20
|
forwardRef,
|
|
@@ -21,6 +22,7 @@ import {
|
|
|
21
22
|
useId,
|
|
22
23
|
useRef,
|
|
23
24
|
useState,
|
|
25
|
+
useMemo,
|
|
24
26
|
Children,
|
|
25
27
|
Fragment,
|
|
26
28
|
} from '@wordpress/element';
|
|
@@ -33,6 +35,10 @@ import { unlock } from './lock-unlock';
|
|
|
33
35
|
import ItemActions from './item-actions';
|
|
34
36
|
import { sanitizeOperators } from './utils';
|
|
35
37
|
import { ENUMERATION_TYPE, SORTING_DIRECTIONS } from './constants';
|
|
38
|
+
import {
|
|
39
|
+
useSomeItemHasAPossibleBulkAction,
|
|
40
|
+
useHasAPossibleBulkAction,
|
|
41
|
+
} from './bulk-actions';
|
|
36
42
|
|
|
37
43
|
const {
|
|
38
44
|
DropdownMenuV2: DropdownMenu,
|
|
@@ -43,7 +49,7 @@ const {
|
|
|
43
49
|
DropdownMenuSeparatorV2: DropdownMenuSeparator,
|
|
44
50
|
} = unlock( componentsPrivateApis );
|
|
45
51
|
|
|
46
|
-
function
|
|
52
|
+
function WithDropDownMenuSeparators( { children } ) {
|
|
47
53
|
return Children.toArray( children )
|
|
48
54
|
.filter( Boolean )
|
|
49
55
|
.map( ( child, i ) => (
|
|
@@ -96,7 +102,7 @@ const HeaderMenu = forwardRef( function HeaderMenu(
|
|
|
96
102
|
}
|
|
97
103
|
style={ { minWidth: '240px' } }
|
|
98
104
|
>
|
|
99
|
-
<
|
|
105
|
+
<WithDropDownMenuSeparators>
|
|
100
106
|
{ isSortable && (
|
|
101
107
|
<DropdownMenuGroup>
|
|
102
108
|
{ Object.entries( SORTING_DIRECTIONS ).map(
|
|
@@ -181,13 +187,25 @@ const HeaderMenu = forwardRef( function HeaderMenu(
|
|
|
181
187
|
</DropdownMenuItemLabel>
|
|
182
188
|
</DropdownMenuItem>
|
|
183
189
|
) }
|
|
184
|
-
</
|
|
190
|
+
</WithDropDownMenuSeparators>
|
|
185
191
|
</DropdownMenu>
|
|
186
192
|
);
|
|
187
193
|
} );
|
|
188
194
|
|
|
189
|
-
function BulkSelectionCheckbox( {
|
|
190
|
-
|
|
195
|
+
function BulkSelectionCheckbox( {
|
|
196
|
+
selection,
|
|
197
|
+
onSelectionChange,
|
|
198
|
+
data,
|
|
199
|
+
actions,
|
|
200
|
+
} ) {
|
|
201
|
+
const selectableItems = useMemo( () => {
|
|
202
|
+
return data.filter( ( item ) => {
|
|
203
|
+
return actions.some(
|
|
204
|
+
( action ) => action.supportsBulk && action.isEligible( item )
|
|
205
|
+
);
|
|
206
|
+
} );
|
|
207
|
+
}, [ data, actions ] );
|
|
208
|
+
const areAllSelected = selection.length === selectableItems.length;
|
|
191
209
|
return (
|
|
192
210
|
<CheckboxControl
|
|
193
211
|
className="dataviews-view-table-selection-checkbox"
|
|
@@ -198,7 +216,7 @@ function BulkSelectionCheckbox( { selection, onSelectionChange, data } ) {
|
|
|
198
216
|
if ( areAllSelected ) {
|
|
199
217
|
onSelectionChange( [] );
|
|
200
218
|
} else {
|
|
201
|
-
onSelectionChange(
|
|
219
|
+
onSelectionChange( selectableItems );
|
|
202
220
|
}
|
|
203
221
|
} }
|
|
204
222
|
label={ areAllSelected ? __( 'Deselect all' ) : __( 'Select all' ) }
|
|
@@ -206,6 +224,127 @@ function BulkSelectionCheckbox( { selection, onSelectionChange, data } ) {
|
|
|
206
224
|
);
|
|
207
225
|
}
|
|
208
226
|
|
|
227
|
+
function TableRow( {
|
|
228
|
+
hasBulkActions,
|
|
229
|
+
item,
|
|
230
|
+
actions,
|
|
231
|
+
id,
|
|
232
|
+
visibleFields,
|
|
233
|
+
primaryField,
|
|
234
|
+
selection,
|
|
235
|
+
getItemId,
|
|
236
|
+
onSelectionChange,
|
|
237
|
+
data,
|
|
238
|
+
} ) {
|
|
239
|
+
const hasPossibleBulkAction = useHasAPossibleBulkAction( actions, item );
|
|
240
|
+
|
|
241
|
+
const isSelected = selection.includes( id );
|
|
242
|
+
|
|
243
|
+
const [ isHovered, setIsHovered ] = useState( false );
|
|
244
|
+
|
|
245
|
+
const handleMouseEnter = () => {
|
|
246
|
+
setIsHovered( true );
|
|
247
|
+
};
|
|
248
|
+
|
|
249
|
+
const handleMouseLeave = () => {
|
|
250
|
+
setIsHovered( false );
|
|
251
|
+
};
|
|
252
|
+
|
|
253
|
+
return (
|
|
254
|
+
<tr
|
|
255
|
+
className={ classnames( 'dataviews-view-table__row', {
|
|
256
|
+
'is-selected':
|
|
257
|
+
hasPossibleBulkAction && selection.includes( id ),
|
|
258
|
+
'is-hovered': isHovered,
|
|
259
|
+
} ) }
|
|
260
|
+
onMouseEnter={ handleMouseEnter }
|
|
261
|
+
onMouseLeave={ handleMouseLeave }
|
|
262
|
+
onClickCapture={ ( event ) => {
|
|
263
|
+
if ( event.ctrlKey || event.metaKey ) {
|
|
264
|
+
event.stopPropagation();
|
|
265
|
+
event.preventDefault();
|
|
266
|
+
if ( ! hasPossibleBulkAction ) {
|
|
267
|
+
return;
|
|
268
|
+
}
|
|
269
|
+
if ( ! isSelected ) {
|
|
270
|
+
onSelectionChange(
|
|
271
|
+
data.filter( ( _item ) => {
|
|
272
|
+
const itemId = getItemId?.( _item );
|
|
273
|
+
return (
|
|
274
|
+
itemId === id ||
|
|
275
|
+
selection.includes( itemId )
|
|
276
|
+
);
|
|
277
|
+
} )
|
|
278
|
+
);
|
|
279
|
+
} else {
|
|
280
|
+
onSelectionChange(
|
|
281
|
+
data.filter( ( _item ) => {
|
|
282
|
+
const itemId = getItemId?.( _item );
|
|
283
|
+
return (
|
|
284
|
+
itemId !== id &&
|
|
285
|
+
selection.includes( itemId )
|
|
286
|
+
);
|
|
287
|
+
} )
|
|
288
|
+
);
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
} }
|
|
292
|
+
>
|
|
293
|
+
{ hasBulkActions && (
|
|
294
|
+
<td
|
|
295
|
+
className="dataviews-view-table__checkbox-column"
|
|
296
|
+
style={ {
|
|
297
|
+
width: 20,
|
|
298
|
+
minWidth: 20,
|
|
299
|
+
} }
|
|
300
|
+
>
|
|
301
|
+
<div className="dataviews-view-table__cell-content-wrapper">
|
|
302
|
+
<SingleSelectionCheckbox
|
|
303
|
+
id={ id }
|
|
304
|
+
item={ item }
|
|
305
|
+
selection={ selection }
|
|
306
|
+
onSelectionChange={ onSelectionChange }
|
|
307
|
+
getItemId={ getItemId }
|
|
308
|
+
data={ data }
|
|
309
|
+
primaryField={ primaryField }
|
|
310
|
+
disabled={ ! hasPossibleBulkAction }
|
|
311
|
+
/>
|
|
312
|
+
</div>
|
|
313
|
+
</td>
|
|
314
|
+
) }
|
|
315
|
+
{ visibleFields.map( ( field ) => (
|
|
316
|
+
<td
|
|
317
|
+
key={ field.id }
|
|
318
|
+
style={ {
|
|
319
|
+
width: field.width || undefined,
|
|
320
|
+
minWidth: field.minWidth || undefined,
|
|
321
|
+
maxWidth: field.maxWidth || undefined,
|
|
322
|
+
} }
|
|
323
|
+
>
|
|
324
|
+
<div
|
|
325
|
+
className={ classnames(
|
|
326
|
+
'dataviews-view-table__cell-content-wrapper',
|
|
327
|
+
{
|
|
328
|
+
'dataviews-view-table__primary-field':
|
|
329
|
+
primaryField?.id === field.id,
|
|
330
|
+
}
|
|
331
|
+
) }
|
|
332
|
+
>
|
|
333
|
+
{ field.render( {
|
|
334
|
+
item,
|
|
335
|
+
} ) }
|
|
336
|
+
</div>
|
|
337
|
+
</td>
|
|
338
|
+
) ) }
|
|
339
|
+
{ !! actions?.length && (
|
|
340
|
+
<td className="dataviews-view-table__actions-column">
|
|
341
|
+
<ItemActions item={ item } actions={ actions } />
|
|
342
|
+
</td>
|
|
343
|
+
) }
|
|
344
|
+
</tr>
|
|
345
|
+
);
|
|
346
|
+
}
|
|
347
|
+
|
|
209
348
|
function ViewTable( {
|
|
210
349
|
view,
|
|
211
350
|
onChangeView,
|
|
@@ -219,10 +358,10 @@ function ViewTable( {
|
|
|
219
358
|
onSelectionChange,
|
|
220
359
|
setOpenedFilter,
|
|
221
360
|
} ) {
|
|
222
|
-
const hasBulkActions = actions?.some( ( action ) => action.supportsBulk );
|
|
223
361
|
const headerMenuRefs = useRef( new Map() );
|
|
224
362
|
const headerMenuToFocusRef = useRef();
|
|
225
363
|
const [ nextHeaderMenuToFocus, setNextHeaderMenuToFocus ] = useState();
|
|
364
|
+
const hasBulkActions = useSomeItemHasAPossibleBulkAction( actions, data );
|
|
226
365
|
|
|
227
366
|
useEffect( () => {
|
|
228
367
|
if ( headerMenuToFocusRef.current ) {
|
|
@@ -263,7 +402,7 @@ function ViewTable( {
|
|
|
263
402
|
);
|
|
264
403
|
|
|
265
404
|
return (
|
|
266
|
-
|
|
405
|
+
<>
|
|
267
406
|
<table
|
|
268
407
|
className="dataviews-view-table"
|
|
269
408
|
aria-busy={ isLoading }
|
|
@@ -285,6 +424,7 @@ function ViewTable( {
|
|
|
285
424
|
selection={ selection }
|
|
286
425
|
onSelectionChange={ onSelectionChange }
|
|
287
426
|
data={ data }
|
|
427
|
+
actions={ actions }
|
|
288
428
|
/>
|
|
289
429
|
</th>
|
|
290
430
|
) }
|
|
@@ -347,78 +487,19 @@ function ViewTable( {
|
|
|
347
487
|
<tbody>
|
|
348
488
|
{ hasData &&
|
|
349
489
|
usedData.map( ( item, index ) => (
|
|
350
|
-
<
|
|
490
|
+
<TableRow
|
|
351
491
|
key={ getItemId( item ) }
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
{
|
|
362
|
-
|
|
363
|
-
className="dataviews-view-table__checkbox-column"
|
|
364
|
-
style={ {
|
|
365
|
-
width: 20,
|
|
366
|
-
minWidth: 20,
|
|
367
|
-
} }
|
|
368
|
-
>
|
|
369
|
-
<div className="dataviews-view-table__cell-content-wrapper">
|
|
370
|
-
<SingleSelectionCheckbox
|
|
371
|
-
id={
|
|
372
|
-
getItemId( item ) || index
|
|
373
|
-
}
|
|
374
|
-
item={ item }
|
|
375
|
-
selection={ selection }
|
|
376
|
-
onSelectionChange={
|
|
377
|
-
onSelectionChange
|
|
378
|
-
}
|
|
379
|
-
getItemId={ getItemId }
|
|
380
|
-
data={ data }
|
|
381
|
-
primaryField={ primaryField }
|
|
382
|
-
/>
|
|
383
|
-
</div>
|
|
384
|
-
</td>
|
|
385
|
-
) }
|
|
386
|
-
{ visibleFields.map( ( field ) => (
|
|
387
|
-
<td
|
|
388
|
-
key={ field.id }
|
|
389
|
-
style={ {
|
|
390
|
-
width: field.width || undefined,
|
|
391
|
-
minWidth:
|
|
392
|
-
field.minWidth || undefined,
|
|
393
|
-
maxWidth:
|
|
394
|
-
field.maxWidth || undefined,
|
|
395
|
-
} }
|
|
396
|
-
>
|
|
397
|
-
<div
|
|
398
|
-
className={ classnames(
|
|
399
|
-
'dataviews-view-table__cell-content-wrapper',
|
|
400
|
-
{
|
|
401
|
-
'dataviews-view-table__primary-field':
|
|
402
|
-
primaryField?.id ===
|
|
403
|
-
field.id,
|
|
404
|
-
}
|
|
405
|
-
) }
|
|
406
|
-
>
|
|
407
|
-
{ field.render( {
|
|
408
|
-
item,
|
|
409
|
-
} ) }
|
|
410
|
-
</div>
|
|
411
|
-
</td>
|
|
412
|
-
) ) }
|
|
413
|
-
{ !! actions?.length && (
|
|
414
|
-
<td className="dataviews-view-table__actions-column">
|
|
415
|
-
<ItemActions
|
|
416
|
-
item={ item }
|
|
417
|
-
actions={ actions }
|
|
418
|
-
/>
|
|
419
|
-
</td>
|
|
420
|
-
) }
|
|
421
|
-
</tr>
|
|
492
|
+
item={ item }
|
|
493
|
+
hasBulkActions={ hasBulkActions }
|
|
494
|
+
actions={ actions }
|
|
495
|
+
id={ getItemId( item ) || index }
|
|
496
|
+
visibleFields={ visibleFields }
|
|
497
|
+
primaryField={ primaryField }
|
|
498
|
+
selection={ selection }
|
|
499
|
+
getItemId={ getItemId }
|
|
500
|
+
onSelectionChange={ onSelectionChange }
|
|
501
|
+
data={ data }
|
|
502
|
+
/>
|
|
422
503
|
) ) }
|
|
423
504
|
</tbody>
|
|
424
505
|
</table>
|
|
@@ -430,10 +511,10 @@ function ViewTable( {
|
|
|
430
511
|
id={ tableNoticeId }
|
|
431
512
|
>
|
|
432
513
|
{ ! hasData && (
|
|
433
|
-
<p>{ isLoading ?
|
|
514
|
+
<p>{ isLoading ? <Spinner /> : __( 'No results' ) }</p>
|
|
434
515
|
) }
|
|
435
516
|
</div>
|
|
436
|
-
|
|
517
|
+
</>
|
|
437
518
|
);
|
|
438
519
|
}
|
|
439
520
|
|