@wordpress/dataviews 0.3.0 → 0.4.1
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 +147 -26
- package/build-style/style.css +147 -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 +156 -28
- 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,17 @@
|
|
|
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
|
+
}
|
|
279
|
+
.dataviews-view-table tbody .dataviews-view-table__cell-content-wrapper > * {
|
|
280
|
+
flex-grow: 1;
|
|
281
|
+
}
|
|
233
282
|
.dataviews-view-table .dataviews-view-table-header-button {
|
|
234
283
|
padding: 4px 8px;
|
|
235
284
|
font-size: 11px;
|
|
@@ -248,10 +297,55 @@
|
|
|
248
297
|
.dataviews-view-table .dataviews-view-table-header {
|
|
249
298
|
padding-left: 4px;
|
|
250
299
|
}
|
|
300
|
+
.dataviews-view-table .dataviews-view-table__actions-column {
|
|
301
|
+
width: 1%;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
.dataviews-view-list__primary-field,
|
|
305
|
+
.dataviews-view-grid__primary-field,
|
|
306
|
+
.dataviews-view-table__primary-field {
|
|
307
|
+
font-size: 13px;
|
|
308
|
+
font-weight: 500;
|
|
309
|
+
color: #1e1e1e;
|
|
310
|
+
text-overflow: ellipsis;
|
|
311
|
+
white-space: nowrap;
|
|
312
|
+
overflow: hidden;
|
|
313
|
+
display: block;
|
|
314
|
+
width: 100%;
|
|
315
|
+
}
|
|
316
|
+
.dataviews-view-list__primary-field a,
|
|
317
|
+
.dataviews-view-grid__primary-field a,
|
|
318
|
+
.dataviews-view-table__primary-field a {
|
|
319
|
+
text-decoration: none;
|
|
320
|
+
color: inherit;
|
|
321
|
+
text-overflow: ellipsis;
|
|
322
|
+
white-space: nowrap;
|
|
323
|
+
overflow: hidden;
|
|
324
|
+
display: block;
|
|
325
|
+
width: 100%;
|
|
326
|
+
}
|
|
327
|
+
.dataviews-view-list__primary-field a:hover,
|
|
328
|
+
.dataviews-view-grid__primary-field a:hover,
|
|
329
|
+
.dataviews-view-table__primary-field a:hover {
|
|
330
|
+
color: #1e1e1e;
|
|
331
|
+
}
|
|
332
|
+
.dataviews-view-list__primary-field button.components-button.is-link,
|
|
333
|
+
.dataviews-view-grid__primary-field button.components-button.is-link,
|
|
334
|
+
.dataviews-view-table__primary-field button.components-button.is-link {
|
|
335
|
+
text-decoration: none;
|
|
336
|
+
color: inherit;
|
|
337
|
+
font-weight: inherit;
|
|
338
|
+
text-overflow: ellipsis;
|
|
339
|
+
white-space: nowrap;
|
|
340
|
+
overflow: hidden;
|
|
341
|
+
display: block;
|
|
342
|
+
width: 100%;
|
|
343
|
+
}
|
|
251
344
|
|
|
252
345
|
.dataviews-view-grid {
|
|
253
346
|
margin-bottom: 24px;
|
|
254
347
|
grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
|
|
348
|
+
grid-template-rows: max-content;
|
|
255
349
|
padding: 0 32px;
|
|
256
350
|
}
|
|
257
351
|
@media (min-width: 1080px) {
|
|
@@ -264,47 +358,45 @@
|
|
|
264
358
|
grid-template-columns: repeat(4, minmax(0, 1fr)) !important;
|
|
265
359
|
}
|
|
266
360
|
}
|
|
267
|
-
.dataviews-view-grid .dataviews-view-grid__card
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
font-size: 13px;
|
|
273
|
-
width: 100%;
|
|
361
|
+
.dataviews-view-grid .dataviews-view-grid__card {
|
|
362
|
+
border-radius: 4px;
|
|
363
|
+
border: 1px solid #e0e0e0;
|
|
364
|
+
height: 100%;
|
|
365
|
+
justify-content: flex-start;
|
|
274
366
|
}
|
|
275
|
-
.dataviews-view-grid .dataviews-view-grid__card .dataviews-view-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
367
|
+
.dataviews-view-grid .dataviews-view-grid__card .dataviews-view-grid__title-actions {
|
|
368
|
+
padding: 0 4px;
|
|
369
|
+
}
|
|
370
|
+
.dataviews-view-grid .dataviews-view-grid__card .dataviews-view-grid__primary-field {
|
|
371
|
+
min-height: 40px;
|
|
280
372
|
}
|
|
281
373
|
.dataviews-view-grid .dataviews-view-grid__media {
|
|
282
374
|
width: 100%;
|
|
283
375
|
min-height: 200px;
|
|
284
376
|
aspect-ratio: 1/1;
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
377
|
+
border-bottom: 1px solid #e0e0e0;
|
|
378
|
+
background-color: #f0f0f0;
|
|
379
|
+
border-radius: 3px 3px 0 0;
|
|
288
380
|
}
|
|
289
|
-
.dataviews-view-grid .dataviews-view-grid__media
|
|
290
|
-
|
|
291
|
-
object-fit: cover;
|
|
381
|
+
.dataviews-view-grid .dataviews-view-grid__media img {
|
|
382
|
+
object-fit: cover;
|
|
292
383
|
width: 100%;
|
|
293
384
|
height: 100%;
|
|
294
385
|
}
|
|
295
386
|
.dataviews-view-grid .dataviews-view-grid__primary-field {
|
|
296
|
-
|
|
387
|
+
padding: 8px;
|
|
297
388
|
}
|
|
298
389
|
.dataviews-view-grid .dataviews-view-grid__fields {
|
|
299
390
|
position: relative;
|
|
300
391
|
font-size: 12px;
|
|
301
392
|
line-height: 16px;
|
|
302
393
|
}
|
|
303
|
-
.dataviews-view-grid .dataviews-view-grid__fields
|
|
304
|
-
|
|
394
|
+
.dataviews-view-grid .dataviews-view-grid__fields:not(:empty) {
|
|
395
|
+
padding: 12px;
|
|
396
|
+
padding-top: 0;
|
|
305
397
|
}
|
|
306
398
|
.dataviews-view-grid .dataviews-view-grid__fields .dataviews-view-grid__field .dataviews-view-grid__field-value {
|
|
307
|
-
color: #
|
|
399
|
+
color: #757575;
|
|
308
400
|
}
|
|
309
401
|
|
|
310
402
|
.dataviews-view-list {
|
|
@@ -331,6 +423,7 @@
|
|
|
331
423
|
.dataviews-view-list li:not(.is-selected):hover {
|
|
332
424
|
color: var(--wp-admin-theme-color);
|
|
333
425
|
}
|
|
426
|
+
.dataviews-view-list li:not(.is-selected):hover .dataviews-view-list__primary-field,
|
|
334
427
|
.dataviews-view-list li:not(.is-selected):hover .dataviews-view-list__fields {
|
|
335
428
|
color: var(--wp-admin-theme-color);
|
|
336
429
|
}
|
|
@@ -339,8 +432,10 @@
|
|
|
339
432
|
background-color: var(--wp-admin-theme-color);
|
|
340
433
|
color: #fff;
|
|
341
434
|
}
|
|
435
|
+
.dataviews-view-list li.is-selected .dataviews-view-list__item-wrapper .dataviews-view-list__primary-field,
|
|
342
436
|
.dataviews-view-list li.is-selected .dataviews-view-list__item-wrapper .dataviews-view-list__fields,
|
|
343
437
|
.dataviews-view-list li.is-selected .dataviews-view-list__item-wrapper .components-button,
|
|
438
|
+
.dataviews-view-list li.is-selected:focus-within .dataviews-view-list__item-wrapper .dataviews-view-list__primary-field,
|
|
344
439
|
.dataviews-view-list li.is-selected:focus-within .dataviews-view-list__item-wrapper .dataviews-view-list__fields,
|
|
345
440
|
.dataviews-view-list li.is-selected:focus-within .dataviews-view-list__item-wrapper .components-button {
|
|
346
441
|
color: #fff;
|
|
@@ -371,11 +466,18 @@
|
|
|
371
466
|
white-space: nowrap;
|
|
372
467
|
}
|
|
373
468
|
.dataviews-view-list .dataviews-view-list__media-wrapper {
|
|
374
|
-
|
|
469
|
+
width: 32px;
|
|
375
470
|
height: 32px;
|
|
376
471
|
border-radius: 4px;
|
|
377
472
|
overflow: hidden;
|
|
378
473
|
position: relative;
|
|
474
|
+
flex-shrink: 0;
|
|
475
|
+
background-color: #f0f0f0;
|
|
476
|
+
}
|
|
477
|
+
.dataviews-view-list .dataviews-view-list__media-wrapper img {
|
|
478
|
+
width: 100%;
|
|
479
|
+
height: 100%;
|
|
480
|
+
object-fit: cover;
|
|
379
481
|
}
|
|
380
482
|
.dataviews-view-list .dataviews-view-list__media-wrapper::after {
|
|
381
483
|
content: "";
|
|
@@ -404,6 +506,9 @@
|
|
|
404
506
|
.dataviews-view-list .dataviews-view-list__fields .dataviews-view-list__field:last-child {
|
|
405
507
|
margin-right: 0;
|
|
406
508
|
}
|
|
509
|
+
.dataviews-view-list .dataviews-view-list__fields .dataviews-view-list__field:empty {
|
|
510
|
+
display: none;
|
|
511
|
+
}
|
|
407
512
|
.dataviews-view-list + .dataviews-pagination {
|
|
408
513
|
justify-content: space-between;
|
|
409
514
|
}
|
|
@@ -429,7 +534,23 @@
|
|
|
429
534
|
padding: 0 32px;
|
|
430
535
|
}
|
|
431
536
|
|
|
537
|
+
.dataviews-view-table-selection-checkbox label {
|
|
538
|
+
position: absolute;
|
|
539
|
+
width: 1px;
|
|
540
|
+
height: 1px;
|
|
541
|
+
padding: 0;
|
|
542
|
+
margin: -1px;
|
|
543
|
+
overflow: hidden;
|
|
544
|
+
clip: rect(0, 0, 0, 0);
|
|
545
|
+
white-space: nowrap;
|
|
546
|
+
border: 0;
|
|
547
|
+
}
|
|
548
|
+
|
|
432
549
|
.dataviews-filters__custom-menu-radio-item-prefix {
|
|
433
550
|
display: block;
|
|
434
551
|
width: 24px;
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
.dataviews-bulk-edit-button.components-button {
|
|
555
|
+
flex-shrink: 0;
|
|
435
556
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wordpress/dataviews",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.1",
|
|
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": "fefb6f718fbfd5df9390f366d5733369f613084a"
|
|
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
|
{
|