@wordpress/dataviews 0.8.0 → 1.0.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 +16 -0
- package/README.md +3 -13
- package/build/add-filter.js.map +1 -1
- package/build/bulk-actions.js.map +1 -1
- package/build/constants.js +1 -4
- package/build/constants.js.map +1 -1
- package/build/dataviews.js +3 -17
- package/build/dataviews.js.map +1 -1
- package/build/dropdown-menu-helper.js.map +1 -1
- package/build/filter-and-sort-data-view.js +147 -0
- package/build/filter-and-sort-data-view.js.map +1 -0
- package/build/filter-summary.js +4 -2
- package/build/filter-summary.js.map +1 -1
- package/build/filters.js +11 -17
- package/build/filters.js.map +1 -1
- package/build/index.js +3 -9
- package/build/index.js.map +1 -1
- package/build/item-actions.js.map +1 -1
- package/build/lock-unlock.js.map +1 -1
- package/build/normalize-fields.js +25 -0
- package/build/normalize-fields.js.map +1 -0
- package/build/pagination.js.map +1 -1
- package/build/reset-filters.js.map +1 -1
- package/build/search-widget.js +5 -4
- package/build/search-widget.js.map +1 -1
- package/build/search.js.map +1 -1
- package/build/single-selection-checkbox.js +1 -1
- package/build/single-selection-checkbox.js.map +1 -1
- package/build/utils.js +1 -65
- package/build/utils.js.map +1 -1
- package/build/view-actions.js.map +1 -1
- package/build/view-grid.js +57 -19
- package/build/view-grid.js.map +1 -1
- package/build/view-list.js +112 -66
- package/build/view-list.js.map +1 -1
- package/build/view-table.js +32 -24
- package/build/view-table.js.map +1 -1
- package/build-module/add-filter.js.map +1 -1
- package/build-module/bulk-actions.js.map +1 -1
- package/build-module/constants.js +0 -3
- package/build-module/constants.js.map +1 -1
- package/build-module/dataviews.js +3 -17
- package/build-module/dataviews.js.map +1 -1
- package/build-module/dropdown-menu-helper.js.map +1 -1
- package/build-module/filter-and-sort-data-view.js +139 -0
- package/build-module/filter-and-sort-data-view.js.map +1 -0
- package/build-module/filter-summary.js +3 -2
- package/build-module/filter-summary.js.map +1 -1
- package/build-module/filters.js +12 -18
- package/build-module/filters.js.map +1 -1
- package/build-module/index.js +1 -1
- package/build-module/index.js.map +1 -1
- package/build-module/item-actions.js.map +1 -1
- package/build-module/lock-unlock.js.map +1 -1
- package/build-module/normalize-fields.js +19 -0
- package/build-module/normalize-fields.js.map +1 -0
- package/build-module/pagination.js.map +1 -1
- package/build-module/reset-filters.js.map +1 -1
- package/build-module/search-widget.js +4 -3
- package/build-module/search-widget.js.map +1 -1
- package/build-module/search.js.map +1 -1
- package/build-module/single-selection-checkbox.js +1 -1
- package/build-module/single-selection-checkbox.js.map +1 -1
- package/build-module/utils.js +0 -63
- package/build-module/utils.js.map +1 -1
- package/build-module/view-actions.js.map +1 -1
- package/build-module/view-grid.js +58 -20
- package/build-module/view-grid.js.map +1 -1
- package/build-module/view-list.js +114 -68
- package/build-module/view-list.js.map +1 -1
- package/build-module/view-table.js +33 -25
- package/build-module/view-table.js.map +1 -1
- package/build-style/style-rtl.css +75 -39
- package/build-style/style.css +75 -39
- package/package.json +11 -11
- package/src/constants.js +0 -3
- package/src/dataviews.js +2 -16
- package/src/filter-and-sort-data-view.js +154 -0
- package/src/filter-summary.js +4 -4
- package/src/filters.js +20 -32
- package/src/index.js +1 -1
- package/src/normalize-fields.js +17 -0
- package/src/search-widget.js +4 -3
- package/src/single-selection-checkbox.js +1 -1
- package/src/stories/fixtures.js +75 -1
- package/src/stories/index.story.js +5 -113
- package/src/style.scss +89 -49
- package/src/test/filter-and-sort-data-view.js +276 -0
- package/src/utils.js +0 -52
- package/src/view-grid.js +97 -36
- package/src/view-list.js +147 -77
- package/src/view-table.js +36 -24
package/src/style.scss
CHANGED
|
@@ -92,10 +92,6 @@
|
|
|
92
92
|
&.dataviews-view-table__checkbox-column {
|
|
93
93
|
padding-right: 0;
|
|
94
94
|
}
|
|
95
|
-
|
|
96
|
-
.components-checkbox-control__input-container {
|
|
97
|
-
margin: $grid-unit-05;
|
|
98
|
-
}
|
|
99
95
|
}
|
|
100
96
|
tr {
|
|
101
97
|
border-bottom: 1px solid $gray-100;
|
|
@@ -150,6 +146,14 @@
|
|
|
150
146
|
}
|
|
151
147
|
}
|
|
152
148
|
|
|
149
|
+
@media (hover: none) {
|
|
150
|
+
// Show checkboxes and quick-actions on devices that do not support hover.
|
|
151
|
+
.components-checkbox-control__input.components-checkbox-control__input,
|
|
152
|
+
.dataviews-item-actions .components-button:not(.dataviews-all-actions-button) {
|
|
153
|
+
opacity: 1;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
153
157
|
&.is-selected {
|
|
154
158
|
background-color: rgba(var(--wp-admin-theme-color--rgb), 0.04);
|
|
155
159
|
color: $gray-700;
|
|
@@ -190,6 +194,12 @@
|
|
|
190
194
|
> * {
|
|
191
195
|
flex-grow: 1;
|
|
192
196
|
}
|
|
197
|
+
|
|
198
|
+
&.dataviews-view-table__primary-field {
|
|
199
|
+
a {
|
|
200
|
+
flex-grow: 0;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
193
203
|
}
|
|
194
204
|
}
|
|
195
205
|
.dataviews-view-table-header-button {
|
|
@@ -231,7 +241,7 @@
|
|
|
231
241
|
.dataviews-view-table__primary-field {
|
|
232
242
|
font-size: $default-font-size;
|
|
233
243
|
font-weight: 500;
|
|
234
|
-
color: $gray-
|
|
244
|
+
color: $gray-700;
|
|
235
245
|
text-overflow: ellipsis;
|
|
236
246
|
white-space: nowrap;
|
|
237
247
|
display: block;
|
|
@@ -239,28 +249,31 @@
|
|
|
239
249
|
|
|
240
250
|
a {
|
|
241
251
|
text-decoration: none;
|
|
242
|
-
color: inherit;
|
|
243
252
|
text-overflow: ellipsis;
|
|
244
253
|
white-space: nowrap;
|
|
245
254
|
overflow: hidden;
|
|
246
255
|
display: block;
|
|
247
|
-
|
|
256
|
+
flex-grow: 0;
|
|
257
|
+
color: $gray-900;
|
|
248
258
|
|
|
249
259
|
&:hover {
|
|
250
|
-
color:
|
|
260
|
+
color: var(--wp-admin-theme-color);
|
|
251
261
|
}
|
|
252
262
|
@include link-reset();
|
|
253
263
|
}
|
|
254
264
|
|
|
255
265
|
button.components-button.is-link {
|
|
256
266
|
text-decoration: none;
|
|
257
|
-
color: inherit;
|
|
258
267
|
font-weight: inherit;
|
|
259
268
|
text-overflow: ellipsis;
|
|
260
269
|
white-space: nowrap;
|
|
261
270
|
overflow: hidden;
|
|
262
271
|
display: block;
|
|
263
272
|
width: 100%;
|
|
273
|
+
color: $gray-900;
|
|
274
|
+
&:hover {
|
|
275
|
+
color: var(--wp-admin-theme-color);
|
|
276
|
+
}
|
|
264
277
|
}
|
|
265
278
|
}
|
|
266
279
|
|
|
@@ -322,16 +335,52 @@
|
|
|
322
335
|
line-height: 16px;
|
|
323
336
|
|
|
324
337
|
&:not(:empty) {
|
|
325
|
-
padding: $grid-unit-15;
|
|
338
|
+
padding: $grid-unit-15 0;
|
|
326
339
|
padding-top: 0;
|
|
340
|
+
margin: 0 $grid-unit-15;
|
|
327
341
|
}
|
|
328
342
|
|
|
329
343
|
.dataviews-view-grid__field {
|
|
330
|
-
|
|
344
|
+
align-items: flex-start;
|
|
345
|
+
|
|
346
|
+
&:not(.is-column) {
|
|
347
|
+
align-items: center;
|
|
348
|
+
|
|
349
|
+
.dataviews-view-grid__field-name {
|
|
350
|
+
width: 35%;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
.dataviews-view-grid__field-value {
|
|
354
|
+
width: 65%;
|
|
355
|
+
overflow: hidden;
|
|
356
|
+
text-overflow: ellipsis;
|
|
357
|
+
white-space: nowrap;
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
.dataviews-view-grid__field-name {
|
|
331
362
|
color: $gray-700;
|
|
332
363
|
}
|
|
333
364
|
}
|
|
334
365
|
}
|
|
366
|
+
|
|
367
|
+
.dataviews-view-grid__badge-fields {
|
|
368
|
+
&:not(:empty) {
|
|
369
|
+
padding: $grid-unit-15;
|
|
370
|
+
padding-top: 0;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
.dataviews-view-grid__field-value {
|
|
374
|
+
width: fit-content;
|
|
375
|
+
background: $gray-100;
|
|
376
|
+
padding: 0 $grid-unit-10;
|
|
377
|
+
min-height: $grid-unit-30;
|
|
378
|
+
border-radius: $radius-block-ui;
|
|
379
|
+
display: flex;
|
|
380
|
+
align-items: center;
|
|
381
|
+
font-size: 12px;
|
|
382
|
+
}
|
|
383
|
+
}
|
|
335
384
|
}
|
|
336
385
|
|
|
337
386
|
.dataviews-view-list {
|
|
@@ -340,6 +389,7 @@
|
|
|
340
389
|
|
|
341
390
|
li {
|
|
342
391
|
margin: 0;
|
|
392
|
+
cursor: pointer;
|
|
343
393
|
|
|
344
394
|
.dataviews-view-list__item-wrapper {
|
|
345
395
|
position: relative;
|
|
@@ -355,14 +405,24 @@
|
|
|
355
405
|
background: $gray-100;
|
|
356
406
|
height: 1px;
|
|
357
407
|
}
|
|
358
|
-
}
|
|
359
408
|
|
|
360
|
-
|
|
361
|
-
|
|
409
|
+
> * {
|
|
410
|
+
width: 100%;
|
|
411
|
+
}
|
|
412
|
+
}
|
|
362
413
|
|
|
363
|
-
|
|
364
|
-
.dataviews-view-
|
|
414
|
+
&:not(.is-selected) {
|
|
415
|
+
.dataviews-view-list__primary-field {
|
|
416
|
+
color: $gray-900;
|
|
417
|
+
}
|
|
418
|
+
&:hover,
|
|
419
|
+
&:focus-within {
|
|
365
420
|
color: var(--wp-admin-theme-color);
|
|
421
|
+
|
|
422
|
+
.dataviews-view-list__primary-field,
|
|
423
|
+
.dataviews-view-list__fields {
|
|
424
|
+
color: var(--wp-admin-theme-color);
|
|
425
|
+
}
|
|
366
426
|
}
|
|
367
427
|
}
|
|
368
428
|
}
|
|
@@ -388,8 +448,9 @@
|
|
|
388
448
|
.dataviews-view-list__item {
|
|
389
449
|
padding: $grid-unit-15 0 $grid-unit-15 $grid-unit-30;
|
|
390
450
|
width: 100%;
|
|
391
|
-
|
|
392
|
-
|
|
451
|
+
scroll-margin: $grid-unit-10 0;
|
|
452
|
+
|
|
453
|
+
&:focus-visible {
|
|
393
454
|
&::before {
|
|
394
455
|
position: absolute;
|
|
395
456
|
content: "";
|
|
@@ -404,6 +465,7 @@
|
|
|
404
465
|
}
|
|
405
466
|
.dataviews-view-list__primary-field {
|
|
406
467
|
min-height: $grid-unit-05 * 5;
|
|
468
|
+
overflow: hidden;
|
|
407
469
|
}
|
|
408
470
|
}
|
|
409
471
|
|
|
@@ -449,7 +511,7 @@
|
|
|
449
511
|
line-height: $grid-unit-20;
|
|
450
512
|
|
|
451
513
|
.dataviews-view-list__field {
|
|
452
|
-
&:empty {
|
|
514
|
+
&:has(.dataviews-view-list__field-value:empty) {
|
|
453
515
|
display: none;
|
|
454
516
|
}
|
|
455
517
|
}
|
|
@@ -459,26 +521,6 @@
|
|
|
459
521
|
justify-content: space-between;
|
|
460
522
|
}
|
|
461
523
|
|
|
462
|
-
.dataviews-view-list__details-button {
|
|
463
|
-
align-self: center;
|
|
464
|
-
opacity: 0;
|
|
465
|
-
}
|
|
466
|
-
|
|
467
|
-
li.is-selected,
|
|
468
|
-
li:hover,
|
|
469
|
-
li:focus-within {
|
|
470
|
-
.dataviews-view-list__details-button {
|
|
471
|
-
opacity: 1;
|
|
472
|
-
}
|
|
473
|
-
}
|
|
474
|
-
|
|
475
|
-
li.is-selected {
|
|
476
|
-
.dataviews-view-list__details-button {
|
|
477
|
-
&:focus {
|
|
478
|
-
box-shadow: 0 0 0 var(--wp-admin-border-width-focus) currentColor;
|
|
479
|
-
}
|
|
480
|
-
}
|
|
481
|
-
}
|
|
482
524
|
}
|
|
483
525
|
|
|
484
526
|
.dataviews-action-modal {
|
|
@@ -494,16 +536,14 @@
|
|
|
494
536
|
justify-content: center;
|
|
495
537
|
}
|
|
496
538
|
|
|
497
|
-
.dataviews-view-table-selection-checkbox
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
white-space: nowrap;
|
|
506
|
-
border: 0;
|
|
539
|
+
.dataviews-view-table-selection-checkbox {
|
|
540
|
+
// Experimental override for CheckboxControl size (fragile)
|
|
541
|
+
--checkbox-input-size: 24px;
|
|
542
|
+
@include break-small() {
|
|
543
|
+
--checkbox-input-size: 16px;
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
line-height: 0;
|
|
507
547
|
}
|
|
508
548
|
|
|
509
549
|
.dataviews-filters__custom-menu-radio-item-prefix {
|
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Internal dependencies
|
|
3
|
+
*/
|
|
4
|
+
import { filterSortAndPaginate } from '../filter-and-sort-data-view';
|
|
5
|
+
import { data, fields } from '../stories/fixtures';
|
|
6
|
+
|
|
7
|
+
describe( 'filters', () => {
|
|
8
|
+
it( 'should return empty if the data is empty', () => {
|
|
9
|
+
expect( filterSortAndPaginate( null, {}, [] ) ).toStrictEqual( {
|
|
10
|
+
data: [],
|
|
11
|
+
paginationInfo: { totalItems: 0, totalPages: 0 },
|
|
12
|
+
} );
|
|
13
|
+
} );
|
|
14
|
+
|
|
15
|
+
it( 'should return the same data if no filters are applied', () => {
|
|
16
|
+
expect(
|
|
17
|
+
filterSortAndPaginate(
|
|
18
|
+
data,
|
|
19
|
+
{
|
|
20
|
+
filters: [],
|
|
21
|
+
},
|
|
22
|
+
[]
|
|
23
|
+
)
|
|
24
|
+
).toStrictEqual( {
|
|
25
|
+
data,
|
|
26
|
+
paginationInfo: { totalItems: data.length, totalPages: 1 },
|
|
27
|
+
} );
|
|
28
|
+
} );
|
|
29
|
+
|
|
30
|
+
it( 'should search using searchable fields (title)', () => {
|
|
31
|
+
const { data: result } = filterSortAndPaginate(
|
|
32
|
+
data,
|
|
33
|
+
{
|
|
34
|
+
search: 'Neptu',
|
|
35
|
+
filters: [],
|
|
36
|
+
},
|
|
37
|
+
fields
|
|
38
|
+
);
|
|
39
|
+
expect( result ).toHaveLength( 1 );
|
|
40
|
+
expect( result[ 0 ].title ).toBe( 'Neptune' );
|
|
41
|
+
} );
|
|
42
|
+
|
|
43
|
+
it( 'should search using searchable fields (description)', () => {
|
|
44
|
+
const { data: result } = filterSortAndPaginate(
|
|
45
|
+
data,
|
|
46
|
+
{
|
|
47
|
+
search: 'photo',
|
|
48
|
+
filters: [],
|
|
49
|
+
},
|
|
50
|
+
fields
|
|
51
|
+
);
|
|
52
|
+
expect( result ).toHaveLength( 1 );
|
|
53
|
+
expect( result[ 0 ].description ).toBe( 'NASA photo' );
|
|
54
|
+
} );
|
|
55
|
+
|
|
56
|
+
it( 'should perform case-insensitive and accent-insensitive search', () => {
|
|
57
|
+
const { data: result } = filterSortAndPaginate(
|
|
58
|
+
data,
|
|
59
|
+
{
|
|
60
|
+
search: 'nete ven',
|
|
61
|
+
filters: [],
|
|
62
|
+
},
|
|
63
|
+
fields
|
|
64
|
+
);
|
|
65
|
+
expect( result ).toHaveLength( 1 );
|
|
66
|
+
expect( result[ 0 ].description ).toBe( 'La planète Vénus' );
|
|
67
|
+
} );
|
|
68
|
+
|
|
69
|
+
it( 'should search using IS filter', () => {
|
|
70
|
+
const { data: result } = filterSortAndPaginate(
|
|
71
|
+
data,
|
|
72
|
+
{
|
|
73
|
+
filters: [
|
|
74
|
+
{
|
|
75
|
+
field: 'type',
|
|
76
|
+
operator: 'is',
|
|
77
|
+
value: 'Ice giant',
|
|
78
|
+
},
|
|
79
|
+
],
|
|
80
|
+
},
|
|
81
|
+
fields
|
|
82
|
+
);
|
|
83
|
+
expect( result ).toHaveLength( 2 );
|
|
84
|
+
expect( result[ 0 ].title ).toBe( 'Neptune' );
|
|
85
|
+
expect( result[ 1 ].title ).toBe( 'Uranus' );
|
|
86
|
+
} );
|
|
87
|
+
|
|
88
|
+
it( 'should search using IS NOT filter', () => {
|
|
89
|
+
const { data: result } = filterSortAndPaginate(
|
|
90
|
+
data,
|
|
91
|
+
{
|
|
92
|
+
filters: [
|
|
93
|
+
{
|
|
94
|
+
field: 'type',
|
|
95
|
+
operator: 'isNot',
|
|
96
|
+
value: 'Ice giant',
|
|
97
|
+
},
|
|
98
|
+
],
|
|
99
|
+
},
|
|
100
|
+
fields
|
|
101
|
+
);
|
|
102
|
+
expect( result ).toHaveLength( 9 );
|
|
103
|
+
expect( result[ 0 ].title ).toBe( 'Apollo' );
|
|
104
|
+
expect( result[ 1 ].title ).toBe( 'Space' );
|
|
105
|
+
expect( result[ 2 ].title ).toBe( 'NASA' );
|
|
106
|
+
expect( result[ 3 ].title ).toBe( 'Mercury' );
|
|
107
|
+
expect( result[ 4 ].title ).toBe( 'Venus' );
|
|
108
|
+
expect( result[ 5 ].title ).toBe( 'Earth' );
|
|
109
|
+
expect( result[ 6 ].title ).toBe( 'Mars' );
|
|
110
|
+
expect( result[ 7 ].title ).toBe( 'Jupiter' );
|
|
111
|
+
expect( result[ 8 ].title ).toBe( 'Saturn' );
|
|
112
|
+
} );
|
|
113
|
+
|
|
114
|
+
it( 'should search using IS ANY filter for STRING values', () => {
|
|
115
|
+
const { data: result } = filterSortAndPaginate(
|
|
116
|
+
data,
|
|
117
|
+
{
|
|
118
|
+
filters: [
|
|
119
|
+
{
|
|
120
|
+
field: 'type',
|
|
121
|
+
operator: 'isAny',
|
|
122
|
+
value: [ 'Ice giant' ],
|
|
123
|
+
},
|
|
124
|
+
],
|
|
125
|
+
},
|
|
126
|
+
fields
|
|
127
|
+
);
|
|
128
|
+
expect( result ).toHaveLength( 2 );
|
|
129
|
+
expect( result[ 0 ].title ).toBe( 'Neptune' );
|
|
130
|
+
expect( result[ 1 ].title ).toBe( 'Uranus' );
|
|
131
|
+
} );
|
|
132
|
+
|
|
133
|
+
it( 'should search using IS NONE filter for STRING values', () => {
|
|
134
|
+
const { data: result } = filterSortAndPaginate(
|
|
135
|
+
data,
|
|
136
|
+
{
|
|
137
|
+
filters: [
|
|
138
|
+
{
|
|
139
|
+
field: 'type',
|
|
140
|
+
operator: 'isNone',
|
|
141
|
+
value: [ 'Ice giant', 'Gas giant', 'Terrestrial' ],
|
|
142
|
+
},
|
|
143
|
+
],
|
|
144
|
+
},
|
|
145
|
+
fields
|
|
146
|
+
);
|
|
147
|
+
expect( result ).toHaveLength( 3 );
|
|
148
|
+
expect( result[ 0 ].title ).toBe( 'Apollo' );
|
|
149
|
+
expect( result[ 1 ].title ).toBe( 'Space' );
|
|
150
|
+
expect( result[ 2 ].title ).toBe( 'NASA' );
|
|
151
|
+
} );
|
|
152
|
+
|
|
153
|
+
it( 'should search using IS ANY filter for ARRAY values', () => {
|
|
154
|
+
const { data: result } = filterSortAndPaginate(
|
|
155
|
+
data,
|
|
156
|
+
{
|
|
157
|
+
filters: [
|
|
158
|
+
{
|
|
159
|
+
field: 'categories',
|
|
160
|
+
operator: 'isAny',
|
|
161
|
+
value: [ 'NASA' ],
|
|
162
|
+
},
|
|
163
|
+
],
|
|
164
|
+
},
|
|
165
|
+
fields
|
|
166
|
+
);
|
|
167
|
+
expect( result ).toHaveLength( 2 );
|
|
168
|
+
expect( result[ 0 ].title ).toBe( 'Apollo' );
|
|
169
|
+
expect( result[ 1 ].title ).toBe( 'NASA' );
|
|
170
|
+
} );
|
|
171
|
+
|
|
172
|
+
it( 'should search using IS NONE filter for ARRAY values', () => {
|
|
173
|
+
const { data: result } = filterSortAndPaginate(
|
|
174
|
+
data,
|
|
175
|
+
{
|
|
176
|
+
filters: [
|
|
177
|
+
{
|
|
178
|
+
field: 'categories',
|
|
179
|
+
operator: 'isNone',
|
|
180
|
+
value: [ 'Space' ],
|
|
181
|
+
},
|
|
182
|
+
],
|
|
183
|
+
},
|
|
184
|
+
fields
|
|
185
|
+
);
|
|
186
|
+
expect( result ).toHaveLength( 1 );
|
|
187
|
+
expect( result[ 0 ].title ).toBe( 'NASA' );
|
|
188
|
+
} );
|
|
189
|
+
|
|
190
|
+
it( 'should search using IS ALL filter', () => {
|
|
191
|
+
const { data: result } = filterSortAndPaginate(
|
|
192
|
+
data,
|
|
193
|
+
{
|
|
194
|
+
filters: [
|
|
195
|
+
{
|
|
196
|
+
field: 'categories',
|
|
197
|
+
operator: 'isAll',
|
|
198
|
+
value: [ 'Planet', 'Solar system' ],
|
|
199
|
+
},
|
|
200
|
+
],
|
|
201
|
+
},
|
|
202
|
+
fields
|
|
203
|
+
);
|
|
204
|
+
expect( result ).toHaveLength( 7 );
|
|
205
|
+
expect( result[ 0 ].title ).toBe( 'Neptune' );
|
|
206
|
+
expect( result[ 1 ].title ).toBe( 'Mercury' );
|
|
207
|
+
expect( result[ 2 ].title ).toBe( 'Venus' );
|
|
208
|
+
expect( result[ 3 ].title ).toBe( 'Earth' );
|
|
209
|
+
expect( result[ 4 ].title ).toBe( 'Mars' );
|
|
210
|
+
expect( result[ 5 ].title ).toBe( 'Jupiter' );
|
|
211
|
+
expect( result[ 6 ].title ).toBe( 'Saturn' );
|
|
212
|
+
} );
|
|
213
|
+
|
|
214
|
+
it( 'should search using IS NOT ALL filter', () => {
|
|
215
|
+
const { data: result } = filterSortAndPaginate(
|
|
216
|
+
data,
|
|
217
|
+
{
|
|
218
|
+
filters: [
|
|
219
|
+
{
|
|
220
|
+
field: 'categories',
|
|
221
|
+
operator: 'isNotAll',
|
|
222
|
+
value: [ 'Planet', 'Solar system' ],
|
|
223
|
+
},
|
|
224
|
+
],
|
|
225
|
+
},
|
|
226
|
+
fields
|
|
227
|
+
);
|
|
228
|
+
expect( result ).toHaveLength( 3 );
|
|
229
|
+
expect( result[ 0 ].title ).toBe( 'Apollo' );
|
|
230
|
+
expect( result[ 1 ].title ).toBe( 'Space' );
|
|
231
|
+
expect( result[ 2 ].title ).toBe( 'NASA' );
|
|
232
|
+
} );
|
|
233
|
+
} );
|
|
234
|
+
|
|
235
|
+
describe( 'sorting', () => {
|
|
236
|
+
it( 'should sort', () => {
|
|
237
|
+
const { data: result } = filterSortAndPaginate(
|
|
238
|
+
data,
|
|
239
|
+
{
|
|
240
|
+
sort: { field: 'title', direction: 'desc' },
|
|
241
|
+
filters: [
|
|
242
|
+
{
|
|
243
|
+
field: 'type',
|
|
244
|
+
operator: 'isAny',
|
|
245
|
+
value: [ 'Ice giant' ],
|
|
246
|
+
},
|
|
247
|
+
],
|
|
248
|
+
},
|
|
249
|
+
fields
|
|
250
|
+
);
|
|
251
|
+
expect( result ).toHaveLength( 2 );
|
|
252
|
+
expect( result[ 0 ].title ).toBe( 'Uranus' );
|
|
253
|
+
expect( result[ 1 ].title ).toBe( 'Neptune' );
|
|
254
|
+
} );
|
|
255
|
+
} );
|
|
256
|
+
|
|
257
|
+
describe( 'pagination', () => {
|
|
258
|
+
it( 'should paginate', () => {
|
|
259
|
+
const { data: result, paginationInfo } = filterSortAndPaginate(
|
|
260
|
+
data,
|
|
261
|
+
{
|
|
262
|
+
perPage: 2,
|
|
263
|
+
page: 2,
|
|
264
|
+
filters: [],
|
|
265
|
+
},
|
|
266
|
+
fields
|
|
267
|
+
);
|
|
268
|
+
expect( result ).toHaveLength( 2 );
|
|
269
|
+
expect( result[ 0 ].title ).toBe( 'NASA' );
|
|
270
|
+
expect( result[ 1 ].title ).toBe( 'Neptune' );
|
|
271
|
+
expect( paginationInfo ).toStrictEqual( {
|
|
272
|
+
totalItems: data.length,
|
|
273
|
+
totalPages: 6,
|
|
274
|
+
} );
|
|
275
|
+
} );
|
|
276
|
+
} );
|
package/src/utils.js
CHANGED
|
@@ -9,58 +9,6 @@ import {
|
|
|
9
9
|
OPERATOR_IS_NONE,
|
|
10
10
|
} from './constants';
|
|
11
11
|
|
|
12
|
-
/**
|
|
13
|
-
* Helper util to sort data by text fields, when sorting is done client side.
|
|
14
|
-
*
|
|
15
|
-
* @param {Object} params Function params.
|
|
16
|
-
* @param {Object[]} params.data Data to sort.
|
|
17
|
-
* @param {Object} params.view Current view object.
|
|
18
|
-
* @param {Object[]} params.fields Array of available fields.
|
|
19
|
-
* @param {string[]} params.textFields Array of the field ids to sort.
|
|
20
|
-
*
|
|
21
|
-
* @return {Object[]} Sorted data.
|
|
22
|
-
*/
|
|
23
|
-
export const sortByTextFields = ( { data, view, fields, textFields } ) => {
|
|
24
|
-
const sortedData = [ ...data ];
|
|
25
|
-
const fieldId = view.sort.field;
|
|
26
|
-
if ( textFields.includes( fieldId ) ) {
|
|
27
|
-
const fieldToSort = fields.find( ( field ) => {
|
|
28
|
-
return field.id === fieldId;
|
|
29
|
-
} );
|
|
30
|
-
sortedData.sort( ( a, b ) => {
|
|
31
|
-
const valueA = fieldToSort.getValue( { item: a } ) ?? '';
|
|
32
|
-
const valueB = fieldToSort.getValue( { item: b } ) ?? '';
|
|
33
|
-
return view.sort.direction === 'asc'
|
|
34
|
-
? valueA.localeCompare( valueB )
|
|
35
|
-
: valueB.localeCompare( valueA );
|
|
36
|
-
} );
|
|
37
|
-
}
|
|
38
|
-
return sortedData;
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* Helper util to get the paginated data and the paginateInfo needed,
|
|
43
|
-
* when pagination is done client side.
|
|
44
|
-
*
|
|
45
|
-
* @param {Object} params Function params.
|
|
46
|
-
* @param {Object[]} params.data Available data.
|
|
47
|
-
* @param {Object} params.view Current view object.
|
|
48
|
-
*
|
|
49
|
-
* @return {Object} Paginated data and paginationInfo.
|
|
50
|
-
*/
|
|
51
|
-
export function getPaginationResults( { data, view } ) {
|
|
52
|
-
const start = ( view.page - 1 ) * view.perPage;
|
|
53
|
-
const totalItems = data?.length || 0;
|
|
54
|
-
data = data?.slice( start, start + view.perPage );
|
|
55
|
-
return {
|
|
56
|
-
data,
|
|
57
|
-
paginationInfo: {
|
|
58
|
-
totalItems,
|
|
59
|
-
totalPages: Math.ceil( totalItems / view.perPage ),
|
|
60
|
-
},
|
|
61
|
-
};
|
|
62
|
-
}
|
|
63
|
-
|
|
64
12
|
export const sanitizeOperators = ( field ) => {
|
|
65
13
|
let operators = field.filterBy?.operators;
|
|
66
14
|
|