@wordpress/dataviews 5.0.0 → 6.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 +31 -1
- package/README.md +55 -27
- package/build/components/dataviews/index.js +13 -4
- package/build/components/dataviews/index.js.map +1 -1
- package/build/components/dataviews-context/index.js +3 -1
- package/build/components/dataviews-context/index.js.map +1 -1
- package/build/components/dataviews-filters/filter.js +15 -8
- package/build/components/dataviews-filters/filter.js.map +1 -1
- package/build/components/dataviews-filters/index.js +16 -5
- package/build/components/dataviews-filters/index.js.map +1 -1
- package/build/components/dataviews-filters/input-widget.js +7 -1
- package/build/components/dataviews-filters/input-widget.js.map +1 -1
- package/build/components/dataviews-filters/reset-filters.js +2 -2
- package/build/components/dataviews-filters/reset-filters.js.map +1 -1
- package/build/components/dataviews-layout/index.js +5 -2
- package/build/components/dataviews-layout/index.js.map +1 -1
- package/build/components/dataviews-view-config/index.js +4 -3
- package/build/components/dataviews-view-config/index.js.map +1 -1
- package/build/dataform-controls/boolean.js +15 -1
- package/build/dataform-controls/boolean.js.map +1 -1
- package/build/dataform-controls/date.js +385 -0
- package/build/dataform-controls/date.js.map +1 -0
- package/build/dataform-controls/datetime.js +5 -84
- package/build/dataform-controls/datetime.js.map +1 -1
- package/build/dataform-controls/email.js +15 -1
- package/build/dataform-controls/email.js.map +1 -1
- package/build/dataform-controls/index.js +2 -0
- package/build/dataform-controls/index.js.map +1 -1
- package/build/dataform-controls/integer.js +23 -4
- package/build/dataform-controls/integer.js.map +1 -1
- package/build/dataform-controls/relative-date-control.js +109 -0
- package/build/dataform-controls/relative-date-control.js.map +1 -0
- package/build/dataform-controls/select.js +12 -5
- package/build/dataform-controls/select.js.map +1 -1
- package/build/dataform-controls/text.js +15 -1
- package/build/dataform-controls/text.js.map +1 -1
- package/build/dataviews-layouts/grid/index.js +40 -23
- package/build/dataviews-layouts/grid/index.js.map +1 -1
- package/build/dataviews-layouts/grid/preview-size-picker.js +39 -85
- package/build/dataviews-layouts/grid/preview-size-picker.js.map +1 -1
- package/build/dataviews-layouts/list/index.js +7 -3
- package/build/dataviews-layouts/list/index.js.map +1 -1
- package/build/dataviews-layouts/table/column-primary.js +18 -3
- package/build/dataviews-layouts/table/column-primary.js.map +1 -1
- package/build/dataviews-layouts/table/index.js +57 -5
- package/build/dataviews-layouts/table/index.js.map +1 -1
- package/build/field-types/array.js +27 -18
- package/build/field-types/array.js.map +1 -1
- package/build/field-types/boolean.js +11 -7
- package/build/field-types/boolean.js.map +1 -1
- package/build/field-types/date.js +21 -12
- package/build/field-types/date.js.map +1 -1
- package/build/field-types/datetime.js +19 -10
- package/build/field-types/datetime.js.map +1 -1
- package/build/field-types/email.js +22 -18
- package/build/field-types/email.js.map +1 -1
- package/build/field-types/index.js +16 -6
- package/build/field-types/index.js.map +1 -1
- package/build/field-types/integer.js +22 -17
- package/build/field-types/integer.js.map +1 -1
- package/build/field-types/media.js +19 -10
- package/build/field-types/media.js.map +1 -1
- package/build/field-types/text.js +19 -10
- package/build/field-types/text.js.map +1 -1
- package/build/filter-and-sort-data-view.js +6 -4
- package/build/filter-and-sort-data-view.js.map +1 -1
- package/build/normalize-fields.js +4 -5
- package/build/normalize-fields.js.map +1 -1
- package/build/types.js.map +1 -1
- package/build/validation.js +15 -2
- package/build/validation.js.map +1 -1
- package/build-module/components/dataviews/index.js +15 -6
- package/build-module/components/dataviews/index.js.map +1 -1
- package/build-module/components/dataviews-context/index.js +3 -1
- package/build-module/components/dataviews-context/index.js.map +1 -1
- package/build-module/components/dataviews-filters/filter.js +15 -8
- package/build-module/components/dataviews-filters/filter.js.map +1 -1
- package/build-module/components/dataviews-filters/index.js +16 -5
- package/build-module/components/dataviews-filters/index.js.map +1 -1
- package/build-module/components/dataviews-filters/input-widget.js +7 -1
- package/build-module/components/dataviews-filters/input-widget.js.map +1 -1
- package/build-module/components/dataviews-filters/reset-filters.js +2 -2
- package/build-module/components/dataviews-filters/reset-filters.js.map +1 -1
- package/build-module/components/dataviews-layout/index.js +5 -2
- package/build-module/components/dataviews-layout/index.js.map +1 -1
- package/build-module/components/dataviews-view-config/index.js +4 -3
- package/build-module/components/dataviews-view-config/index.js.map +1 -1
- package/build-module/dataform-controls/boolean.js +17 -2
- package/build-module/dataform-controls/boolean.js.map +1 -1
- package/build-module/dataform-controls/date.js +376 -0
- package/build-module/dataform-controls/date.js.map +1 -0
- package/build-module/dataform-controls/datetime.js +3 -84
- package/build-module/dataform-controls/datetime.js.map +1 -1
- package/build-module/dataform-controls/email.js +17 -2
- package/build-module/dataform-controls/email.js.map +1 -1
- package/build-module/dataform-controls/index.js +2 -0
- package/build-module/dataform-controls/index.js.map +1 -1
- package/build-module/dataform-controls/integer.js +24 -5
- package/build-module/dataform-controls/integer.js.map +1 -1
- package/build-module/dataform-controls/relative-date-control.js +100 -0
- package/build-module/dataform-controls/relative-date-control.js.map +1 -0
- package/build-module/dataform-controls/select.js +12 -5
- package/build-module/dataform-controls/select.js.map +1 -1
- package/build-module/dataform-controls/text.js +17 -2
- package/build-module/dataform-controls/text.js.map +1 -1
- package/build-module/dataviews-layouts/grid/index.js +41 -24
- package/build-module/dataviews-layouts/grid/index.js.map +1 -1
- package/build-module/dataviews-layouts/grid/preview-size-picker.js +40 -85
- package/build-module/dataviews-layouts/grid/preview-size-picker.js.map +1 -1
- package/build-module/dataviews-layouts/list/index.js +7 -3
- package/build-module/dataviews-layouts/list/index.js.map +1 -1
- package/build-module/dataviews-layouts/table/column-primary.js +18 -3
- package/build-module/dataviews-layouts/table/column-primary.js.map +1 -1
- package/build-module/dataviews-layouts/table/index.js +58 -6
- package/build-module/dataviews-layouts/table/index.js.map +1 -1
- package/build-module/field-types/array.js +27 -18
- package/build-module/field-types/array.js.map +1 -1
- package/build-module/field-types/boolean.js +11 -7
- package/build-module/field-types/boolean.js.map +1 -1
- package/build-module/field-types/date.js +21 -12
- package/build-module/field-types/date.js.map +1 -1
- package/build-module/field-types/datetime.js +19 -10
- package/build-module/field-types/datetime.js.map +1 -1
- package/build-module/field-types/email.js +22 -18
- package/build-module/field-types/email.js.map +1 -1
- package/build-module/field-types/index.js +16 -6
- package/build-module/field-types/index.js.map +1 -1
- package/build-module/field-types/integer.js +22 -17
- package/build-module/field-types/integer.js.map +1 -1
- package/build-module/field-types/media.js +19 -10
- package/build-module/field-types/media.js.map +1 -1
- package/build-module/field-types/text.js +19 -10
- package/build-module/field-types/text.js.map +1 -1
- package/build-module/filter-and-sort-data-view.js +6 -4
- package/build-module/filter-and-sort-data-view.js.map +1 -1
- package/build-module/normalize-fields.js +4 -5
- package/build-module/normalize-fields.js.map +1 -1
- package/build-module/types.js.map +1 -1
- package/build-module/validation.js +15 -2
- package/build-module/validation.js.map +1 -1
- package/build-style/style-rtl.css +78 -43
- package/build-style/style.css +78 -43
- package/build-types/components/dataform/stories/index.story.d.ts +21 -0
- package/build-types/components/dataform/stories/index.story.d.ts.map +1 -1
- package/build-types/components/dataviews/index.d.ts +3 -2
- package/build-types/components/dataviews/index.d.ts.map +1 -1
- package/build-types/components/dataviews/stories/fixtures.d.ts.map +1 -1
- package/build-types/components/dataviews/stories/index.story.d.ts +16 -3
- package/build-types/components/dataviews/stories/index.story.d.ts.map +1 -1
- package/build-types/components/dataviews-context/index.d.ts +4 -2
- package/build-types/components/dataviews-context/index.d.ts.map +1 -1
- package/build-types/components/dataviews-filters/filter.d.ts.map +1 -1
- package/build-types/components/dataviews-filters/index.d.ts.map +1 -1
- package/build-types/components/dataviews-filters/input-widget.d.ts.map +1 -1
- package/build-types/components/dataviews-filters/reset-filters.d.ts.map +1 -1
- package/build-types/components/dataviews-layout/index.d.ts.map +1 -1
- package/build-types/components/dataviews-view-config/index.d.ts.map +1 -1
- package/build-types/constants.d.ts +2 -2
- package/build-types/dataform-controls/boolean.d.ts.map +1 -1
- package/build-types/dataform-controls/date.d.ts +3 -0
- package/build-types/dataform-controls/date.d.ts.map +1 -0
- package/build-types/dataform-controls/datetime.d.ts.map +1 -1
- package/build-types/dataform-controls/email.d.ts.map +1 -1
- package/build-types/dataform-controls/index.d.ts.map +1 -1
- package/build-types/dataform-controls/integer.d.ts.map +1 -1
- package/build-types/dataform-controls/relative-date-control.d.ts +46 -0
- package/build-types/dataform-controls/relative-date-control.d.ts.map +1 -0
- package/build-types/dataform-controls/select.d.ts.map +1 -1
- package/build-types/dataform-controls/text.d.ts.map +1 -1
- package/build-types/dataviews-layouts/grid/index.d.ts +1 -1
- package/build-types/dataviews-layouts/grid/index.d.ts.map +1 -1
- package/build-types/dataviews-layouts/grid/preview-size-picker.d.ts +0 -1
- package/build-types/dataviews-layouts/grid/preview-size-picker.d.ts.map +1 -1
- package/build-types/dataviews-layouts/index.d.ts +3 -3
- package/build-types/dataviews-layouts/list/index.d.ts.map +1 -1
- package/build-types/dataviews-layouts/table/column-primary.d.ts.map +1 -1
- package/build-types/dataviews-layouts/table/index.d.ts +1 -1
- package/build-types/dataviews-layouts/table/index.d.ts.map +1 -1
- package/build-types/field-types/array.d.ts.map +1 -1
- package/build-types/field-types/boolean.d.ts +5 -4
- package/build-types/field-types/boolean.d.ts.map +1 -1
- package/build-types/field-types/date.d.ts +9 -5
- package/build-types/field-types/date.d.ts.map +1 -1
- package/build-types/field-types/datetime.d.ts +4 -3
- package/build-types/field-types/datetime.d.ts.map +1 -1
- package/build-types/field-types/email.d.ts +4 -3
- package/build-types/field-types/email.d.ts.map +1 -1
- package/build-types/field-types/index.d.ts.map +1 -1
- package/build-types/field-types/integer.d.ts +4 -3
- package/build-types/field-types/integer.d.ts.map +1 -1
- package/build-types/field-types/media.d.ts +4 -3
- package/build-types/field-types/media.d.ts.map +1 -1
- package/build-types/field-types/text.d.ts +4 -3
- package/build-types/field-types/text.d.ts.map +1 -1
- package/build-types/filter-and-sort-data-view.d.ts.map +1 -1
- package/build-types/normalize-fields.d.ts.map +1 -1
- package/build-types/types.d.ts +20 -7
- package/build-types/types.d.ts.map +1 -1
- package/build-types/validation.d.ts.map +1 -1
- package/build-wp/index.js +1561 -670
- package/package.json +15 -14
- package/src/components/dataform/stories/index.story.tsx +229 -2
- package/src/components/dataviews/index.tsx +30 -10
- package/src/components/dataviews/stories/fixtures.tsx +3 -1
- package/src/components/dataviews/stories/index.story.tsx +49 -29
- package/src/components/dataviews/stories/style.css +6 -0
- package/src/components/dataviews-context/index.ts +8 -2
- package/src/components/dataviews-filters/filter.tsx +17 -7
- package/src/components/dataviews-filters/index.tsx +17 -2
- package/src/components/dataviews-filters/input-widget.tsx +7 -1
- package/src/components/dataviews-filters/reset-filters.tsx +4 -2
- package/src/components/dataviews-filters/style.scss +8 -2
- package/src/components/dataviews-layout/index.tsx +3 -0
- package/src/components/dataviews-view-config/index.tsx +5 -3
- package/src/dataform-controls/boolean.tsx +19 -2
- package/src/dataform-controls/date.tsx +499 -0
- package/src/dataform-controls/datetime.tsx +5 -91
- package/src/dataform-controls/email.tsx +19 -2
- package/src/dataform-controls/index.tsx +2 -0
- package/src/dataform-controls/integer.tsx +30 -4
- package/src/dataform-controls/relative-date-control.tsx +106 -0
- package/src/dataform-controls/select.tsx +23 -13
- package/src/dataform-controls/style.scss +19 -2
- package/src/dataform-controls/text.tsx +19 -2
- package/src/dataviews-layouts/grid/index.tsx +46 -24
- package/src/dataviews-layouts/grid/preview-size-picker.tsx +48 -73
- package/src/dataviews-layouts/grid/style.scss +15 -28
- package/src/dataviews-layouts/list/index.tsx +7 -4
- package/src/dataviews-layouts/list/style.scss +3 -3
- package/src/dataviews-layouts/table/column-primary.tsx +29 -5
- package/src/dataviews-layouts/table/index.tsx +134 -42
- package/src/dataviews-layouts/table/style.scss +45 -1
- package/src/field-types/array.tsx +33 -21
- package/src/field-types/boolean.tsx +15 -9
- package/src/field-types/date.ts +51 -15
- package/src/field-types/datetime.tsx +19 -13
- package/src/field-types/email.tsx +26 -21
- package/src/field-types/index.tsx +18 -8
- package/src/field-types/integer.tsx +26 -22
- package/src/field-types/media.tsx +19 -13
- package/src/field-types/text.tsx +19 -13
- package/src/filter-and-sort-data-view.ts +11 -4
- package/src/normalize-fields.ts +4 -8
- package/src/test/dataviews.tsx +129 -0
- package/src/test/filter-and-sort-data-view.js +52 -2
- package/src/test/validation.ts +4 -15
- package/src/types.ts +28 -8
- package/src/validation.ts +30 -1
- package/tsconfig.json +1 -0
- package/tsconfig.tsbuildinfo +1 -1
package/src/test/dataviews.tsx
CHANGED
|
@@ -285,6 +285,71 @@ describe( 'DataViews component', () => {
|
|
|
285
285
|
await user.click( titleField );
|
|
286
286
|
expect( onClickItemCallback ).toHaveBeenCalledWith( data[ 0 ] );
|
|
287
287
|
} );
|
|
288
|
+
|
|
289
|
+
it( 'accepts click for single selection', async () => {
|
|
290
|
+
render(
|
|
291
|
+
<DataViewWrapper
|
|
292
|
+
view={ {
|
|
293
|
+
...DEFAULT_VIEW,
|
|
294
|
+
fields: [ 'author' ],
|
|
295
|
+
titleField: 'title',
|
|
296
|
+
} }
|
|
297
|
+
// A bulk action is required for the dataview to be multi-selectable.
|
|
298
|
+
actions={ actions }
|
|
299
|
+
/>
|
|
300
|
+
);
|
|
301
|
+
const firstItemElement = screen.getByText( data[ 0 ].title );
|
|
302
|
+
const thirdItemElement = screen.getByText( data[ 2 ].title );
|
|
303
|
+
const user = userEvent.setup();
|
|
304
|
+
await user.click( firstItemElement );
|
|
305
|
+
|
|
306
|
+
// First item should be selected.
|
|
307
|
+
expect(
|
|
308
|
+
screen.getByRole( 'checkbox', { name: data[ 0 ].title } )
|
|
309
|
+
).toBeChecked();
|
|
310
|
+
await user.click( thirdItemElement );
|
|
311
|
+
|
|
312
|
+
// Third item should be selected. First item was deselected.
|
|
313
|
+
expect(
|
|
314
|
+
screen.getByRole( 'checkbox', { name: data[ 2 ].title } )
|
|
315
|
+
).toBeChecked();
|
|
316
|
+
} );
|
|
317
|
+
|
|
318
|
+
it( 'accepts ctrl/cmd key and click for non-consecutive multi-selection', async () => {
|
|
319
|
+
render(
|
|
320
|
+
<DataViewWrapper
|
|
321
|
+
view={ {
|
|
322
|
+
...DEFAULT_VIEW,
|
|
323
|
+
fields: [ 'author' ],
|
|
324
|
+
titleField: 'title',
|
|
325
|
+
} }
|
|
326
|
+
// A bulk action is required for the dataview to be multi-selectable.
|
|
327
|
+
actions={ actions }
|
|
328
|
+
/>
|
|
329
|
+
);
|
|
330
|
+
const firstItemElement = screen.getByText( data[ 0 ].title );
|
|
331
|
+
const thirdItemElement = screen.getByText( data[ 2 ].title );
|
|
332
|
+
const user = userEvent.setup();
|
|
333
|
+
await user.click( firstItemElement );
|
|
334
|
+
|
|
335
|
+
// First item should be selected.
|
|
336
|
+
expect(
|
|
337
|
+
screen.getByRole( 'checkbox', { name: data[ 0 ].title } )
|
|
338
|
+
).toBeChecked();
|
|
339
|
+
await user.keyboard( '{Control>}' );
|
|
340
|
+
await user.click( thirdItemElement );
|
|
341
|
+
|
|
342
|
+
// Both items should be selected.
|
|
343
|
+
expect(
|
|
344
|
+
screen.getByRole( 'checkbox', { name: data[ 0 ].title } )
|
|
345
|
+
).toBeChecked();
|
|
346
|
+
expect(
|
|
347
|
+
screen.getByRole( 'checkbox', { name: data[ 2 ].title } )
|
|
348
|
+
).toBeChecked();
|
|
349
|
+
|
|
350
|
+
// Don't keep the modifier pressed down, that's just mean.
|
|
351
|
+
await user.keyboard( '{/Control}' );
|
|
352
|
+
} );
|
|
288
353
|
} );
|
|
289
354
|
|
|
290
355
|
describe( 'in grid view', () => {
|
|
@@ -363,6 +428,70 @@ describe( 'DataViews component', () => {
|
|
|
363
428
|
await user.click( imageField );
|
|
364
429
|
expect( mediaClickItemCallback ).toHaveBeenCalledWith( data[ 0 ] );
|
|
365
430
|
} );
|
|
431
|
+
|
|
432
|
+
it( 'accepts click for single selection', async () => {
|
|
433
|
+
render(
|
|
434
|
+
<DataViewWrapper
|
|
435
|
+
view={ {
|
|
436
|
+
...DEFAULT_VIEW,
|
|
437
|
+
fields: [ 'author' ],
|
|
438
|
+
titleField: 'title',
|
|
439
|
+
} }
|
|
440
|
+
// A bulk action is required for the dataview to be multi-selectable.
|
|
441
|
+
actions={ actions }
|
|
442
|
+
/>
|
|
443
|
+
);
|
|
444
|
+
const firstItemElement = screen.getByText( data[ 0 ].title );
|
|
445
|
+
const thirdItemElement = screen.getByText( data[ 2 ].title );
|
|
446
|
+
const user = userEvent.setup();
|
|
447
|
+
await user.click( firstItemElement );
|
|
448
|
+
|
|
449
|
+
// First item should be selected.
|
|
450
|
+
expect(
|
|
451
|
+
screen.getByRole( 'checkbox', { name: data[ 0 ].title } )
|
|
452
|
+
).toBeChecked();
|
|
453
|
+
await user.click( thirdItemElement );
|
|
454
|
+
|
|
455
|
+
// Third item should be selected. First item was deselected.
|
|
456
|
+
expect(
|
|
457
|
+
screen.getByRole( 'checkbox', { name: data[ 2 ].title } )
|
|
458
|
+
).toBeChecked();
|
|
459
|
+
} );
|
|
460
|
+
|
|
461
|
+
it( 'accepts ctrl/cmd key and click for non-consecutive multi-selection', async () => {
|
|
462
|
+
render(
|
|
463
|
+
<DataViewWrapper
|
|
464
|
+
view={ {
|
|
465
|
+
...DEFAULT_VIEW,
|
|
466
|
+
fields: [ 'author' ],
|
|
467
|
+
titleField: 'title',
|
|
468
|
+
} }
|
|
469
|
+
// A bulk action is required for the dataview to be multi-selectable.
|
|
470
|
+
actions={ actions }
|
|
471
|
+
/>
|
|
472
|
+
);
|
|
473
|
+
const firstItemElement = screen.getByText( data[ 0 ].title );
|
|
474
|
+
const thirdItemElement = screen.getByText( data[ 2 ].title );
|
|
475
|
+
const user = userEvent.setup();
|
|
476
|
+
await user.click( firstItemElement );
|
|
477
|
+
|
|
478
|
+
// First item should be selected.
|
|
479
|
+
expect(
|
|
480
|
+
screen.getByRole( 'checkbox', { name: data[ 0 ].title } )
|
|
481
|
+
).toBeChecked();
|
|
482
|
+
await user.keyboard( '{Control>}' );
|
|
483
|
+
await user.click( thirdItemElement );
|
|
484
|
+
|
|
485
|
+
// Both items should be selected.
|
|
486
|
+
expect(
|
|
487
|
+
screen.getByRole( 'checkbox', { name: data[ 0 ].title } )
|
|
488
|
+
).toBeChecked();
|
|
489
|
+
expect(
|
|
490
|
+
screen.getByRole( 'checkbox', { name: data[ 2 ].title } )
|
|
491
|
+
).toBeChecked();
|
|
492
|
+
|
|
493
|
+
await user.keyboard( '{/Control}' );
|
|
494
|
+
} );
|
|
366
495
|
} );
|
|
367
496
|
|
|
368
497
|
describe( 'in list view', () => {
|
|
@@ -55,7 +55,9 @@ describe( 'filters', () => {
|
|
|
55
55
|
fields
|
|
56
56
|
);
|
|
57
57
|
expect( result ).toHaveLength( 2 );
|
|
58
|
-
expect( result[ 0 ].description ).toBe(
|
|
58
|
+
expect( result[ 0 ].description ).toBe(
|
|
59
|
+
'The Moon is Earth’s only natural satellite, orbiting at an average distance of 384,400 kilometers with a synchronous rotation that leads to fixed lunar phases as seen from Earth. Its cratered surface and subtle glow define night skies, inspiring exploration missions and influencing tides and biological rhythms worldwide.'
|
|
60
|
+
);
|
|
59
61
|
} );
|
|
60
62
|
|
|
61
63
|
it( 'should perform case-insensitive and accent-insensitive search', () => {
|
|
@@ -71,6 +73,54 @@ describe( 'filters', () => {
|
|
|
71
73
|
expect( result[ 0 ].description ).toBe( 'La planète Vénus' );
|
|
72
74
|
} );
|
|
73
75
|
|
|
76
|
+
it( 'should search over array fields when enableGlobalSearch is true', () => {
|
|
77
|
+
const fieldsWithArraySearch = fields.map( ( field ) =>
|
|
78
|
+
field.id === 'categories'
|
|
79
|
+
? { ...field, enableGlobalSearch: true }
|
|
80
|
+
: field
|
|
81
|
+
);
|
|
82
|
+
|
|
83
|
+
const { data: result } = filterSortAndPaginate(
|
|
84
|
+
data,
|
|
85
|
+
{
|
|
86
|
+
search: 'Moon',
|
|
87
|
+
filters: [],
|
|
88
|
+
},
|
|
89
|
+
fieldsWithArraySearch
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
// Should find items with "satellite" in categories
|
|
93
|
+
expect( result ).toHaveLength( 3 );
|
|
94
|
+
expect( result.map( ( r ) => r.title ).sort() ).toEqual( [
|
|
95
|
+
'Europa',
|
|
96
|
+
'Io',
|
|
97
|
+
'Moon',
|
|
98
|
+
] );
|
|
99
|
+
} );
|
|
100
|
+
|
|
101
|
+
it( 'should search over array fields case-insensitively', () => {
|
|
102
|
+
const fieldsWithArraySearch = fields.map( ( field ) =>
|
|
103
|
+
field.id === 'categories'
|
|
104
|
+
? { ...field, enableGlobalSearch: true }
|
|
105
|
+
: field
|
|
106
|
+
);
|
|
107
|
+
|
|
108
|
+
const { data: result } = filterSortAndPaginate(
|
|
109
|
+
data,
|
|
110
|
+
{
|
|
111
|
+
search: 'planet',
|
|
112
|
+
filters: [],
|
|
113
|
+
},
|
|
114
|
+
fieldsWithArraySearch
|
|
115
|
+
);
|
|
116
|
+
|
|
117
|
+
// Should find items with "Planet" in categories (case-insensitive)
|
|
118
|
+
expect( result ).toHaveLength( 8 );
|
|
119
|
+
expect( result.map( ( r ) => r.title ) ).toContain( 'Neptune' );
|
|
120
|
+
expect( result.map( ( r ) => r.title ) ).toContain( 'Mercury' );
|
|
121
|
+
expect( result.map( ( r ) => r.title ) ).toContain( 'Earth' );
|
|
122
|
+
} );
|
|
123
|
+
|
|
74
124
|
it( 'should search using IS filter', () => {
|
|
75
125
|
const { data: result } = filterSortAndPaginate(
|
|
76
126
|
data,
|
|
@@ -374,7 +424,7 @@ describe( 'filters', () => {
|
|
|
374
424
|
fields
|
|
375
425
|
);
|
|
376
426
|
expect( result.map( ( r ) => r.description ) ).toEqual( [
|
|
377
|
-
|
|
427
|
+
'The Moon is Earth’s only natural satellite, orbiting at an average distance of 384,400 kilometers with a synchronous rotation that leads to fixed lunar phases as seen from Earth. Its cratered surface and subtle glow define night skies, inspiring exploration missions and influencing tides and biological rhythms worldwide.',
|
|
378
428
|
'Moon of Jupiter',
|
|
379
429
|
'Moon of Jupiter',
|
|
380
430
|
'La planète Vénus',
|
package/src/test/validation.ts
CHANGED
|
@@ -35,7 +35,7 @@ describe( 'validation', () => {
|
|
|
35
35
|
expect( result ).toBe( true );
|
|
36
36
|
} );
|
|
37
37
|
|
|
38
|
-
it( 'integer field is invalid if value is not integer', () => {
|
|
38
|
+
it( 'integer field is invalid if value is not integer when not empty', () => {
|
|
39
39
|
const item = { id: 1, order: 'd' };
|
|
40
40
|
const fields: Field< {} >[] = [
|
|
41
41
|
{
|
|
@@ -48,19 +48,6 @@ describe( 'validation', () => {
|
|
|
48
48
|
expect( result ).toBe( false );
|
|
49
49
|
} );
|
|
50
50
|
|
|
51
|
-
it( 'integer field is invalid if value is empty', () => {
|
|
52
|
-
const item = { id: 1, order: '' };
|
|
53
|
-
const fields: Field< {} >[] = [
|
|
54
|
-
{
|
|
55
|
-
id: 'order',
|
|
56
|
-
type: 'integer',
|
|
57
|
-
},
|
|
58
|
-
];
|
|
59
|
-
const form = { fields: [ 'order' ] };
|
|
60
|
-
const result = isItemValid( item, fields, form );
|
|
61
|
-
expect( result ).toBe( false );
|
|
62
|
-
} );
|
|
63
|
-
|
|
64
51
|
it( 'integer field is invalid if value is not one of the elements', () => {
|
|
65
52
|
const item = { id: 1, author: 3 };
|
|
66
53
|
const fields: Field< {} >[] = [
|
|
@@ -121,7 +108,9 @@ describe( 'validation', () => {
|
|
|
121
108
|
{ value: 'a', label: 'A' },
|
|
122
109
|
{ value: 'b', label: 'B' },
|
|
123
110
|
],
|
|
124
|
-
isValid:
|
|
111
|
+
isValid: {
|
|
112
|
+
custom: () => null, // Overrides the validation provided for integer types.
|
|
113
|
+
},
|
|
125
114
|
},
|
|
126
115
|
];
|
|
127
116
|
const form = { fields: [ 'order' ] };
|
package/src/types.ts
CHANGED
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* External dependencies
|
|
3
3
|
*/
|
|
4
|
-
import type {
|
|
4
|
+
import type {
|
|
5
|
+
ReactElement,
|
|
6
|
+
ReactNode,
|
|
7
|
+
ComponentType,
|
|
8
|
+
ComponentProps,
|
|
9
|
+
} from 'react';
|
|
5
10
|
|
|
6
11
|
/**
|
|
7
12
|
* Internal dependencies
|
|
@@ -100,10 +105,6 @@ export type FieldType =
|
|
|
100
105
|
| 'email'
|
|
101
106
|
| 'array';
|
|
102
107
|
|
|
103
|
-
export type ValidationContext = {
|
|
104
|
-
elements?: Option[];
|
|
105
|
-
};
|
|
106
|
-
|
|
107
108
|
/**
|
|
108
109
|
* An abstract interface for Field based on the field type.
|
|
109
110
|
*/
|
|
@@ -116,7 +117,7 @@ export type FieldTypeDefinition< Item > = {
|
|
|
116
117
|
/**
|
|
117
118
|
* Callback used to validate the field.
|
|
118
119
|
*/
|
|
119
|
-
isValid:
|
|
120
|
+
isValid: Rules< Item >;
|
|
120
121
|
|
|
121
122
|
/**
|
|
122
123
|
* Callback used to render an edit control for the field or control name.
|
|
@@ -145,6 +146,11 @@ export type FieldTypeDefinition< Item > = {
|
|
|
145
146
|
enableSorting: boolean;
|
|
146
147
|
};
|
|
147
148
|
|
|
149
|
+
export type Rules< Item > = {
|
|
150
|
+
required?: boolean;
|
|
151
|
+
custom?: ( item: Item, field: NormalizedField< Item > ) => null | string;
|
|
152
|
+
};
|
|
153
|
+
|
|
148
154
|
/**
|
|
149
155
|
* A dataview field for a specific property of a data type.
|
|
150
156
|
*/
|
|
@@ -198,7 +204,7 @@ export type Field< Item > = {
|
|
|
198
204
|
/**
|
|
199
205
|
* Callback used to validate the field.
|
|
200
206
|
*/
|
|
201
|
-
isValid?:
|
|
207
|
+
isValid?: Rules< Item >;
|
|
202
208
|
|
|
203
209
|
/**
|
|
204
210
|
* Callback used to decide if a field should be displayed.
|
|
@@ -250,7 +256,7 @@ export type NormalizedField< Item > = Omit< Field< Item >, 'Edit' > & {
|
|
|
250
256
|
render: ComponentType< DataViewRenderFieldProps< Item > >;
|
|
251
257
|
Edit: ComponentType< DataFormControlProps< Item > > | null;
|
|
252
258
|
sort: ( a: Item, b: Item, direction: SortDirection ) => number;
|
|
253
|
-
isValid:
|
|
259
|
+
isValid: Rules< Item >;
|
|
254
260
|
enableHiding: boolean;
|
|
255
261
|
enableSorting: boolean;
|
|
256
262
|
filterBy: NormalizedFilterByConfig | false;
|
|
@@ -280,6 +286,9 @@ export type DataFormControlProps< Item > = {
|
|
|
280
286
|
export type DataViewRenderFieldProps< Item > = {
|
|
281
287
|
item: Item;
|
|
282
288
|
field: NormalizedField< Item >;
|
|
289
|
+
config?: {
|
|
290
|
+
sizes: string;
|
|
291
|
+
};
|
|
283
292
|
};
|
|
284
293
|
|
|
285
294
|
/**
|
|
@@ -300,6 +309,11 @@ export interface Filter {
|
|
|
300
309
|
* The value to filter by.
|
|
301
310
|
*/
|
|
302
311
|
value: any;
|
|
312
|
+
|
|
313
|
+
/**
|
|
314
|
+
* Whether the filter can be edited by the user.
|
|
315
|
+
*/
|
|
316
|
+
isLocked?: boolean;
|
|
303
317
|
}
|
|
304
318
|
|
|
305
319
|
export interface NormalizedFilter {
|
|
@@ -337,6 +351,11 @@ export interface NormalizedFilter {
|
|
|
337
351
|
* Whether it is a primary filter.
|
|
338
352
|
*/
|
|
339
353
|
isPrimary: boolean;
|
|
354
|
+
|
|
355
|
+
/**
|
|
356
|
+
* Whether the filter can be edited by the user.
|
|
357
|
+
*/
|
|
358
|
+
isLocked: boolean;
|
|
340
359
|
}
|
|
341
360
|
|
|
342
361
|
interface ViewBase {
|
|
@@ -616,6 +635,7 @@ export interface ViewBaseProps< Item > {
|
|
|
616
635
|
) => ReactElement;
|
|
617
636
|
isItemClickable: ( item: Item ) => boolean;
|
|
618
637
|
view: View;
|
|
638
|
+
empty: ReactNode;
|
|
619
639
|
}
|
|
620
640
|
|
|
621
641
|
export interface ViewTableProps< Item > extends ViewBaseProps< Item > {
|
package/src/validation.ts
CHANGED
|
@@ -21,7 +21,36 @@ export function isItemValid< Item >(
|
|
|
21
21
|
const _fields = normalizeFields(
|
|
22
22
|
fields.filter( ( { id } ) => !! form.fields?.includes( id ) )
|
|
23
23
|
);
|
|
24
|
+
|
|
25
|
+
const isEmptyNullOrUndefined = ( value: any ) =>
|
|
26
|
+
[ undefined, '', null ].includes( value );
|
|
27
|
+
|
|
24
28
|
return _fields.every( ( field ) => {
|
|
25
|
-
|
|
29
|
+
const value = field.getValue( { item } );
|
|
30
|
+
|
|
31
|
+
if ( field.isValid.required ) {
|
|
32
|
+
if (
|
|
33
|
+
( field.type === 'text' && isEmptyNullOrUndefined( value ) ) ||
|
|
34
|
+
( field.type === 'email' && isEmptyNullOrUndefined( value ) ) ||
|
|
35
|
+
( field.type === 'integer' &&
|
|
36
|
+
isEmptyNullOrUndefined( value ) ) ||
|
|
37
|
+
( field.type === undefined && isEmptyNullOrUndefined( value ) )
|
|
38
|
+
) {
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if ( field.type === 'boolean' && value !== true ) {
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (
|
|
48
|
+
typeof field.isValid.custom === 'function' &&
|
|
49
|
+
field.isValid.custom( item, field ) !== null
|
|
50
|
+
) {
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return true;
|
|
26
55
|
} );
|
|
27
56
|
}
|