@wordpress/dataviews 0.3.0 → 0.4.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 +2 -0
- package/build/bulk-actions.js +143 -0
- package/build/bulk-actions.js.map +1 -0
- package/build/dataviews.js +15 -1
- package/build/dataviews.js.map +1 -1
- package/build/item-actions.js +4 -4
- package/build/item-actions.js.map +1 -1
- package/build/pagination.js +2 -2
- package/build/pagination.js.map +1 -1
- package/build/view-actions.js +3 -2
- package/build/view-actions.js.map +1 -1
- package/build/view-grid.js +11 -8
- package/build/view-grid.js.map +1 -1
- package/build/view-list.js +13 -1
- package/build/view-list.js.map +1 -1
- package/build/view-table.js +116 -9
- package/build/view-table.js.map +1 -1
- package/build-module/bulk-actions.js +136 -0
- package/build-module/bulk-actions.js.map +1 -0
- package/build-module/dataviews.js +17 -3
- package/build-module/dataviews.js.map +1 -1
- package/build-module/item-actions.js +4 -4
- package/build-module/item-actions.js.map +1 -1
- package/build-module/pagination.js +2 -2
- package/build-module/pagination.js.map +1 -1
- package/build-module/view-actions.js +4 -3
- package/build-module/view-actions.js.map +1 -1
- package/build-module/view-grid.js +12 -9
- package/build-module/view-grid.js.map +1 -1
- package/build-module/view-list.js +13 -1
- package/build-module/view-list.js.map +1 -1
- package/build-module/view-table.js +120 -13
- package/build-module/view-table.js.map +1 -1
- package/build-style/style-rtl.css +143 -26
- package/build-style/style.css +143 -26
- package/package.json +11 -11
- package/src/bulk-actions.js +187 -0
- package/src/dataviews.js +29 -2
- package/src/item-actions.js +4 -7
- package/src/pagination.js +2 -6
- package/src/style.scss +152 -29
- package/src/view-actions.js +8 -14
- package/src/view-grid.js +14 -12
- package/src/view-list.js +20 -1
- package/src/view-table.js +161 -15
package/build-style/style.css
CHANGED
|
@@ -97,7 +97,7 @@
|
|
|
97
97
|
--wp-block-synced-color: #7a00df;
|
|
98
98
|
--wp-block-synced-color--rgb: 122, 0, 223;
|
|
99
99
|
}
|
|
100
|
-
@media (
|
|
100
|
+
@media (min-resolution: 192dpi) {
|
|
101
101
|
:root {
|
|
102
102
|
--wp-admin-border-width-focus: 1.5px;
|
|
103
103
|
}
|
|
@@ -122,6 +122,10 @@
|
|
|
122
122
|
max-width: 240px;
|
|
123
123
|
}
|
|
124
124
|
|
|
125
|
+
.dataviews-filters__view-actions.components-h-stack {
|
|
126
|
+
align-items: center;
|
|
127
|
+
}
|
|
128
|
+
|
|
125
129
|
.dataviews-filters-button {
|
|
126
130
|
position: relative;
|
|
127
131
|
}
|
|
@@ -160,6 +164,10 @@
|
|
|
160
164
|
margin: 32px 0 16px;
|
|
161
165
|
}
|
|
162
166
|
|
|
167
|
+
.dataviews-view-table-wrapper {
|
|
168
|
+
overflow-x: auto;
|
|
169
|
+
}
|
|
170
|
+
|
|
163
171
|
.dataviews-view-table {
|
|
164
172
|
width: 100%;
|
|
165
173
|
text-indent: 0;
|
|
@@ -182,12 +190,26 @@
|
|
|
182
190
|
.dataviews-view-table td,
|
|
183
191
|
.dataviews-view-table th {
|
|
184
192
|
padding: 12px;
|
|
185
|
-
|
|
193
|
+
white-space: nowrap;
|
|
194
|
+
}
|
|
195
|
+
@media (min-width: 1440px) {
|
|
196
|
+
.dataviews-view-table td,
|
|
197
|
+
.dataviews-view-table th {
|
|
198
|
+
min-width: 200px;
|
|
199
|
+
}
|
|
186
200
|
}
|
|
187
201
|
.dataviews-view-table td[data-field-id=actions],
|
|
188
202
|
.dataviews-view-table th[data-field-id=actions] {
|
|
189
203
|
text-align: right;
|
|
190
204
|
}
|
|
205
|
+
.dataviews-view-table td.dataviews-view-table__checkbox-column,
|
|
206
|
+
.dataviews-view-table th.dataviews-view-table__checkbox-column {
|
|
207
|
+
padding-right: 0;
|
|
208
|
+
}
|
|
209
|
+
.dataviews-view-table td .components-checkbox-control__input-container,
|
|
210
|
+
.dataviews-view-table th .components-checkbox-control__input-container {
|
|
211
|
+
margin: 4px;
|
|
212
|
+
}
|
|
191
213
|
.dataviews-view-table tr {
|
|
192
214
|
border-bottom: 1px solid #f0f0f0;
|
|
193
215
|
}
|
|
@@ -211,9 +233,25 @@
|
|
|
211
233
|
.dataviews-view-table tr:last-child {
|
|
212
234
|
border-bottom: 0;
|
|
213
235
|
}
|
|
214
|
-
.dataviews-view-table tr:hover
|
|
236
|
+
.dataviews-view-table tr:hover {
|
|
215
237
|
background-color: #f8f8f8;
|
|
216
238
|
}
|
|
239
|
+
.dataviews-view-table tr .components-checkbox-control__input {
|
|
240
|
+
opacity: 0;
|
|
241
|
+
}
|
|
242
|
+
.dataviews-view-table tr .components-checkbox-control__input:checked, .dataviews-view-table tr .components-checkbox-control__input:indeterminate, .dataviews-view-table tr .components-checkbox-control__input:focus {
|
|
243
|
+
opacity: 1;
|
|
244
|
+
}
|
|
245
|
+
.dataviews-view-table tr:focus-within .components-checkbox-control__input, .dataviews-view-table tr:hover .components-checkbox-control__input {
|
|
246
|
+
opacity: 1;
|
|
247
|
+
}
|
|
248
|
+
.dataviews-view-table tr.is-selected {
|
|
249
|
+
background-color: rgba(var(--wp-admin-theme-color--rgb), 0.04);
|
|
250
|
+
color: #757575;
|
|
251
|
+
}
|
|
252
|
+
.dataviews-view-table tr.is-selected:hover {
|
|
253
|
+
background-color: rgba(var(--wp-admin-theme-color--rgb), 0.08);
|
|
254
|
+
}
|
|
217
255
|
.dataviews-view-table thead tr {
|
|
218
256
|
border: 0;
|
|
219
257
|
}
|
|
@@ -230,6 +268,14 @@
|
|
|
230
268
|
font-weight: 500;
|
|
231
269
|
padding-left: 4px;
|
|
232
270
|
}
|
|
271
|
+
.dataviews-view-table tbody td {
|
|
272
|
+
vertical-align: top;
|
|
273
|
+
}
|
|
274
|
+
.dataviews-view-table tbody .dataviews-view-table__cell-content-wrapper {
|
|
275
|
+
min-height: 32px;
|
|
276
|
+
display: flex;
|
|
277
|
+
align-items: center;
|
|
278
|
+
}
|
|
233
279
|
.dataviews-view-table .dataviews-view-table-header-button {
|
|
234
280
|
padding: 4px 8px;
|
|
235
281
|
font-size: 11px;
|
|
@@ -248,6 +294,50 @@
|
|
|
248
294
|
.dataviews-view-table .dataviews-view-table-header {
|
|
249
295
|
padding-left: 4px;
|
|
250
296
|
}
|
|
297
|
+
.dataviews-view-table .dataviews-view-table__actions-column {
|
|
298
|
+
width: 1%;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
.dataviews-view-list__primary-field,
|
|
302
|
+
.dataviews-view-grid__primary-field,
|
|
303
|
+
.dataviews-view-table__primary-field {
|
|
304
|
+
font-size: 13px;
|
|
305
|
+
font-weight: 500;
|
|
306
|
+
color: #1e1e1e;
|
|
307
|
+
text-overflow: ellipsis;
|
|
308
|
+
white-space: nowrap;
|
|
309
|
+
overflow: hidden;
|
|
310
|
+
display: block;
|
|
311
|
+
width: 100%;
|
|
312
|
+
}
|
|
313
|
+
.dataviews-view-list__primary-field a,
|
|
314
|
+
.dataviews-view-grid__primary-field a,
|
|
315
|
+
.dataviews-view-table__primary-field a {
|
|
316
|
+
text-decoration: none;
|
|
317
|
+
color: inherit;
|
|
318
|
+
text-overflow: ellipsis;
|
|
319
|
+
white-space: nowrap;
|
|
320
|
+
overflow: hidden;
|
|
321
|
+
display: block;
|
|
322
|
+
width: 100%;
|
|
323
|
+
}
|
|
324
|
+
.dataviews-view-list__primary-field a:hover,
|
|
325
|
+
.dataviews-view-grid__primary-field a:hover,
|
|
326
|
+
.dataviews-view-table__primary-field a:hover {
|
|
327
|
+
color: #1e1e1e;
|
|
328
|
+
}
|
|
329
|
+
.dataviews-view-list__primary-field button.components-button.is-link,
|
|
330
|
+
.dataviews-view-grid__primary-field button.components-button.is-link,
|
|
331
|
+
.dataviews-view-table__primary-field button.components-button.is-link {
|
|
332
|
+
text-decoration: none;
|
|
333
|
+
color: inherit;
|
|
334
|
+
font-weight: inherit;
|
|
335
|
+
text-overflow: ellipsis;
|
|
336
|
+
white-space: nowrap;
|
|
337
|
+
overflow: hidden;
|
|
338
|
+
display: block;
|
|
339
|
+
width: 100%;
|
|
340
|
+
}
|
|
251
341
|
|
|
252
342
|
.dataviews-view-grid {
|
|
253
343
|
margin-bottom: 24px;
|
|
@@ -264,47 +354,45 @@
|
|
|
264
354
|
grid-template-columns: repeat(4, minmax(0, 1fr)) !important;
|
|
265
355
|
}
|
|
266
356
|
}
|
|
267
|
-
.dataviews-view-grid .dataviews-view-grid__card
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
font-size: 13px;
|
|
273
|
-
width: 100%;
|
|
357
|
+
.dataviews-view-grid .dataviews-view-grid__card {
|
|
358
|
+
border-radius: 4px;
|
|
359
|
+
border: 1px solid #e0e0e0;
|
|
360
|
+
height: 100%;
|
|
361
|
+
justify-content: flex-start;
|
|
274
362
|
}
|
|
275
|
-
.dataviews-view-grid .dataviews-view-grid__card .dataviews-view-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
363
|
+
.dataviews-view-grid .dataviews-view-grid__card .dataviews-view-grid__title-actions {
|
|
364
|
+
padding: 0 4px;
|
|
365
|
+
}
|
|
366
|
+
.dataviews-view-grid .dataviews-view-grid__card .dataviews-view-grid__primary-field {
|
|
367
|
+
min-height: 40px;
|
|
280
368
|
}
|
|
281
369
|
.dataviews-view-grid .dataviews-view-grid__media {
|
|
282
370
|
width: 100%;
|
|
283
371
|
min-height: 200px;
|
|
284
372
|
aspect-ratio: 1/1;
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
373
|
+
border-bottom: 1px solid #e0e0e0;
|
|
374
|
+
background-color: #f0f0f0;
|
|
375
|
+
border-radius: 3px 3px 0 0;
|
|
288
376
|
}
|
|
289
|
-
.dataviews-view-grid .dataviews-view-grid__media
|
|
290
|
-
|
|
291
|
-
object-fit: cover;
|
|
377
|
+
.dataviews-view-grid .dataviews-view-grid__media img {
|
|
378
|
+
object-fit: cover;
|
|
292
379
|
width: 100%;
|
|
293
380
|
height: 100%;
|
|
294
381
|
}
|
|
295
382
|
.dataviews-view-grid .dataviews-view-grid__primary-field {
|
|
296
|
-
|
|
383
|
+
padding: 8px;
|
|
297
384
|
}
|
|
298
385
|
.dataviews-view-grid .dataviews-view-grid__fields {
|
|
299
386
|
position: relative;
|
|
300
387
|
font-size: 12px;
|
|
301
388
|
line-height: 16px;
|
|
302
389
|
}
|
|
303
|
-
.dataviews-view-grid .dataviews-view-grid__fields
|
|
304
|
-
|
|
390
|
+
.dataviews-view-grid .dataviews-view-grid__fields:not(:empty) {
|
|
391
|
+
padding: 12px;
|
|
392
|
+
padding-top: 0;
|
|
305
393
|
}
|
|
306
394
|
.dataviews-view-grid .dataviews-view-grid__fields .dataviews-view-grid__field .dataviews-view-grid__field-value {
|
|
307
|
-
color: #
|
|
395
|
+
color: #757575;
|
|
308
396
|
}
|
|
309
397
|
|
|
310
398
|
.dataviews-view-list {
|
|
@@ -331,6 +419,7 @@
|
|
|
331
419
|
.dataviews-view-list li:not(.is-selected):hover {
|
|
332
420
|
color: var(--wp-admin-theme-color);
|
|
333
421
|
}
|
|
422
|
+
.dataviews-view-list li:not(.is-selected):hover .dataviews-view-list__primary-field,
|
|
334
423
|
.dataviews-view-list li:not(.is-selected):hover .dataviews-view-list__fields {
|
|
335
424
|
color: var(--wp-admin-theme-color);
|
|
336
425
|
}
|
|
@@ -339,8 +428,10 @@
|
|
|
339
428
|
background-color: var(--wp-admin-theme-color);
|
|
340
429
|
color: #fff;
|
|
341
430
|
}
|
|
431
|
+
.dataviews-view-list li.is-selected .dataviews-view-list__item-wrapper .dataviews-view-list__primary-field,
|
|
342
432
|
.dataviews-view-list li.is-selected .dataviews-view-list__item-wrapper .dataviews-view-list__fields,
|
|
343
433
|
.dataviews-view-list li.is-selected .dataviews-view-list__item-wrapper .components-button,
|
|
434
|
+
.dataviews-view-list li.is-selected:focus-within .dataviews-view-list__item-wrapper .dataviews-view-list__primary-field,
|
|
344
435
|
.dataviews-view-list li.is-selected:focus-within .dataviews-view-list__item-wrapper .dataviews-view-list__fields,
|
|
345
436
|
.dataviews-view-list li.is-selected:focus-within .dataviews-view-list__item-wrapper .components-button {
|
|
346
437
|
color: #fff;
|
|
@@ -371,11 +462,18 @@
|
|
|
371
462
|
white-space: nowrap;
|
|
372
463
|
}
|
|
373
464
|
.dataviews-view-list .dataviews-view-list__media-wrapper {
|
|
374
|
-
|
|
465
|
+
width: 32px;
|
|
375
466
|
height: 32px;
|
|
376
467
|
border-radius: 4px;
|
|
377
468
|
overflow: hidden;
|
|
378
469
|
position: relative;
|
|
470
|
+
flex-shrink: 0;
|
|
471
|
+
background-color: #f0f0f0;
|
|
472
|
+
}
|
|
473
|
+
.dataviews-view-list .dataviews-view-list__media-wrapper img {
|
|
474
|
+
width: 100%;
|
|
475
|
+
height: 100%;
|
|
476
|
+
object-fit: cover;
|
|
379
477
|
}
|
|
380
478
|
.dataviews-view-list .dataviews-view-list__media-wrapper::after {
|
|
381
479
|
content: "";
|
|
@@ -404,6 +502,9 @@
|
|
|
404
502
|
.dataviews-view-list .dataviews-view-list__fields .dataviews-view-list__field:last-child {
|
|
405
503
|
margin-right: 0;
|
|
406
504
|
}
|
|
505
|
+
.dataviews-view-list .dataviews-view-list__fields .dataviews-view-list__field:empty {
|
|
506
|
+
display: none;
|
|
507
|
+
}
|
|
407
508
|
.dataviews-view-list + .dataviews-pagination {
|
|
408
509
|
justify-content: space-between;
|
|
409
510
|
}
|
|
@@ -429,7 +530,23 @@
|
|
|
429
530
|
padding: 0 32px;
|
|
430
531
|
}
|
|
431
532
|
|
|
533
|
+
.dataviews-view-table-selection-checkbox label {
|
|
534
|
+
position: absolute;
|
|
535
|
+
width: 1px;
|
|
536
|
+
height: 1px;
|
|
537
|
+
padding: 0;
|
|
538
|
+
margin: -1px;
|
|
539
|
+
overflow: hidden;
|
|
540
|
+
clip: rect(0, 0, 0, 0);
|
|
541
|
+
white-space: nowrap;
|
|
542
|
+
border: 0;
|
|
543
|
+
}
|
|
544
|
+
|
|
432
545
|
.dataviews-filters__custom-menu-radio-item-prefix {
|
|
433
546
|
display: block;
|
|
434
547
|
width: 24px;
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
.dataviews-bulk-edit-button.components-button {
|
|
551
|
+
flex-shrink: 0;
|
|
435
552
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wordpress/dataviews",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "DataViews is a component that provides an API to render datasets using different types of layouts (table, grid, list, etc.).",
|
|
5
5
|
"author": "The WordPress Contributors",
|
|
6
6
|
"license": "GPL-2.0-or-later",
|
|
@@ -28,15 +28,15 @@
|
|
|
28
28
|
"sideEffects": false,
|
|
29
29
|
"dependencies": {
|
|
30
30
|
"@babel/runtime": "^7.16.0",
|
|
31
|
-
"@wordpress/a11y": "^3.
|
|
32
|
-
"@wordpress/components": "^25.
|
|
33
|
-
"@wordpress/compose": "^6.
|
|
34
|
-
"@wordpress/element": "^5.
|
|
35
|
-
"@wordpress/i18n": "^4.
|
|
36
|
-
"@wordpress/icons": "^9.
|
|
37
|
-
"@wordpress/keycodes": "^3.
|
|
38
|
-
"@wordpress/primitives": "^3.
|
|
39
|
-
"@wordpress/private-apis": "^0.
|
|
31
|
+
"@wordpress/a11y": "^3.50.0",
|
|
32
|
+
"@wordpress/components": "^25.16.0",
|
|
33
|
+
"@wordpress/compose": "^6.27.0",
|
|
34
|
+
"@wordpress/element": "^5.27.0",
|
|
35
|
+
"@wordpress/i18n": "^4.50.0",
|
|
36
|
+
"@wordpress/icons": "^9.41.0",
|
|
37
|
+
"@wordpress/keycodes": "^3.50.0",
|
|
38
|
+
"@wordpress/primitives": "^3.48.0",
|
|
39
|
+
"@wordpress/private-apis": "^0.32.0",
|
|
40
40
|
"classnames": "^2.3.1",
|
|
41
41
|
"remove-accents": "^0.5.0"
|
|
42
42
|
},
|
|
@@ -46,5 +46,5 @@
|
|
|
46
46
|
"publishConfig": {
|
|
47
47
|
"access": "public"
|
|
48
48
|
},
|
|
49
|
-
"gitHead": "
|
|
49
|
+
"gitHead": "45de2cb4212fed7f2763e95f10300d1ff9d0ec08"
|
|
50
50
|
}
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WordPress dependencies
|
|
3
|
+
*/
|
|
4
|
+
import {
|
|
5
|
+
privateApis as componentsPrivateApis,
|
|
6
|
+
Button,
|
|
7
|
+
Modal,
|
|
8
|
+
} from '@wordpress/components';
|
|
9
|
+
import { __, sprintf, _n } from '@wordpress/i18n';
|
|
10
|
+
import { useMemo, useState, useCallback } from '@wordpress/element';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Internal dependencies
|
|
14
|
+
*/
|
|
15
|
+
import { unlock } from './lock-unlock';
|
|
16
|
+
|
|
17
|
+
const {
|
|
18
|
+
DropdownMenuV2: DropdownMenu,
|
|
19
|
+
DropdownMenuGroupV2: DropdownMenuGroup,
|
|
20
|
+
DropdownMenuItemV2: DropdownMenuItem,
|
|
21
|
+
DropdownMenuSeparatorV2: DropdownMenuSeparator,
|
|
22
|
+
} = unlock( componentsPrivateApis );
|
|
23
|
+
|
|
24
|
+
function ActionWithModal( {
|
|
25
|
+
action,
|
|
26
|
+
selectedItems,
|
|
27
|
+
setActionWithModal,
|
|
28
|
+
onMenuOpenChange,
|
|
29
|
+
} ) {
|
|
30
|
+
const eligibleItems = useMemo( () => {
|
|
31
|
+
return selectedItems.filter( ( item ) => action.isEligible( item ) );
|
|
32
|
+
}, [ action, selectedItems ] );
|
|
33
|
+
const { RenderModal, hideModalHeader } = action;
|
|
34
|
+
const onCloseModal = useCallback( () => {
|
|
35
|
+
setActionWithModal( undefined );
|
|
36
|
+
}, [ setActionWithModal ] );
|
|
37
|
+
return (
|
|
38
|
+
<Modal
|
|
39
|
+
title={ ! hideModalHeader && action.label }
|
|
40
|
+
__experimentalHideHeader={ !! hideModalHeader }
|
|
41
|
+
onRequestClose={ onCloseModal }
|
|
42
|
+
overlayClassName="dataviews-action-modal"
|
|
43
|
+
>
|
|
44
|
+
<RenderModal
|
|
45
|
+
items={ eligibleItems }
|
|
46
|
+
closeModal={ onCloseModal }
|
|
47
|
+
onPerform={ () => onMenuOpenChange( false ) }
|
|
48
|
+
/>
|
|
49
|
+
</Modal>
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function BulkActionItem( { action, selectedItems, setActionWithModal } ) {
|
|
54
|
+
const eligibleItems = useMemo( () => {
|
|
55
|
+
return selectedItems.filter( ( item ) => action.isEligible( item ) );
|
|
56
|
+
}, [ action, selectedItems ] );
|
|
57
|
+
|
|
58
|
+
const shouldShowModal = !! action.RenderModal;
|
|
59
|
+
|
|
60
|
+
return (
|
|
61
|
+
<DropdownMenuItem
|
|
62
|
+
key={ action.id }
|
|
63
|
+
disabled={ eligibleItems.length === 0 }
|
|
64
|
+
hideOnClick={ ! shouldShowModal }
|
|
65
|
+
onClick={ async () => {
|
|
66
|
+
if ( shouldShowModal ) {
|
|
67
|
+
setActionWithModal( action );
|
|
68
|
+
} else {
|
|
69
|
+
await action.callback( eligibleItems );
|
|
70
|
+
}
|
|
71
|
+
} }
|
|
72
|
+
suffix={
|
|
73
|
+
eligibleItems.length > 0 ? eligibleItems.length : undefined
|
|
74
|
+
}
|
|
75
|
+
>
|
|
76
|
+
{ action.label }
|
|
77
|
+
</DropdownMenuItem>
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function ActionsMenuGroup( { actions, selectedItems, setActionWithModal } ) {
|
|
82
|
+
return (
|
|
83
|
+
<>
|
|
84
|
+
<DropdownMenuGroup>
|
|
85
|
+
{ actions.map( ( action ) => (
|
|
86
|
+
<BulkActionItem
|
|
87
|
+
key={ action.id }
|
|
88
|
+
action={ action }
|
|
89
|
+
selectedItems={ selectedItems }
|
|
90
|
+
setActionWithModal={ setActionWithModal }
|
|
91
|
+
/>
|
|
92
|
+
) ) }
|
|
93
|
+
</DropdownMenuGroup>
|
|
94
|
+
<DropdownMenuSeparator />
|
|
95
|
+
</>
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export default function BulkActions( {
|
|
100
|
+
data,
|
|
101
|
+
actions,
|
|
102
|
+
selection,
|
|
103
|
+
onSelectionChange,
|
|
104
|
+
getItemId,
|
|
105
|
+
} ) {
|
|
106
|
+
const bulkActions = useMemo(
|
|
107
|
+
() => actions.filter( ( action ) => action.supportsBulk ),
|
|
108
|
+
[ actions ]
|
|
109
|
+
);
|
|
110
|
+
const areAllSelected = selection && selection.length === data.length;
|
|
111
|
+
const [ isMenuOpen, onMenuOpenChange ] = useState( false );
|
|
112
|
+
const [ actionWithModal, setActionWithModal ] = useState();
|
|
113
|
+
const selectedItems = useMemo( () => {
|
|
114
|
+
return data.filter( ( item ) =>
|
|
115
|
+
selection.includes( getItemId( item ) )
|
|
116
|
+
);
|
|
117
|
+
}, [ selection, data, getItemId ] );
|
|
118
|
+
|
|
119
|
+
if ( bulkActions.length === 0 ) {
|
|
120
|
+
return null;
|
|
121
|
+
}
|
|
122
|
+
return (
|
|
123
|
+
<>
|
|
124
|
+
<DropdownMenu
|
|
125
|
+
open={ isMenuOpen }
|
|
126
|
+
onOpenChange={ onMenuOpenChange }
|
|
127
|
+
label={ __( 'Bulk actions' ) }
|
|
128
|
+
style={ { minWidth: '240px' } }
|
|
129
|
+
trigger={
|
|
130
|
+
<Button
|
|
131
|
+
className="dataviews-bulk-edit-button"
|
|
132
|
+
__next40pxDefaultSize
|
|
133
|
+
variant="tertiary"
|
|
134
|
+
size="compact"
|
|
135
|
+
>
|
|
136
|
+
{ selection.length
|
|
137
|
+
? sprintf(
|
|
138
|
+
/* translators: %d: Number of items. */
|
|
139
|
+
_n(
|
|
140
|
+
'Edit %d item',
|
|
141
|
+
'Edit %d items',
|
|
142
|
+
selection.length
|
|
143
|
+
),
|
|
144
|
+
selection.length
|
|
145
|
+
)
|
|
146
|
+
: __( 'Bulk edit' ) }
|
|
147
|
+
</Button>
|
|
148
|
+
}
|
|
149
|
+
>
|
|
150
|
+
<ActionsMenuGroup
|
|
151
|
+
actions={ bulkActions }
|
|
152
|
+
setActionWithModal={ setActionWithModal }
|
|
153
|
+
selectedItems={ selectedItems }
|
|
154
|
+
/>
|
|
155
|
+
<DropdownMenuGroup>
|
|
156
|
+
<DropdownMenuItem
|
|
157
|
+
disabled={ areAllSelected }
|
|
158
|
+
hideOnClick={ false }
|
|
159
|
+
onClick={ () => {
|
|
160
|
+
onSelectionChange( data );
|
|
161
|
+
} }
|
|
162
|
+
suffix={ data.length }
|
|
163
|
+
>
|
|
164
|
+
{ __( 'Select all' ) }
|
|
165
|
+
</DropdownMenuItem>
|
|
166
|
+
<DropdownMenuItem
|
|
167
|
+
disabled={ selection.length === 0 }
|
|
168
|
+
hideOnClick={ false }
|
|
169
|
+
onClick={ () => {
|
|
170
|
+
onSelectionChange( [] );
|
|
171
|
+
} }
|
|
172
|
+
>
|
|
173
|
+
{ __( 'Deselect' ) }
|
|
174
|
+
</DropdownMenuItem>
|
|
175
|
+
</DropdownMenuGroup>
|
|
176
|
+
</DropdownMenu>
|
|
177
|
+
{ actionWithModal && (
|
|
178
|
+
<ActionWithModal
|
|
179
|
+
action={ actionWithModal }
|
|
180
|
+
selectedItems={ selectedItems }
|
|
181
|
+
setActionWithModal={ setActionWithModal }
|
|
182
|
+
onMenuOpenChange={ onMenuOpenChange }
|
|
183
|
+
/>
|
|
184
|
+
) }
|
|
185
|
+
</>
|
|
186
|
+
);
|
|
187
|
+
}
|
package/src/dataviews.js
CHANGED
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
__experimentalVStack as VStack,
|
|
6
6
|
__experimentalHStack as HStack,
|
|
7
7
|
} from '@wordpress/components';
|
|
8
|
-
import { useMemo, useState, useCallback } from '@wordpress/element';
|
|
8
|
+
import { useMemo, useState, useCallback, useEffect } from '@wordpress/element';
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* Internal dependencies
|
|
@@ -14,7 +14,8 @@ import Pagination from './pagination';
|
|
|
14
14
|
import ViewActions from './view-actions';
|
|
15
15
|
import Filters from './filters';
|
|
16
16
|
import Search from './search';
|
|
17
|
-
import { VIEW_LAYOUTS } from './constants';
|
|
17
|
+
import { VIEW_LAYOUTS, LAYOUT_TABLE } from './constants';
|
|
18
|
+
import BulkActions from './bulk-actions';
|
|
18
19
|
|
|
19
20
|
const defaultGetItemId = ( item ) => item.id;
|
|
20
21
|
const defaultOnSelectionChange = () => {};
|
|
@@ -37,6 +38,23 @@ export default function DataViews( {
|
|
|
37
38
|
} ) {
|
|
38
39
|
const [ selection, setSelection ] = useState( [] );
|
|
39
40
|
|
|
41
|
+
useEffect( () => {
|
|
42
|
+
if (
|
|
43
|
+
selection.length > 0 &&
|
|
44
|
+
selection.some(
|
|
45
|
+
( id ) => ! data.some( ( item ) => item.id === id )
|
|
46
|
+
)
|
|
47
|
+
) {
|
|
48
|
+
const newSelection = selection.filter( ( id ) =>
|
|
49
|
+
data.some( ( item ) => item.id === id )
|
|
50
|
+
);
|
|
51
|
+
setSelection( newSelection );
|
|
52
|
+
onSelectionChange(
|
|
53
|
+
data.filter( ( item ) => newSelection.includes( item.id ) )
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
}, [ selection, data, onSelectionChange ] );
|
|
57
|
+
|
|
40
58
|
const onSetSelection = useCallback(
|
|
41
59
|
( items ) => {
|
|
42
60
|
setSelection( items.map( ( item ) => item.id ) );
|
|
@@ -75,6 +93,15 @@ export default function DataViews( {
|
|
|
75
93
|
onChangeView={ onChangeView }
|
|
76
94
|
/>
|
|
77
95
|
</HStack>
|
|
96
|
+
{ view.type === LAYOUT_TABLE && (
|
|
97
|
+
<BulkActions
|
|
98
|
+
actions={ actions }
|
|
99
|
+
data={ data }
|
|
100
|
+
onSelectionChange={ onSetSelection }
|
|
101
|
+
selection={ selection }
|
|
102
|
+
getItemId={ getItemId }
|
|
103
|
+
/>
|
|
104
|
+
) }
|
|
78
105
|
<ViewActions
|
|
79
106
|
fields={ _fields }
|
|
80
107
|
view={ view }
|
package/src/item-actions.js
CHANGED
|
@@ -59,10 +59,7 @@ function ActionWithModal( { action, item, ActionTrigger } ) {
|
|
|
59
59
|
<ActionTrigger { ...actionTriggerProps } />
|
|
60
60
|
{ isModalOpen && (
|
|
61
61
|
<Modal
|
|
62
|
-
title={
|
|
63
|
-
( ! hideModalHeader && action.modalHeader ) ||
|
|
64
|
-
action.label
|
|
65
|
-
}
|
|
62
|
+
title={ action.modalHeader || action.label }
|
|
66
63
|
__experimentalHideHeader={ !! hideModalHeader }
|
|
67
64
|
onRequestClose={ () => {
|
|
68
65
|
setIsModalOpen( false );
|
|
@@ -72,7 +69,7 @@ function ActionWithModal( { action, item, ActionTrigger } ) {
|
|
|
72
69
|
) }` }
|
|
73
70
|
>
|
|
74
71
|
<RenderModal
|
|
75
|
-
|
|
72
|
+
items={ [ item ] }
|
|
76
73
|
closeModal={ () => setIsModalOpen( false ) }
|
|
77
74
|
/>
|
|
78
75
|
</Modal>
|
|
@@ -99,7 +96,7 @@ function ActionsDropdownMenuGroup( { actions, item } ) {
|
|
|
99
96
|
<DropdownMenuItemTrigger
|
|
100
97
|
key={ action.id }
|
|
101
98
|
action={ action }
|
|
102
|
-
onClick={ () => action.callback( item ) }
|
|
99
|
+
onClick={ () => action.callback( [ item ] ) }
|
|
103
100
|
/>
|
|
104
101
|
);
|
|
105
102
|
} ) }
|
|
@@ -160,7 +157,7 @@ export default function ItemActions( { item, actions, isCompact } ) {
|
|
|
160
157
|
<ButtonTrigger
|
|
161
158
|
key={ action.id }
|
|
162
159
|
action={ action }
|
|
163
|
-
onClick={ () => action.callback( item ) }
|
|
160
|
+
onClick={ () => action.callback( [ item ] ) }
|
|
164
161
|
/>
|
|
165
162
|
);
|
|
166
163
|
} ) }
|
package/src/pagination.js
CHANGED
|
@@ -30,12 +30,8 @@ const Pagination = memo( function Pagination( {
|
|
|
30
30
|
<HStack justify="flex-start" expanded={ false } spacing={ 2 }>
|
|
31
31
|
{ createInterpolateElement(
|
|
32
32
|
sprintf(
|
|
33
|
-
// translators: %
|
|
34
|
-
_x(
|
|
35
|
-
'Page <CurrenPageControl /> of %2$s',
|
|
36
|
-
'paging'
|
|
37
|
-
),
|
|
38
|
-
view.page,
|
|
33
|
+
// translators: %s: Total number of pages.
|
|
34
|
+
_x( 'Page <CurrenPageControl /> of %s', 'paging' ),
|
|
39
35
|
totalPages
|
|
40
36
|
),
|
|
41
37
|
{
|