From 32bc82abb67ffcd39367569c2a2014c68baa840b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Maneiro?= <583546+oandregal@users.noreply.github.com> Date: Tue, 25 Nov 2025 10:34:54 +0100 Subject: [PATCH 01/15] Move normalizeFields to field-types --- packages/dataviews/src/components/dataform/index.tsx | 2 +- packages/dataviews/src/components/dataviews-picker/index.tsx | 2 +- packages/dataviews/src/components/dataviews/index.tsx | 2 +- .../dataviews/src/field-types/{utils => }/normalize-fields.ts | 4 ++-- packages/dataviews/src/hooks/use-form-validity.ts | 2 +- packages/dataviews/src/test/normalize-fields.ts | 2 +- packages/dataviews/src/utils/filter-sort-and-paginate.ts | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-) rename packages/dataviews/src/field-types/{utils => }/normalize-fields.ts (81%) diff --git a/packages/dataviews/src/components/dataform/index.tsx b/packages/dataviews/src/components/dataform/index.tsx index 321af6f9302669..f31c1db09de91c 100644 --- a/packages/dataviews/src/components/dataform/index.tsx +++ b/packages/dataviews/src/components/dataform/index.tsx @@ -8,7 +8,7 @@ import { useMemo } from '@wordpress/element'; */ import type { DataFormProps } from '../../types'; import { DataFormProvider } from '../dataform-context'; -import normalizeFields from '../../field-types/utils/normalize-fields'; +import normalizeFields from '../../field-types/normalize-fields'; import { DataFormLayout } from '../../dataform-layouts/data-form-layout'; import normalizeForm from '../../dataform-layouts/normalize-form'; diff --git a/packages/dataviews/src/components/dataviews-picker/index.tsx b/packages/dataviews/src/components/dataviews-picker/index.tsx index a97bb40825978f..258f0d68d7e8a0 100644 --- a/packages/dataviews/src/components/dataviews-picker/index.tsx +++ b/packages/dataviews/src/components/dataviews-picker/index.tsx @@ -29,7 +29,7 @@ import DataViewsViewConfig, { DataviewsViewConfigDropdown, ViewTypeMenu, } from '../dataviews-view-config'; -import normalizeFields from '../../field-types/utils/normalize-fields'; +import normalizeFields from '../../field-types/normalize-fields'; import type { ActionButton, Field, View, SupportedLayouts } from '../../types'; import type { SelectionOrUpdater } from '../../types/private'; type ItemWithId = { id: string }; diff --git a/packages/dataviews/src/components/dataviews/index.tsx b/packages/dataviews/src/components/dataviews/index.tsx index 07cda5d91bd9b7..bf8dbf539b5328 100644 --- a/packages/dataviews/src/components/dataviews/index.tsx +++ b/packages/dataviews/src/components/dataviews/index.tsx @@ -30,7 +30,7 @@ import DataViewsViewConfig, { DataviewsViewConfigDropdown, ViewTypeMenu, } from '../dataviews-view-config'; -import normalizeFields from '../../field-types/utils/normalize-fields'; +import normalizeFields from '../../field-types/normalize-fields'; import type { Action, Field, View, SupportedLayouts } from '../../types'; import type { SelectionOrUpdater } from '../../types/private'; type ItemWithId = { id: string }; diff --git a/packages/dataviews/src/field-types/utils/normalize-fields.ts b/packages/dataviews/src/field-types/normalize-fields.ts similarity index 81% rename from packages/dataviews/src/field-types/utils/normalize-fields.ts rename to packages/dataviews/src/field-types/normalize-fields.ts index 0abb1f55f7332c..df15c8dae9666a 100644 --- a/packages/dataviews/src/field-types/utils/normalize-fields.ts +++ b/packages/dataviews/src/field-types/normalize-fields.ts @@ -5,8 +5,8 @@ /** * Internal dependencies */ -import getNormalizeFieldFunction from '..'; -import type { Field, NormalizedField } from '../../types'; +import getNormalizeFieldFunction from '.'; +import type { Field, NormalizedField } from '../types'; /** * Apply default values and normalize the fields config. diff --git a/packages/dataviews/src/hooks/use-form-validity.ts b/packages/dataviews/src/hooks/use-form-validity.ts index 27bf9d5f5937bf..f37d8e87b75291 100644 --- a/packages/dataviews/src/hooks/use-form-validity.ts +++ b/packages/dataviews/src/hooks/use-form-validity.ts @@ -13,7 +13,7 @@ import { __ } from '@wordpress/i18n'; /** * Internal dependencies */ -import normalizeFields from '../field-types/utils/normalize-fields'; +import normalizeFields from '../field-types/normalize-fields'; import normalizeForm from '../dataform-layouts/normalize-form'; import type { Field, diff --git a/packages/dataviews/src/test/normalize-fields.ts b/packages/dataviews/src/test/normalize-fields.ts index 807f615841ed38..7696edcac25e8f 100644 --- a/packages/dataviews/src/test/normalize-fields.ts +++ b/packages/dataviews/src/test/normalize-fields.ts @@ -1,7 +1,7 @@ /** * Internal dependencies */ -import normalizeFields from '../field-types/utils/normalize-fields'; +import normalizeFields from '../field-types/normalize-fields'; import type { Field } from '../types'; describe( 'normalizeFields: default getValue', () => { diff --git a/packages/dataviews/src/utils/filter-sort-and-paginate.ts b/packages/dataviews/src/utils/filter-sort-and-paginate.ts index 362d80ab68a4bc..4fb9f440276314 100644 --- a/packages/dataviews/src/utils/filter-sort-and-paginate.ts +++ b/packages/dataviews/src/utils/filter-sort-and-paginate.ts @@ -36,7 +36,7 @@ import { OPERATOR_IN_THE_PAST, OPERATOR_OVER, } from '../constants'; -import normalizeFields from '../field-types/utils/normalize-fields'; +import normalizeFields from '../field-types/normalize-fields'; import type { Field, View } from '../types'; function normalizeSearchInput( input = '' ) { From 8af5f81d563bc83b146d69e1f56f29c0da41c1bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Maneiro?= <583546+oandregal@users.noreply.github.com> Date: Tue, 25 Nov 2025 10:37:26 +0100 Subject: [PATCH 02/15] Convert to a switch --- packages/dataviews/src/field-types/index.tsx | 85 +++++++------------- 1 file changed, 31 insertions(+), 54 deletions(-) diff --git a/packages/dataviews/src/field-types/index.tsx b/packages/dataviews/src/field-types/index.tsx index 4534a2ff3e6d6f..bac448000627ec 100644 --- a/packages/dataviews/src/field-types/index.tsx +++ b/packages/dataviews/src/field-types/index.tsx @@ -106,59 +106,36 @@ function normalizeField< Item >( export default function getNormalizeFieldFunction< Item >( type?: FieldType ): ( field: Field< Item > ) => NormalizedField< Item > { - if ( 'email' === type ) { - return email; + switch ( type ) { + case 'email': + return email; + case 'integer': + return integer; + case 'number': + return number; + case 'text': + return text; + case 'datetime': + return datetime; + case 'date': + return date; + case 'boolean': + return boolean; + case 'media': + return media; + case 'array': + return array; + case 'password': + return password; + case 'telephone': + return telephone; + case 'color': + return color; + case 'url': + return url; + // This is a fallback for fields that don't provide a type. + // It can be removed when the field.type is mandatory. + default: + return normalizeField; } - - if ( 'integer' === type ) { - return integer; - } - - if ( 'number' === type ) { - return number; - } - - if ( 'text' === type ) { - return text; - } - - if ( 'datetime' === type ) { - return datetime; - } - - if ( 'date' === type ) { - return date; - } - - if ( 'boolean' === type ) { - return boolean; - } - - if ( 'media' === type ) { - return media; - } - - if ( 'array' === type ) { - return array; - } - - if ( 'password' === type ) { - return password; - } - - if ( 'telephone' === type ) { - return telephone; - } - - if ( 'color' === type ) { - return color; - } - - if ( 'url' === type ) { - return url; - } - - // This is a fallback for fields that don't provide a type. - // It can be removed when the field.type is mandatory. - return normalizeField; } From bbd5097dcadbe6de08a30c38cfe3e6c5cfbcda1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Maneiro?= <583546+oandregal@users.noreply.github.com> Date: Tue, 25 Nov 2025 10:38:03 +0100 Subject: [PATCH 03/15] Remove unused type --- packages/dataviews/src/types/field-api.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/dataviews/src/types/field-api.ts b/packages/dataviews/src/types/field-api.ts index a7b40bb90b5c20..db901bccbd8e61 100644 --- a/packages/dataviews/src/types/field-api.ts +++ b/packages/dataviews/src/types/field-api.ts @@ -244,8 +244,6 @@ export type Field< Item > = { format?: FormatDate; }; -export type NormalizedFormat = Required< FormatDate > | {}; - /** * Format for date fields: * From a6ce5a341f93b7c543c0fad61383d1715d61b664 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Maneiro?= <583546+oandregal@users.noreply.github.com> Date: Tue, 25 Nov 2025 11:21:36 +0100 Subject: [PATCH 04/15] Refactor: the field types only provide specific props, not all --- packages/dataviews/src/field-types/array.tsx | 62 ++++------- .../dataviews/src/field-types/boolean.tsx | 59 ++++------- packages/dataviews/src/field-types/color.tsx | 73 +++++-------- packages/dataviews/src/field-types/date.tsx | 76 ++++++------- .../dataviews/src/field-types/datetime.tsx | 72 +++++-------- packages/dataviews/src/field-types/email.tsx | 81 ++++++-------- packages/dataviews/src/field-types/index.tsx | 74 +++++++------ .../dataviews/src/field-types/integer.tsx | 100 ++++++++---------- packages/dataviews/src/field-types/media.tsx | 33 ++---- .../src/field-types/normalize-fields.ts | 20 +++- packages/dataviews/src/field-types/number.tsx | 96 +++++++---------- .../dataviews/src/field-types/password.tsx | 32 ++---- .../dataviews/src/field-types/telephone.tsx | 58 ++++------ packages/dataviews/src/field-types/text.tsx | 60 ++++------- packages/dataviews/src/field-types/url.tsx | 58 ++++------ packages/dataviews/src/types/private.ts | 17 +++ 16 files changed, 395 insertions(+), 576 deletions(-) diff --git a/packages/dataviews/src/field-types/array.tsx b/packages/dataviews/src/field-types/array.tsx index 50fc08b519a645..0443c7c0e93dc9 100644 --- a/packages/dataviews/src/field-types/array.tsx +++ b/packages/dataviews/src/field-types/array.tsx @@ -9,11 +9,11 @@ import { __ } from '@wordpress/i18n'; import type { DataViewRenderFieldProps, Field, - NormalizedField, Operator, Rules, SortDirection, } from '../types'; +import type { TypeProvidedProps } from '../types/private'; import { OPERATOR_IS_ALL, OPERATOR_IS_ANY, @@ -21,9 +21,7 @@ import { OPERATOR_IS_NOT_ALL, } from '../constants'; import { getControl } from '../dataform-controls'; -import hasElements from './utils/has-elements'; import getValueFromId from './utils/get-value-from-id'; -import setValueFromId from './utils/set-value-from-id'; import getFilterBy from './utils/get-filter-by'; function render( { item, field }: DataViewRenderFieldProps< any > ) { @@ -31,6 +29,27 @@ function render( { item, field }: DataViewRenderFieldProps< any > ) { return value.join( ', ' ); } +const isValid: Rules< any > = { + elements: true, + custom: ( item: any, normalizedField ) => { + const value = normalizedField.getValue( { item } ); + + if ( + ! [ undefined, '', null ].includes( value ) && + ! Array.isArray( value ) + ) { + return __( 'Value must be an array.' ); + } + + // Only allow strings for now. Can be extended to other types in the future. + if ( ! value.every( ( v: any ) => typeof v === 'string' ) ) { + return __( 'Every value must be a string.' ); + } + + return null; + }, +}; + const defaultOperators: Operator[] = [ OPERATOR_IS_ANY, OPERATOR_IS_NONE ]; const validOperators: Operator[] = [ OPERATOR_IS_ANY, @@ -41,9 +60,8 @@ const validOperators: Operator[] = [ export default function normalizeField< Item >( field: Field< Item > -): NormalizedField< Item > { +): TypeProvidedProps< Item > { const getValue = field.getValue || getValueFromId( field.id ); - const setValue = field.setValue || setValueFromId( field.id ); const sort = ( a: any, b: any, direction: SortDirection ) => { // Sort arrays by length, then alphabetically by joined string @@ -64,39 +82,8 @@ export default function normalizeField< Item >( : joinedB.localeCompare( joinedA ); }; - const isValid: Rules< Item > = { - elements: true, - custom: ( item: any, normalizedField ) => { - const value = normalizedField.getValue( { item } ); - - if ( - ! [ undefined, '', null ].includes( value ) && - ! Array.isArray( value ) - ) { - return __( 'Value must be an array.' ); - } - - // Only allow strings for now. Can be extended to other types in the future. - if ( ! value.every( ( v: any ) => typeof v === 'string' ) ) { - return __( 'Every value must be a string.' ); - } - - return null; - }, - }; - return { - id: field.id, type: 'array', - label: field.label || field.id, - header: field.header || field.label || field.id, - description: field.description, - placeholder: field.placeholder, - getValue, - setValue, - elements: field.elements, - getElements: field.getElements, - hasElements: hasElements( field ), render: field.render ?? render, Edit: getControl( field, 'array' ), sort: field.sort ?? sort, @@ -104,11 +91,8 @@ export default function normalizeField< Item >( ...isValid, ...field.isValid, }, - isVisible: field.isVisible, enableSorting: field.enableSorting ?? true, enableGlobalSearch: field.enableGlobalSearch ?? false, - enableHiding: field.enableHiding ?? true, - readOnly: field.readOnly ?? false, filterBy: getFilterBy( field, defaultOperators, validOperators ), format: {}, }; diff --git a/packages/dataviews/src/field-types/boolean.tsx b/packages/dataviews/src/field-types/boolean.tsx index 3c1ab3059f4dd6..3abad6abd34e77 100644 --- a/packages/dataviews/src/field-types/boolean.tsx +++ b/packages/dataviews/src/field-types/boolean.tsx @@ -9,17 +9,15 @@ import { __ } from '@wordpress/i18n'; import type { DataViewRenderFieldProps, Field, - NormalizedField, Operator, Rules, SortDirection, } from '../types'; +import type { TypeProvidedProps } from '../types/private'; import RenderFromElements from './utils/render-from-elements'; import { OPERATOR_IS, OPERATOR_IS_NOT } from '../constants'; import { getControl } from '../dataform-controls'; -import hasElements from './utils/has-elements'; import getValueFromId from './utils/get-value-from-id'; -import setValueFromId from './utils/set-value-from-id'; import getFilterBy from './utils/get-filter-by'; function render( { item, field }: DataViewRenderFieldProps< any > ) { @@ -38,11 +36,29 @@ function render( { item, field }: DataViewRenderFieldProps< any > ) { return null; } +const isValid: Rules< any > = { + elements: true, + custom: ( item: any, normalizedField ) => { + const value = normalizedField.getValue( { item } ); + + if ( + ! [ undefined, '', null ].includes( value ) && + ! [ true, false ].includes( value ) + ) { + return __( 'Value must be true, false, or undefined' ); + } + + return null; + }, +}; + +const defaultOperators: Operator[] = [ OPERATOR_IS, OPERATOR_IS_NOT ]; +const validOperators: Operator[] = [ OPERATOR_IS, OPERATOR_IS_NOT ]; + export default function normalizeField< Item >( field: Field< Item > -): NormalizedField< Item > { +): TypeProvidedProps< Item > { const getValue = field.getValue || getValueFromId( field.id ); - const setValue = field.setValue || setValueFromId( field.id ); const sort = ( a: any, b: any, direction: SortDirection ) => { const valueA = getValue( { item: a } ); @@ -63,38 +79,8 @@ export default function normalizeField< Item >( return boolA ? -1 : 1; }; - const isValid: Rules< Item > = { - elements: true, - custom: ( item: any, normalizedField ) => { - const value = normalizedField.getValue( { item } ); - - if ( - ! [ undefined, '', null ].includes( value ) && - ! [ true, false ].includes( value ) - ) { - return __( 'Value must be true, false, or undefined' ); - } - - return null; - }, - }; - - const defaultOperators: Operator[] = [ OPERATOR_IS, OPERATOR_IS_NOT ]; - - const validOperators: Operator[] = [ OPERATOR_IS, OPERATOR_IS_NOT ]; - return { - id: field.id, type: 'boolean', - label: field.label || field.id, - header: field.header || field.label || field.id, - description: field.description, - placeholder: field.placeholder, - getValue, - setValue, - elements: field.elements, - getElements: field.getElements, - hasElements: hasElements( field ), render: field.render ?? render, Edit: getControl( field, 'checkbox' ), sort: field.sort ?? sort, @@ -102,11 +88,8 @@ export default function normalizeField< Item >( ...isValid, ...field.isValid, }, - isVisible: field.isVisible, enableSorting: field.enableSorting ?? true, enableGlobalSearch: field.enableGlobalSearch ?? false, - enableHiding: field.enableHiding ?? true, - readOnly: field.readOnly ?? false, filterBy: getFilterBy( field, defaultOperators, validOperators ), format: {}, }; diff --git a/packages/dataviews/src/field-types/color.tsx b/packages/dataviews/src/field-types/color.tsx index 907c62f8ee0620..60c4f777263234 100644 --- a/packages/dataviews/src/field-types/color.tsx +++ b/packages/dataviews/src/field-types/color.tsx @@ -14,11 +14,11 @@ import { __ } from '@wordpress/i18n'; import type { DataViewRenderFieldProps, Field, - NormalizedField, Operator, Rules, SortDirection, } from '../types'; +import type { TypeProvidedProps } from '../types/private'; import RenderFromElements from './utils/render-from-elements'; import { OPERATOR_IS, @@ -27,9 +27,7 @@ import { OPERATOR_IS_NOT, } from '../constants'; import { getControl } from '../dataform-controls'; -import hasElements from './utils/has-elements'; import getValueFromId from './utils/get-value-from-id'; -import setValueFromId from './utils/set-value-from-id'; import getFilterBy from './utils/get-filter-by'; function render( { item, field }: DataViewRenderFieldProps< any > ) { @@ -61,16 +59,39 @@ function render( { item, field }: DataViewRenderFieldProps< any > ) { ); } +const isValid: Rules< any > = { + elements: true, + custom: ( item: any, normalizedField ) => { + const value = normalizedField.getValue( { item } ); + + if ( + ! [ undefined, '', null ].includes( value ) && + ! colord( value ).isValid() + ) { + return __( 'Value must be a valid color.' ); + } + + return null; + }, +}; + +const defaultOperators: Operator[] = [ OPERATOR_IS_ANY, OPERATOR_IS_NONE ]; +const validOperators: Operator[] = [ + OPERATOR_IS, + OPERATOR_IS_NOT, + OPERATOR_IS_ANY, + OPERATOR_IS_NONE, +]; + export default function normalizeField< Item >( field: Field< Item > -): NormalizedField< Item > { +): TypeProvidedProps< Item > { const getValue = field.getValue || getValueFromId( field.id ); - const setValue = field.setValue || setValueFromId( field.id ); const sort = ( valueA: any, valueB: any, direction: SortDirection ) => { // Convert colors to HSL for better sorting - const colorA = colord( valueA ); - const colorB = colord( valueB ); + const colorA = colord( getValue( { item: valueA } ) ); + const colorB = colord( getValue( { item: valueB } ) ); if ( ! colorA.isValid() && ! colorB.isValid() ) { return 0; @@ -95,43 +116,8 @@ export default function normalizeField< Item >( return direction === 'asc' ? hslA.l - hslB.l : hslB.l - hslA.l; }; - const isValid: Rules< Item > = { - elements: true, - custom: ( item: any, normalizedField ) => { - const value = normalizedField.getValue( { item } ); - - if ( - ! [ undefined, '', null ].includes( value ) && - ! colord( value ).isValid() - ) { - return __( 'Value must be a valid color.' ); - } - - return null; - }, - }; - - const defaultOperators: Operator[] = [ OPERATOR_IS_ANY, OPERATOR_IS_NONE ]; - - const validOperators: Operator[] = [ - OPERATOR_IS, - OPERATOR_IS_NOT, - OPERATOR_IS_ANY, - OPERATOR_IS_NONE, - ]; - return { - id: field.id, type: 'color', - label: field.label || field.id, - header: field.header || field.label || field.id, - description: field.description, - placeholder: field.placeholder, - getValue, - setValue, - elements: field.elements, - getElements: field.getElements, - hasElements: hasElements( field ), render: field.render ?? render, Edit: getControl( field, 'color' ), sort: field.sort ?? sort, @@ -139,11 +125,8 @@ export default function normalizeField< Item >( ...isValid, ...field.isValid, }, - isVisible: field.isVisible, enableSorting: field.enableSorting ?? true, enableGlobalSearch: field.enableGlobalSearch ?? false, - enableHiding: field.enableHiding ?? true, - readOnly: field.readOnly ?? false, filterBy: getFilterBy( field, defaultOperators, validOperators ), format: {}, }; diff --git a/packages/dataviews/src/field-types/date.tsx b/packages/dataviews/src/field-types/date.tsx index dcd8b7d513e08c..7fb78bbda66e0b 100644 --- a/packages/dataviews/src/field-types/date.tsx +++ b/packages/dataviews/src/field-types/date.tsx @@ -10,11 +10,11 @@ import type { DataViewRenderFieldProps, Field, FormatDate, - NormalizedField, Operator, Rules, SortDirection, } from '../types'; +import type { TypeProvidedProps } from '../types/private'; import RenderFromElements from './utils/render-from-elements'; import { OPERATOR_ON, @@ -29,9 +29,7 @@ import { DAYS_OF_WEEK, } from '../constants'; import { getControl } from '../dataform-controls'; -import hasElements from './utils/has-elements'; import getValueFromId from './utils/get-value-from-id'; -import setValueFromId from './utils/set-value-from-id'; import getFilterBy from './utils/get-filter-by'; function getFormat( field: Field< any > ): Required< FormatDate > { @@ -74,15 +72,38 @@ function render( { item, field }: DataViewRenderFieldProps< any > ) { return dateI18n( format.date, getDate( value ) ); } +const isValid: Rules< any > = { + elements: true, + custom: () => null, +}; + +const defaultOperators: Operator[] = [ + OPERATOR_ON, + OPERATOR_NOT_ON, + OPERATOR_BEFORE, + OPERATOR_AFTER, + OPERATOR_BEFORE_INC, + OPERATOR_AFTER_INC, + OPERATOR_IN_THE_PAST, + OPERATOR_OVER, + OPERATOR_BETWEEN, +]; +const validOperators: Operator[] = [ + OPERATOR_ON, + OPERATOR_NOT_ON, + OPERATOR_BEFORE, + OPERATOR_AFTER, + OPERATOR_BEFORE_INC, + OPERATOR_AFTER_INC, + OPERATOR_IN_THE_PAST, + OPERATOR_OVER, + OPERATOR_BETWEEN, +]; + export default function normalizeField< Item >( field: Field< Item > -): NormalizedField< Item > { +): TypeProvidedProps< Item > { const getValue = field.getValue || getValueFromId( field.id ); - const setValue = field.setValue || setValueFromId( field.id ); - const isValid: Rules< Item > = { - elements: true, - custom: () => null, - }; const sort = ( a: Item, b: Item, direction: SortDirection ) => { const valueA = getValue( { item: a } ); @@ -93,42 +114,8 @@ export default function normalizeField< Item >( return direction === 'asc' ? timeA - timeB : timeB - timeA; }; - const defaultOperators: Operator[] = [ - OPERATOR_ON, - OPERATOR_NOT_ON, - OPERATOR_BEFORE, - OPERATOR_AFTER, - OPERATOR_BEFORE_INC, - OPERATOR_AFTER_INC, - OPERATOR_IN_THE_PAST, - OPERATOR_OVER, - OPERATOR_BETWEEN, - ]; - - const validOperators: Operator[] = [ - OPERATOR_ON, - OPERATOR_NOT_ON, - OPERATOR_BEFORE, - OPERATOR_AFTER, - OPERATOR_BEFORE_INC, - OPERATOR_AFTER_INC, - OPERATOR_IN_THE_PAST, - OPERATOR_OVER, - OPERATOR_BETWEEN, - ]; - return { - id: field.id, type: 'date', - label: field.label || field.id, - header: field.header || field.label || field.id, - description: field.description, - placeholder: field.placeholder, - getValue, - setValue, - elements: field.elements, - getElements: field.getElements, - hasElements: hasElements( field ), render: field.render ?? render, Edit: getControl( field, 'date' ), sort: field.sort ?? sort, @@ -136,11 +123,8 @@ export default function normalizeField< Item >( ...isValid, ...field.isValid, }, - isVisible: field.isVisible, enableSorting: field.enableSorting ?? true, enableGlobalSearch: field.enableGlobalSearch ?? false, - enableHiding: field.enableHiding ?? true, - readOnly: field.readOnly ?? false, filterBy: getFilterBy( field, defaultOperators, validOperators ), format: getFormat( field ), }; diff --git a/packages/dataviews/src/field-types/datetime.tsx b/packages/dataviews/src/field-types/datetime.tsx index bdf424c1ec57a3..1b304b05ea2fa5 100644 --- a/packages/dataviews/src/field-types/datetime.tsx +++ b/packages/dataviews/src/field-types/datetime.tsx @@ -4,11 +4,11 @@ import type { DataViewRenderFieldProps, Field, - NormalizedField, Operator, Rules, SortDirection, } from '../types'; +import type { TypeProvidedProps } from '../types/private'; import RenderFromElements from './utils/render-from-elements'; import parseDateTime from './utils/parse-date-time'; import { @@ -22,9 +22,7 @@ import { OPERATOR_OVER, } from '../constants'; import { getControl } from '../dataform-controls'; -import hasElements from './utils/has-elements'; import getValueFromId from './utils/get-value-from-id'; -import setValueFromId from './utils/set-value-from-id'; import getFilterBy from './utils/get-filter-by'; function render( { item, field }: DataViewRenderFieldProps< any > ) { @@ -45,15 +43,36 @@ function render( { item, field }: DataViewRenderFieldProps< any > ) { } } +const isValid: Rules< any > = { + elements: true, + custom: () => null, +}; + +const defaultOperators: Operator[] = [ + OPERATOR_ON, + OPERATOR_NOT_ON, + OPERATOR_BEFORE, + OPERATOR_AFTER, + OPERATOR_BEFORE_INC, + OPERATOR_AFTER_INC, + OPERATOR_IN_THE_PAST, + OPERATOR_OVER, +]; +const validOperators: Operator[] = [ + OPERATOR_ON, + OPERATOR_NOT_ON, + OPERATOR_BEFORE, + OPERATOR_AFTER, + OPERATOR_BEFORE_INC, + OPERATOR_AFTER_INC, + OPERATOR_IN_THE_PAST, + OPERATOR_OVER, +]; + export default function normalizeField< Item >( field: Field< Item > -): NormalizedField< Item > { +): TypeProvidedProps< Item > { const getValue = field.getValue || getValueFromId( field.id ); - const setValue = field.setValue || setValueFromId( field.id ); - const isValid: Rules< Item > = { - elements: true, - custom: () => null, - }; const sort = ( a: Item, b: Item, direction: SortDirection ) => { const valueA = getValue( { item: a } ); @@ -64,40 +83,8 @@ export default function normalizeField< Item >( return direction === 'asc' ? timeA - timeB : timeB - timeA; }; - const defaultOperators: Operator[] = [ - OPERATOR_ON, - OPERATOR_NOT_ON, - OPERATOR_BEFORE, - OPERATOR_AFTER, - OPERATOR_BEFORE_INC, - OPERATOR_AFTER_INC, - OPERATOR_IN_THE_PAST, - OPERATOR_OVER, - ]; - - const validOperators: Operator[] = [ - OPERATOR_ON, - OPERATOR_NOT_ON, - OPERATOR_BEFORE, - OPERATOR_AFTER, - OPERATOR_BEFORE_INC, - OPERATOR_AFTER_INC, - OPERATOR_IN_THE_PAST, - OPERATOR_OVER, - ]; - return { - id: field.id, type: 'datetime', - label: field.label || field.id, - header: field.header || field.label || field.id, - description: field.description, - placeholder: field.placeholder, - getValue, - setValue, - elements: field.elements, - getElements: field.getElements, - hasElements: hasElements( field ), render: field.render ?? render, Edit: getControl( field, 'datetime' ), sort: field.sort ?? sort, @@ -105,11 +92,8 @@ export default function normalizeField< Item >( ...isValid, ...field.isValid, }, - isVisible: field.isVisible, enableSorting: field.enableSorting ?? true, enableGlobalSearch: field.enableGlobalSearch ?? false, - enableHiding: field.enableHiding ?? true, - readOnly: field.readOnly ?? false, filterBy: getFilterBy( field, defaultOperators, validOperators ), format: {}, }; diff --git a/packages/dataviews/src/field-types/email.tsx b/packages/dataviews/src/field-types/email.tsx index ad4e03fa6b0f49..f5dbc32ca2c586 100644 --- a/packages/dataviews/src/field-types/email.tsx +++ b/packages/dataviews/src/field-types/email.tsx @@ -9,11 +9,11 @@ import { __ } from '@wordpress/i18n'; import type { DataViewRenderFieldProps, Field, - NormalizedField, Operator, Rules, SortDirection, } from '../types'; +import type { TypeProvidedProps } from '../types/private'; import RenderFromElements from './utils/render-from-elements'; import { OPERATOR_IS, @@ -27,9 +27,7 @@ import { OPERATOR_STARTS_WITH, } from '../constants'; import { getControl } from '../dataform-controls'; -import hasElements from './utils/has-elements'; import getValueFromId from './utils/get-value-from-id'; -import setValueFromId from './utils/set-value-from-id'; import getFilterBy from './utils/get-filter-by'; // Email validation regex based on HTML5 spec @@ -45,11 +43,40 @@ function render( { item, field }: DataViewRenderFieldProps< any > ) { ); } +const isValid: Rules< any > = { + elements: true, + custom: ( item: any, normalizedField ) => { + const value = normalizedField.getValue( { item } ); + + if ( + ! [ undefined, '', null ].includes( value ) && + ! emailRegex.test( value ) + ) { + return __( 'Value must be a valid email address.' ); + } + + return null; + }, +}; + +const defaultOperators: Operator[] = [ OPERATOR_IS_ANY, OPERATOR_IS_NONE ]; +const validOperators: Operator[] = [ + OPERATOR_IS, + OPERATOR_IS_NOT, + OPERATOR_CONTAINS, + OPERATOR_NOT_CONTAINS, + OPERATOR_STARTS_WITH, + // Multiple selection + OPERATOR_IS_ANY, + OPERATOR_IS_NONE, + OPERATOR_IS_ALL, + OPERATOR_IS_NOT_ALL, +]; + export default function normalizeField< Item >( field: Field< Item > -): NormalizedField< Item > { +): TypeProvidedProps< Item > { const getValue = field.getValue || getValueFromId( field.id ); - const setValue = field.setValue || setValueFromId( field.id ); const sort = ( a: any, b: any, direction: SortDirection ) => { const valueA = getValue( { item: a } ); @@ -59,49 +86,8 @@ export default function normalizeField< Item >( : valueB.localeCompare( valueA ); }; - const isValid: Rules< Item > = { - elements: true, - custom: ( item: any, normalizedField ) => { - const value = normalizedField.getValue( { item } ); - - if ( - ! [ undefined, '', null ].includes( value ) && - ! emailRegex.test( value ) - ) { - return __( 'Value must be a valid email address.' ); - } - - return null; - }, - }; - - const defaultOperators: Operator[] = [ OPERATOR_IS_ANY, OPERATOR_IS_NONE ]; - - const validOperators: Operator[] = [ - OPERATOR_IS, - OPERATOR_IS_NOT, - OPERATOR_CONTAINS, - OPERATOR_NOT_CONTAINS, - OPERATOR_STARTS_WITH, - // Multiple selection - OPERATOR_IS_ANY, - OPERATOR_IS_NONE, - OPERATOR_IS_ALL, - OPERATOR_IS_NOT_ALL, - ]; - return { - id: field.id, type: 'email', - label: field.label || field.id, - header: field.header || field.label || field.id, - description: field.description, - placeholder: field.placeholder, - getValue, - setValue, - elements: field.elements, - getElements: field.getElements, - hasElements: hasElements( field ), render: field.render ?? render, Edit: getControl( field, 'email' ), sort: field.sort ?? sort, @@ -109,11 +95,8 @@ export default function normalizeField< Item >( ...isValid, ...field.isValid, }, - isVisible: field.isVisible, enableSorting: field.enableSorting ?? true, enableGlobalSearch: field.enableGlobalSearch ?? false, - enableHiding: field.enableHiding ?? true, - readOnly: field.readOnly ?? false, filterBy: getFilterBy( field, defaultOperators, validOperators ), format: {}, }; diff --git a/packages/dataviews/src/field-types/index.tsx b/packages/dataviews/src/field-types/index.tsx index bac448000627ec..17fc6f789e2671 100644 --- a/packages/dataviews/src/field-types/index.tsx +++ b/packages/dataviews/src/field-types/index.tsx @@ -9,6 +9,7 @@ import type { Operator, SortDirection, } from '../types'; +import type { TypeProvidedProps } from '../types/private'; import { default as email } from './email'; import { default as integer } from './integer'; import { default as number } from './number'; @@ -25,21 +26,32 @@ import { default as url } from './url'; import RenderFromElements from './utils/render-from-elements'; import { ALL_OPERATORS, OPERATOR_IS, OPERATOR_IS_NOT } from '../constants'; import { getControl } from '../dataform-controls'; -import hasElements from './utils/has-elements'; import getValueFromId from './utils/get-value-from-id'; -import setValueFromId from './utils/set-value-from-id'; import getFilterBy from './utils/get-filter-by'; +const isValid = { + elements: true, + custom: () => null, +}; + +const render = ( { + item, + field: normalizedField, +}: DataViewRenderFieldProps< any > ) => { + return normalizedField.hasElements ? ( + + ) : ( + normalizedField.getValue( { item } ) + ); +}; + +const defaultOperators: Operator[] = [ OPERATOR_IS, OPERATOR_IS_NOT ]; +const validOperators: Operator[] = ALL_OPERATORS; + function normalizeField< Item >( field: Field< Item > -): NormalizedField< Item > { +): TypeProvidedProps< Item > { const getValue = field.getValue || getValueFromId( field.id ); - const setValue = field.setValue || setValueFromId( field.id ); - - const isValid = { - elements: true, - custom: () => null, - }; const sort = ( a: any, b: any, direction: SortDirection ) => { const valueA = getValue( { item: a } ); @@ -54,32 +66,8 @@ function normalizeField< Item >( : valueB.localeCompare( valueA ); }; - const render = ( { - item, - field: normalizedField, - }: DataViewRenderFieldProps< Item > ) => { - return normalizedField.hasElements ? ( - - ) : ( - normalizedField.getValue( { item } ) - ); - }; - - const defaultOperators: Operator[] = [ OPERATOR_IS, OPERATOR_IS_NOT ]; - const validOperators: Operator[] = ALL_OPERATORS; - return { - id: field.id, - // type — it does not have a type - label: field.label || field.id, - header: field.header || field.label || field.id, - description: field.description, - placeholder: field.placeholder, - getValue, - setValue, - elements: field.elements, - getElements: field.getElements, - hasElements: hasElements( field ), + // type: no type for this render: field.render ?? render, Edit: getControl( field, null ), sort: field.sort ?? sort, @@ -87,11 +75,8 @@ function normalizeField< Item >( ...isValid, ...field.isValid, }, - isVisible: field.isVisible, enableSorting: field.enableSorting ?? true, enableGlobalSearch: field.enableGlobalSearch ?? false, - enableHiding: field.enableHiding ?? true, - readOnly: field.readOnly ?? false, filterBy: getFilterBy( field, defaultOperators, validOperators ), format: {}, }; @@ -105,7 +90,20 @@ function normalizeField< Item >( */ export default function getNormalizeFieldFunction< Item >( type?: FieldType -): ( field: Field< Item > ) => NormalizedField< Item > { +): ( + field: Field< Item > +) => Pick< + NormalizedField< Item >, + | 'type' + | 'render' + | 'Edit' + | 'sort' + | 'isValid' + | 'enableSorting' + | 'enableGlobalSearch' + | 'filterBy' + | 'format' +> { switch ( type ) { case 'email': return email; diff --git a/packages/dataviews/src/field-types/integer.tsx b/packages/dataviews/src/field-types/integer.tsx index 19864a1fab7ae8..d37a9bfe2f3f46 100644 --- a/packages/dataviews/src/field-types/integer.tsx +++ b/packages/dataviews/src/field-types/integer.tsx @@ -9,11 +9,11 @@ import { __ } from '@wordpress/i18n'; import type { DataViewRenderFieldProps, Field, - NormalizedField, Operator, Rules, SortDirection, } from '../types'; +import type { TypeProvidedProps } from '../types/private'; import RenderFromElements from './utils/render-from-elements'; import { OPERATOR_IS, @@ -29,9 +29,7 @@ import { OPERATOR_BETWEEN, } from '../constants'; import { getControl } from '../dataform-controls'; -import hasElements from './utils/has-elements'; import getValueFromId from './utils/get-value-from-id'; -import setValueFromId from './utils/set-value-from-id'; import getFilterBy from './utils/get-filter-by'; function render( { item, field }: DataViewRenderFieldProps< any > ) { @@ -42,25 +40,50 @@ function render( { item, field }: DataViewRenderFieldProps< any > ) { ); } +const isValid: Rules< any > = { + elements: true, + custom: ( item: any, normalizedField ) => { + const value = normalizedField.getValue( { item } ); + if ( + ! [ undefined, '', null ].includes( value ) && + ! Number.isInteger( value ) + ) { + return __( 'Value must be an integer.' ); + } + + return null; + }, +}; + +const defaultOperators: Operator[] = [ + OPERATOR_IS, + OPERATOR_IS_NOT, + OPERATOR_LESS_THAN, + OPERATOR_GREATER_THAN, + OPERATOR_LESS_THAN_OR_EQUAL, + OPERATOR_GREATER_THAN_OR_EQUAL, + OPERATOR_BETWEEN, +]; +const validOperators: Operator[] = [ + // Single-selection + OPERATOR_IS, + OPERATOR_IS_NOT, + OPERATOR_LESS_THAN, + OPERATOR_GREATER_THAN, + OPERATOR_LESS_THAN_OR_EQUAL, + OPERATOR_GREATER_THAN_OR_EQUAL, + OPERATOR_BETWEEN, + // Multiple-selection + OPERATOR_IS_ANY, + OPERATOR_IS_NONE, + OPERATOR_IS_ALL, + OPERATOR_IS_NOT_ALL, +]; + export default function normalizeField< Item >( field: Field< Item > -): NormalizedField< Item > { +): TypeProvidedProps< Item > { const getValue = field.getValue || getValueFromId( field.id ); - const setValue = field.setValue || setValueFromId( field.id ); - const isValid: Rules< Item > = { - elements: true, - custom: ( item: any, normalizedField ) => { - const value = normalizedField.getValue( { item } ); - if ( - ! [ undefined, '', null ].includes( value ) && - ! Number.isInteger( value ) - ) { - return __( 'Value must be an integer.' ); - } - - return null; - }, - }; const sort = ( a: Item, b: Item, direction: SortDirection ) => { const valueA = getValue( { item: a } ); @@ -68,44 +91,8 @@ export default function normalizeField< Item >( return direction === 'asc' ? valueA - valueB : valueB - valueA; }; - const defaultOperators: Operator[] = [ - OPERATOR_IS, - OPERATOR_IS_NOT, - OPERATOR_LESS_THAN, - OPERATOR_GREATER_THAN, - OPERATOR_LESS_THAN_OR_EQUAL, - OPERATOR_GREATER_THAN_OR_EQUAL, - OPERATOR_BETWEEN, - ]; - - const validOperators: Operator[] = [ - // Single-selection - OPERATOR_IS, - OPERATOR_IS_NOT, - OPERATOR_LESS_THAN, - OPERATOR_GREATER_THAN, - OPERATOR_LESS_THAN_OR_EQUAL, - OPERATOR_GREATER_THAN_OR_EQUAL, - OPERATOR_BETWEEN, - // Multiple-selection - OPERATOR_IS_ANY, - OPERATOR_IS_NONE, - OPERATOR_IS_ALL, - OPERATOR_IS_NOT_ALL, - ]; - return { - id: field.id, type: 'integer', - label: field.label || field.id, - header: field.header || field.label || field.id, - description: field.description, - placeholder: field.placeholder, - getValue, - setValue, - elements: field.elements, - getElements: field.getElements, - hasElements: hasElements( field ), render: field.render ?? render, Edit: getControl( field, 'integer' ), sort: field.sort ?? sort, @@ -113,11 +100,8 @@ export default function normalizeField< Item >( ...isValid, ...field.isValid, }, - isVisible: field.isVisible, enableSorting: field.enableSorting ?? true, enableGlobalSearch: field.enableGlobalSearch ?? false, - enableHiding: field.enableHiding ?? true, - readOnly: field.readOnly ?? false, filterBy: getFilterBy( field, defaultOperators, validOperators ), format: {}, }; diff --git a/packages/dataviews/src/field-types/media.tsx b/packages/dataviews/src/field-types/media.tsx index 6e2ba665110189..582082f52d1be6 100644 --- a/packages/dataviews/src/field-types/media.tsx +++ b/packages/dataviews/src/field-types/media.tsx @@ -1,11 +1,9 @@ /** * Internal dependencies */ -import type { Field, NormalizedField, Rules } from '../types'; +import type { Field, Rules } from '../types'; +import type { TypeProvidedProps } from '../types/private'; import { getControl } from '../dataform-controls'; -import hasElements from './utils/has-elements'; -import getValueFromId from './utils/get-value-from-id'; -import setValueFromId from './utils/set-value-from-id'; function sort() { return 0; @@ -15,28 +13,16 @@ function render() { return null; } +const isValid: Rules< any > = { + elements: true, + custom: () => null, +}; + export default function normalizeField< Item >( field: Field< Item > -): NormalizedField< Item > { - const getValue = field.getValue || getValueFromId( field.id ); - const setValue = field.setValue || setValueFromId( field.id ); - const isValid: Rules< Item > = { - elements: true, - custom: () => null, - }; - +): TypeProvidedProps< Item > { return { - id: field.id, type: 'media', - label: field.label || field.id, - header: field.header || field.label || field.id, - description: field.description, - placeholder: field.placeholder, - getValue, - setValue, - elements: field.elements, - getElements: field.getElements, - hasElements: hasElements( field ), render: field.render ?? render, Edit: getControl( field, null ), sort: field.sort ?? sort, @@ -44,11 +30,8 @@ export default function normalizeField< Item >( ...isValid, ...field.isValid, }, - isVisible: field.isVisible, enableSorting: field.enableSorting ?? false, enableGlobalSearch: field.enableGlobalSearch ?? false, - enableHiding: field.enableHiding ?? true, - readOnly: field.readOnly ?? false, filterBy: false, format: {}, }; diff --git a/packages/dataviews/src/field-types/normalize-fields.ts b/packages/dataviews/src/field-types/normalize-fields.ts index df15c8dae9666a..ae453a38eee69e 100644 --- a/packages/dataviews/src/field-types/normalize-fields.ts +++ b/packages/dataviews/src/field-types/normalize-fields.ts @@ -7,6 +7,9 @@ */ import getNormalizeFieldFunction from '.'; import type { Field, NormalizedField } from '../types'; +import getValueFromId from './utils/get-value-from-id'; +import hasElements from './utils/has-elements'; +import setValueFromId from './utils/set-value-from-id'; /** * Apply default values and normalize the fields config. @@ -20,6 +23,21 @@ export default function normalizeFields< Item >( return fields.map( ( field ) => { const normalize = getNormalizeFieldFunction< Item >( field.type ); - return normalize( field ); + return { + id: field.id, + label: field.label || field.id, + header: field.header || field.label || field.id, + description: field.description, + placeholder: field.placeholder, + getValue: field.getValue || getValueFromId( field.id ), + setValue: field.setValue || setValueFromId( field.id ), + elements: field.elements, + getElements: field.getElements, + hasElements: hasElements( field ), + isVisible: field.isVisible, + enableHiding: field.enableHiding ?? true, + readOnly: field.readOnly ?? false, + ...normalize( field ), + }; } ); } diff --git a/packages/dataviews/src/field-types/number.tsx b/packages/dataviews/src/field-types/number.tsx index ca6d54fbeb352e..080e2d0357e59e 100644 --- a/packages/dataviews/src/field-types/number.tsx +++ b/packages/dataviews/src/field-types/number.tsx @@ -9,11 +9,11 @@ import { __ } from '@wordpress/i18n'; import type { DataViewRenderFieldProps, Field, - NormalizedField, Operator, Rules, SortDirection, } from '../types'; +import type { TypeProvidedProps } from '../types/private'; import { OPERATOR_IS, OPERATOR_IS_NOT, @@ -29,9 +29,7 @@ import { } from '../constants'; import RenderFromElements from './utils/render-from-elements'; import { getControl } from '../dataform-controls'; -import hasElements from './utils/has-elements'; import getValueFromId from './utils/get-value-from-id'; -import setValueFromId from './utils/set-value-from-id'; import getFilterBy from './utils/get-filter-by'; function isEmpty( value: unknown ): value is '' | undefined | null { @@ -51,23 +49,48 @@ function render( { item, field }: DataViewRenderFieldProps< any > ) { return null; } +const isValid: Rules< any > = { + elements: true, + custom: ( item: any, normalizedField ) => { + const value = normalizedField.getValue( { item } ); + + if ( ! isEmpty( value ) && ! Number.isFinite( value ) ) { + return __( 'Value must be a number.' ); + } + + return null; + }, +}; + +const defaultOperators: Operator[] = [ + OPERATOR_IS, + OPERATOR_IS_NOT, + OPERATOR_LESS_THAN, + OPERATOR_GREATER_THAN, + OPERATOR_LESS_THAN_OR_EQUAL, + OPERATOR_GREATER_THAN_OR_EQUAL, + OPERATOR_BETWEEN, +]; +const validOperators: Operator[] = [ + // Single-selection + OPERATOR_IS, + OPERATOR_IS_NOT, + OPERATOR_LESS_THAN, + OPERATOR_GREATER_THAN, + OPERATOR_LESS_THAN_OR_EQUAL, + OPERATOR_GREATER_THAN_OR_EQUAL, + OPERATOR_BETWEEN, + // Multiple-selection + OPERATOR_IS_ANY, + OPERATOR_IS_NONE, + OPERATOR_IS_ALL, + OPERATOR_IS_NOT_ALL, +]; + export default function normalizeField< Item >( field: Field< Item > -): NormalizedField< Item > { +): TypeProvidedProps< Item > { const getValue = field.getValue || getValueFromId( field.id ); - const setValue = field.setValue || setValueFromId( field.id ); - const isValid: Rules< Item > = { - elements: true, - custom: ( item: any, normalizedField ) => { - const value = normalizedField.getValue( { item } ); - - if ( ! isEmpty( value ) && ! Number.isFinite( value ) ) { - return __( 'Value must be a number.' ); - } - - return null; - }, - }; const sort = ( a: Item, b: Item, direction: SortDirection ) => { const valueA = getValue( { item: a } ); @@ -75,44 +98,8 @@ export default function normalizeField< Item >( return direction === 'asc' ? valueA - valueB : valueB - valueA; }; - const defaultOperators: Operator[] = [ - OPERATOR_IS, - OPERATOR_IS_NOT, - OPERATOR_LESS_THAN, - OPERATOR_GREATER_THAN, - OPERATOR_LESS_THAN_OR_EQUAL, - OPERATOR_GREATER_THAN_OR_EQUAL, - OPERATOR_BETWEEN, - ]; - - const validOperators: Operator[] = [ - // Single-selection - OPERATOR_IS, - OPERATOR_IS_NOT, - OPERATOR_LESS_THAN, - OPERATOR_GREATER_THAN, - OPERATOR_LESS_THAN_OR_EQUAL, - OPERATOR_GREATER_THAN_OR_EQUAL, - OPERATOR_BETWEEN, - // Multiple-selection - OPERATOR_IS_ANY, - OPERATOR_IS_NONE, - OPERATOR_IS_ALL, - OPERATOR_IS_NOT_ALL, - ]; - return { - id: field.id, type: 'number', - label: field.label || field.id, - header: field.header || field.label || field.id, - description: field.description, - placeholder: field.placeholder, - getValue, - setValue, - elements: field.elements, - getElements: field.getElements, - hasElements: hasElements( field ), render: field.render ?? render, Edit: getControl( field, 'number' ), sort: field.sort ?? sort, @@ -120,11 +107,8 @@ export default function normalizeField< Item >( ...isValid, ...field.isValid, }, - isVisible: field.isVisible, enableSorting: field.enableSorting ?? true, enableGlobalSearch: field.enableGlobalSearch ?? false, - enableHiding: field.enableHiding ?? true, - readOnly: field.readOnly ?? false, filterBy: getFilterBy( field, defaultOperators, validOperators ), format: {}, }; diff --git a/packages/dataviews/src/field-types/password.tsx b/packages/dataviews/src/field-types/password.tsx index ec8c5ea8dc5758..7a1aed99ca1013 100644 --- a/packages/dataviews/src/field-types/password.tsx +++ b/packages/dataviews/src/field-types/password.tsx @@ -4,15 +4,12 @@ import type { DataViewRenderFieldProps, Field, - NormalizedField, Rules, SortDirection, } from '../types'; +import type { TypeProvidedProps } from '../types/private'; import RenderFromElements from './utils/render-from-elements'; import { getControl } from '../dataform-controls'; -import hasElements from './utils/has-elements'; -import getValueFromId from './utils/get-value-from-id'; -import setValueFromId from './utils/set-value-from-id'; /* eslint-disable-next-line @typescript-eslint/no-unused-vars */ function sort( _valueA: any, _valueB: any, _direction: SortDirection ) { @@ -28,28 +25,16 @@ function render( { item, field }: DataViewRenderFieldProps< any > ) { ); } +const isValid: Rules< any > = { + elements: true, + custom: () => null, +}; + export default function normalizeField< Item >( field: Field< Item > -): NormalizedField< Item > { - const getValue = field.getValue || getValueFromId( field.id ); - const setValue = field.setValue || setValueFromId( field.id ); - const isValid: Rules< Item > = { - elements: true, - custom: () => null, - }; - +): TypeProvidedProps< Item > { return { - id: field.id, type: 'password', - label: field.label || field.id, - header: field.header || field.label || field.id, - description: field.description, - placeholder: field.placeholder, - getValue, - setValue, - elements: field.elements, - getElements: field.getElements, - hasElements: hasElements( field ), render: field.render ?? render, Edit: getControl( field, 'password' ), sort: field.sort ?? sort, @@ -57,11 +42,8 @@ export default function normalizeField< Item >( ...isValid, ...field.isValid, }, - isVisible: field.isVisible, enableSorting: field.enableSorting ?? false, enableGlobalSearch: field.enableGlobalSearch ?? false, - enableHiding: field.enableHiding ?? true, - readOnly: field.readOnly ?? false, filterBy: false, format: {}, }; diff --git a/packages/dataviews/src/field-types/telephone.tsx b/packages/dataviews/src/field-types/telephone.tsx index 19d2040c820de0..8b14469a5d494b 100644 --- a/packages/dataviews/src/field-types/telephone.tsx +++ b/packages/dataviews/src/field-types/telephone.tsx @@ -4,11 +4,11 @@ import type { DataViewRenderFieldProps, Field, - NormalizedField, Operator, Rules, SortDirection, } from '../types'; +import type { TypeProvidedProps } from '../types/private'; import RenderFromElements from './utils/render-from-elements'; import { OPERATOR_IS, @@ -22,9 +22,7 @@ import { OPERATOR_STARTS_WITH, } from '../constants'; import { getControl } from '../dataform-controls'; -import hasElements from './utils/has-elements'; import getValueFromId from './utils/get-value-from-id'; -import setValueFromId from './utils/set-value-from-id'; import getFilterBy from './utils/get-filter-by'; function render( { item, field }: DataViewRenderFieldProps< any > ) { @@ -35,15 +33,29 @@ function render( { item, field }: DataViewRenderFieldProps< any > ) { ); } +const isValid: Rules< any > = { + elements: true, + custom: () => null, +}; + +const defaultOperators: Operator[] = [ OPERATOR_IS_ANY, OPERATOR_IS_NONE ]; +const validOperators: Operator[] = [ + OPERATOR_IS, + OPERATOR_IS_NOT, + OPERATOR_CONTAINS, + OPERATOR_NOT_CONTAINS, + OPERATOR_STARTS_WITH, + // Multiple selection + OPERATOR_IS_ANY, + OPERATOR_IS_NONE, + OPERATOR_IS_ALL, + OPERATOR_IS_NOT_ALL, +]; + export default function normalizeField< Item >( field: Field< Item > -): NormalizedField< Item > { +): TypeProvidedProps< Item > { const getValue = field.getValue || getValueFromId( field.id ); - const setValue = field.setValue || setValueFromId( field.id ); - const isValid: Rules< Item > = { - elements: true, - custom: () => null, - }; const sort = ( a: any, b: any, direction: SortDirection ) => { const valueA = getValue( { item: a } ); @@ -53,33 +65,8 @@ export default function normalizeField< Item >( : valueB.localeCompare( valueA ); }; - const defaultOperators: Operator[] = [ OPERATOR_IS_ANY, OPERATOR_IS_NONE ]; - - const validOperators: Operator[] = [ - OPERATOR_IS, - OPERATOR_IS_NOT, - OPERATOR_CONTAINS, - OPERATOR_NOT_CONTAINS, - OPERATOR_STARTS_WITH, - // Multiple selection - OPERATOR_IS_ANY, - OPERATOR_IS_NONE, - OPERATOR_IS_ALL, - OPERATOR_IS_NOT_ALL, - ]; - return { - id: field.id, type: 'telephone', - label: field.label || field.id, - header: field.header || field.label || field.id, - description: field.description, - placeholder: field.placeholder, - getValue, - setValue, - elements: field.elements, - getElements: field.getElements, - hasElements: hasElements( field ), render: field.render ?? render, Edit: getControl( field, 'telephone' ), sort: field.sort ?? sort, @@ -87,11 +74,8 @@ export default function normalizeField< Item >( ...isValid, ...field.isValid, }, - isVisible: field.isVisible, enableSorting: field.enableSorting ?? true, enableGlobalSearch: field.enableGlobalSearch ?? false, - enableHiding: field.enableHiding ?? true, - readOnly: field.readOnly ?? false, filterBy: getFilterBy( field, defaultOperators, validOperators ), format: {}, }; diff --git a/packages/dataviews/src/field-types/text.tsx b/packages/dataviews/src/field-types/text.tsx index 036863ff8ad058..a17336a0670ce7 100644 --- a/packages/dataviews/src/field-types/text.tsx +++ b/packages/dataviews/src/field-types/text.tsx @@ -4,11 +4,11 @@ import type { DataViewRenderFieldProps, Field, - NormalizedField, Operator, Rules, SortDirection, } from '../types'; +import type { TypeProvidedProps } from '../types/private'; import RenderFromElements from './utils/render-from-elements'; import { OPERATOR_CONTAINS, @@ -22,11 +22,29 @@ import { OPERATOR_STARTS_WITH, } from '../constants'; import { getControl } from '../dataform-controls'; -import hasElements from './utils/has-elements'; import getValueFromId from './utils/get-value-from-id'; -import setValueFromId from './utils/set-value-from-id'; import getFilterBy from './utils/get-filter-by'; +const isValid: Rules< any > = { + elements: true, + custom: () => null, +}; + +const defaultOperators: Operator[] = [ OPERATOR_IS_ANY, OPERATOR_IS_NONE ]; +const validOperators: Operator[] = [ + // Single selection + OPERATOR_IS, + OPERATOR_IS_NOT, + OPERATOR_CONTAINS, + OPERATOR_NOT_CONTAINS, + OPERATOR_STARTS_WITH, + // Multiple selection + OPERATOR_IS_ANY, + OPERATOR_IS_NONE, + OPERATOR_IS_ALL, + OPERATOR_IS_NOT_ALL, +]; + function render( { item, field }: DataViewRenderFieldProps< any > ) { return field.hasElements ? ( @@ -37,13 +55,8 @@ function render( { item, field }: DataViewRenderFieldProps< any > ) { export default function normalizeField< Item >( field: Field< Item > -): NormalizedField< Item > { +): TypeProvidedProps< Item > { const getValue = field.getValue || getValueFromId( field.id ); - const setValue = field.setValue || setValueFromId( field.id ); - const isValid: Rules< Item > = { - elements: true, - custom: () => null, - }; const sort = ( a: Item, b: Item, direction: SortDirection ) => { const valueA = getValue( { item: a } ); @@ -53,34 +66,8 @@ export default function normalizeField< Item >( : valueB.localeCompare( valueA ); }; - const defaultOperators: Operator[] = [ OPERATOR_IS_ANY, OPERATOR_IS_NONE ]; - - const validOperators: Operator[] = [ - // Single selection - OPERATOR_IS, - OPERATOR_IS_NOT, - OPERATOR_CONTAINS, - OPERATOR_NOT_CONTAINS, - OPERATOR_STARTS_WITH, - // Multiple selection - OPERATOR_IS_ANY, - OPERATOR_IS_NONE, - OPERATOR_IS_ALL, - OPERATOR_IS_NOT_ALL, - ]; - return { - id: field.id, type: 'text', - label: field.label || field.id, - header: field.header || field.label || field.id, - description: field.description, - placeholder: field.placeholder, - getValue, - setValue, - elements: field.elements, - getElements: field.getElements, - hasElements: hasElements( field ), render: field.render ?? render, Edit: getControl( field, 'text' ), sort: field.sort ?? sort, @@ -88,11 +75,8 @@ export default function normalizeField< Item >( ...isValid, ...field.isValid, }, - isVisible: field.isVisible, enableSorting: field.enableSorting ?? true, enableGlobalSearch: field.enableGlobalSearch ?? false, - enableHiding: field.enableHiding ?? true, - readOnly: field.readOnly ?? false, filterBy: getFilterBy( field, defaultOperators, validOperators ), format: {}, }; diff --git a/packages/dataviews/src/field-types/url.tsx b/packages/dataviews/src/field-types/url.tsx index d43dcfd885e57f..e7716dc5de6794 100644 --- a/packages/dataviews/src/field-types/url.tsx +++ b/packages/dataviews/src/field-types/url.tsx @@ -4,11 +4,11 @@ import type { DataViewRenderFieldProps, Field, - NormalizedField, Operator, Rules, SortDirection, } from '../types'; +import type { TypeProvidedProps } from '../types/private'; import RenderFromElements from './utils/render-from-elements'; import { OPERATOR_IS, @@ -22,9 +22,7 @@ import { OPERATOR_STARTS_WITH, } from '../constants'; import { getControl } from '../dataform-controls'; -import hasElements from './utils/has-elements'; import getValueFromId from './utils/get-value-from-id'; -import setValueFromId from './utils/set-value-from-id'; import getFilterBy from './utils/get-filter-by'; function render( { item, field }: DataViewRenderFieldProps< any > ) { @@ -35,15 +33,29 @@ function render( { item, field }: DataViewRenderFieldProps< any > ) { ); } +const isValid: Rules< any > = { + elements: true, + custom: () => null, +}; + +const defaultOperators: Operator[] = [ OPERATOR_IS_ANY, OPERATOR_IS_NONE ]; +const validOperators: Operator[] = [ + OPERATOR_IS, + OPERATOR_IS_NOT, + OPERATOR_CONTAINS, + OPERATOR_NOT_CONTAINS, + OPERATOR_STARTS_WITH, + // Multiple selection + OPERATOR_IS_ANY, + OPERATOR_IS_NONE, + OPERATOR_IS_ALL, + OPERATOR_IS_NOT_ALL, +]; + export default function normalizeField< Item >( field: Field< Item > -): NormalizedField< Item > { +): TypeProvidedProps< Item > { const getValue = field.getValue || getValueFromId( field.id ); - const setValue = field.setValue || setValueFromId( field.id ); - const isValid: Rules< Item > = { - elements: true, - custom: () => null, - }; const sort = ( a: any, b: any, direction: SortDirection ) => { const valueA = getValue( { item: a } ); @@ -53,33 +65,8 @@ export default function normalizeField< Item >( : valueB.localeCompare( valueA ); }; - const defaultOperators: Operator[] = [ OPERATOR_IS_ANY, OPERATOR_IS_NONE ]; - - const validOperators: Operator[] = [ - OPERATOR_IS, - OPERATOR_IS_NOT, - OPERATOR_CONTAINS, - OPERATOR_NOT_CONTAINS, - OPERATOR_STARTS_WITH, - // Multiple selection - OPERATOR_IS_ANY, - OPERATOR_IS_NONE, - OPERATOR_IS_ALL, - OPERATOR_IS_NOT_ALL, - ]; - return { - id: field.id, type: 'url', - label: field.label || field.id, - header: field.header || field.label || field.id, - description: field.description, - placeholder: field.placeholder, - getValue, - setValue, - elements: field.elements, - getElements: field.getElements, - hasElements: hasElements( field ), render: field.render ?? render, Edit: getControl( field, 'url' ), sort: field.sort ?? sort, @@ -87,11 +74,8 @@ export default function normalizeField< Item >( ...isValid, ...field.isValid, }, - isVisible: field.isVisible, enableSorting: field.enableSorting ?? true, enableGlobalSearch: field.enableGlobalSearch ?? false, - enableHiding: field.enableHiding ?? true, - readOnly: field.readOnly ?? false, filterBy: getFilterBy( field, defaultOperators, validOperators ), format: {}, }; diff --git a/packages/dataviews/src/types/private.ts b/packages/dataviews/src/types/private.ts index d2d453e63599c9..72abc53547fd28 100644 --- a/packages/dataviews/src/types/private.ts +++ b/packages/dataviews/src/types/private.ts @@ -1,2 +1,19 @@ +/** + * Internal dependencies + */ +import type { NormalizedField } from './field-api'; + export type SelectionOrUpdater = string[] | ( ( prev: string[] ) => string[] ); export type SetSelection = ( selection: SelectionOrUpdater ) => void; +export type TypeProvidedProps< Item > = Pick< + NormalizedField< Item >, + | 'type' + | 'render' + | 'Edit' + | 'sort' + | 'isValid' + | 'enableSorting' + | 'enableGlobalSearch' + | 'filterBy' + | 'format' +>; From 15f8253e592c15815980f76abe2a750f44659972 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Maneiro?= <583546+oandregal@users.noreply.github.com> Date: Tue, 25 Nov 2025 12:06:01 +0100 Subject: [PATCH 05/15] Trim down the types --- packages/dataviews/src/field-types/array.tsx | 36 ++++----- .../dataviews/src/field-types/boolean.tsx | 26 +++---- packages/dataviews/src/field-types/color.tsx | 36 ++++----- packages/dataviews/src/field-types/date.tsx | 24 +++--- .../dataviews/src/field-types/datetime.tsx | 73 ++++++++----------- packages/dataviews/src/field-types/email.tsx | 48 +++++------- packages/dataviews/src/field-types/index.tsx | 46 +++--------- .../dataviews/src/field-types/integer.tsx | 70 ++++++++---------- packages/dataviews/src/field-types/media.tsx | 38 +++------- .../src/field-types/normalize-fields.ts | 22 +++++- packages/dataviews/src/field-types/number.tsx | 70 ++++++++---------- .../dataviews/src/field-types/password.tsx | 42 +++-------- .../dataviews/src/field-types/telephone.tsx | 59 ++++++--------- packages/dataviews/src/field-types/text.tsx | 61 ++++++---------- packages/dataviews/src/field-types/url.tsx | 59 ++++++--------- packages/dataviews/src/types/private.ts | 14 ++-- 16 files changed, 289 insertions(+), 435 deletions(-) diff --git a/packages/dataviews/src/field-types/array.tsx b/packages/dataviews/src/field-types/array.tsx index 0443c7c0e93dc9..6e0085bbc1096a 100644 --- a/packages/dataviews/src/field-types/array.tsx +++ b/packages/dataviews/src/field-types/array.tsx @@ -9,7 +9,6 @@ import { __ } from '@wordpress/i18n'; import type { DataViewRenderFieldProps, Field, - Operator, Rules, SortDirection, } from '../types'; @@ -20,9 +19,7 @@ import { OPERATOR_IS_NONE, OPERATOR_IS_NOT_ALL, } from '../constants'; -import { getControl } from '../dataform-controls'; import getValueFromId from './utils/get-value-from-id'; -import getFilterBy from './utils/get-filter-by'; function render( { item, field }: DataViewRenderFieldProps< any > ) { const value = field.getValue( { item } ) || []; @@ -50,14 +47,6 @@ const isValid: Rules< any > = { }, }; -const defaultOperators: Operator[] = [ OPERATOR_IS_ANY, OPERATOR_IS_NONE ]; -const validOperators: Operator[] = [ - OPERATOR_IS_ANY, - OPERATOR_IS_NONE, - OPERATOR_IS_ALL, - OPERATOR_IS_NOT_ALL, -]; - export default function normalizeField< Item >( field: Field< Item > ): TypeProvidedProps< Item > { @@ -84,16 +73,19 @@ export default function normalizeField< Item >( return { type: 'array', - render: field.render ?? render, - Edit: getControl( field, 'array' ), - sort: field.sort ?? sort, - isValid: { - ...isValid, - ...field.isValid, - }, - enableSorting: field.enableSorting ?? true, - enableGlobalSearch: field.enableGlobalSearch ?? false, - filterBy: getFilterBy( field, defaultOperators, validOperators ), - format: {}, + render, + Edit: 'array', + sort, + isValid, + enableSorting: true, + enableGlobalSearch: false, + defaultOperators: [ OPERATOR_IS_ANY, OPERATOR_IS_NONE ], + validOperators: [ + OPERATOR_IS_ANY, + OPERATOR_IS_NONE, + OPERATOR_IS_ALL, + OPERATOR_IS_NOT_ALL, + ], + getFormat: () => ( {} ), }; } diff --git a/packages/dataviews/src/field-types/boolean.tsx b/packages/dataviews/src/field-types/boolean.tsx index 3abad6abd34e77..1e1091fd253564 100644 --- a/packages/dataviews/src/field-types/boolean.tsx +++ b/packages/dataviews/src/field-types/boolean.tsx @@ -9,16 +9,13 @@ import { __ } from '@wordpress/i18n'; import type { DataViewRenderFieldProps, Field, - Operator, Rules, SortDirection, } from '../types'; import type { TypeProvidedProps } from '../types/private'; import RenderFromElements from './utils/render-from-elements'; import { OPERATOR_IS, OPERATOR_IS_NOT } from '../constants'; -import { getControl } from '../dataform-controls'; import getValueFromId from './utils/get-value-from-id'; -import getFilterBy from './utils/get-filter-by'; function render( { item, field }: DataViewRenderFieldProps< any > ) { if ( field.hasElements ) { @@ -52,9 +49,6 @@ const isValid: Rules< any > = { }, }; -const defaultOperators: Operator[] = [ OPERATOR_IS, OPERATOR_IS_NOT ]; -const validOperators: Operator[] = [ OPERATOR_IS, OPERATOR_IS_NOT ]; - export default function normalizeField< Item >( field: Field< Item > ): TypeProvidedProps< Item > { @@ -81,16 +75,14 @@ export default function normalizeField< Item >( return { type: 'boolean', - render: field.render ?? render, - Edit: getControl( field, 'checkbox' ), - sort: field.sort ?? sort, - isValid: { - ...isValid, - ...field.isValid, - }, - enableSorting: field.enableSorting ?? true, - enableGlobalSearch: field.enableGlobalSearch ?? false, - filterBy: getFilterBy( field, defaultOperators, validOperators ), - format: {}, + render, + Edit: 'checkbox', + sort, + isValid, + enableSorting: true, + enableGlobalSearch: false, + defaultOperators: [ OPERATOR_IS, OPERATOR_IS_NOT ], + validOperators: [ OPERATOR_IS, OPERATOR_IS_NOT ], + getFormat: () => ( {} ), }; } diff --git a/packages/dataviews/src/field-types/color.tsx b/packages/dataviews/src/field-types/color.tsx index 60c4f777263234..800098e7654342 100644 --- a/packages/dataviews/src/field-types/color.tsx +++ b/packages/dataviews/src/field-types/color.tsx @@ -14,7 +14,6 @@ import { __ } from '@wordpress/i18n'; import type { DataViewRenderFieldProps, Field, - Operator, Rules, SortDirection, } from '../types'; @@ -26,9 +25,7 @@ import { OPERATOR_IS_NONE, OPERATOR_IS_NOT, } from '../constants'; -import { getControl } from '../dataform-controls'; import getValueFromId from './utils/get-value-from-id'; -import getFilterBy from './utils/get-filter-by'; function render( { item, field }: DataViewRenderFieldProps< any > ) { if ( field.hasElements ) { @@ -75,14 +72,6 @@ const isValid: Rules< any > = { }, }; -const defaultOperators: Operator[] = [ OPERATOR_IS_ANY, OPERATOR_IS_NONE ]; -const validOperators: Operator[] = [ - OPERATOR_IS, - OPERATOR_IS_NOT, - OPERATOR_IS_ANY, - OPERATOR_IS_NONE, -]; - export default function normalizeField< Item >( field: Field< Item > ): TypeProvidedProps< Item > { @@ -118,16 +107,19 @@ export default function normalizeField< Item >( return { type: 'color', - render: field.render ?? render, - Edit: getControl( field, 'color' ), - sort: field.sort ?? sort, - isValid: { - ...isValid, - ...field.isValid, - }, - enableSorting: field.enableSorting ?? true, - enableGlobalSearch: field.enableGlobalSearch ?? false, - filterBy: getFilterBy( field, defaultOperators, validOperators ), - format: {}, + render, + Edit: 'color', + sort, + isValid, + enableSorting: true, + enableGlobalSearch: false, + defaultOperators: [ OPERATOR_IS_ANY, OPERATOR_IS_NONE ], + validOperators: [ + OPERATOR_IS, + OPERATOR_IS_NOT, + OPERATOR_IS_ANY, + OPERATOR_IS_NONE, + ], + getFormat: () => ( {} ), }; } diff --git a/packages/dataviews/src/field-types/date.tsx b/packages/dataviews/src/field-types/date.tsx index 7fb78bbda66e0b..f292a4c2a88562 100644 --- a/packages/dataviews/src/field-types/date.tsx +++ b/packages/dataviews/src/field-types/date.tsx @@ -28,11 +28,9 @@ import { OPERATOR_BETWEEN, DAYS_OF_WEEK, } from '../constants'; -import { getControl } from '../dataform-controls'; import getValueFromId from './utils/get-value-from-id'; -import getFilterBy from './utils/get-filter-by'; -function getFormat( field: Field< any > ): Required< FormatDate > { +function getFormat< Item >( field: Field< Item > ): Required< FormatDate > { return { date: field.format?.date !== undefined && @@ -116,16 +114,14 @@ export default function normalizeField< Item >( return { type: 'date', - render: field.render ?? render, - Edit: getControl( field, 'date' ), - sort: field.sort ?? sort, - isValid: { - ...isValid, - ...field.isValid, - }, - enableSorting: field.enableSorting ?? true, - enableGlobalSearch: field.enableGlobalSearch ?? false, - filterBy: getFilterBy( field, defaultOperators, validOperators ), - format: getFormat( field ), + render, + Edit: 'date', + sort, + isValid, + enableSorting: true, + enableGlobalSearch: false, + defaultOperators, + validOperators, + getFormat, }; } diff --git a/packages/dataviews/src/field-types/datetime.tsx b/packages/dataviews/src/field-types/datetime.tsx index 1b304b05ea2fa5..01f517247cec5b 100644 --- a/packages/dataviews/src/field-types/datetime.tsx +++ b/packages/dataviews/src/field-types/datetime.tsx @@ -1,13 +1,7 @@ /** * Internal dependencies */ -import type { - DataViewRenderFieldProps, - Field, - Operator, - Rules, - SortDirection, -} from '../types'; +import type { DataViewRenderFieldProps, Field, SortDirection } from '../types'; import type { TypeProvidedProps } from '../types/private'; import RenderFromElements from './utils/render-from-elements'; import parseDateTime from './utils/parse-date-time'; @@ -21,9 +15,7 @@ import { OPERATOR_IN_THE_PAST, OPERATOR_OVER, } from '../constants'; -import { getControl } from '../dataform-controls'; import getValueFromId from './utils/get-value-from-id'; -import getFilterBy from './utils/get-filter-by'; function render( { item, field }: DataViewRenderFieldProps< any > ) { if ( field.elements ) { @@ -43,32 +35,6 @@ function render( { item, field }: DataViewRenderFieldProps< any > ) { } } -const isValid: Rules< any > = { - elements: true, - custom: () => null, -}; - -const defaultOperators: Operator[] = [ - OPERATOR_ON, - OPERATOR_NOT_ON, - OPERATOR_BEFORE, - OPERATOR_AFTER, - OPERATOR_BEFORE_INC, - OPERATOR_AFTER_INC, - OPERATOR_IN_THE_PAST, - OPERATOR_OVER, -]; -const validOperators: Operator[] = [ - OPERATOR_ON, - OPERATOR_NOT_ON, - OPERATOR_BEFORE, - OPERATOR_AFTER, - OPERATOR_BEFORE_INC, - OPERATOR_AFTER_INC, - OPERATOR_IN_THE_PAST, - OPERATOR_OVER, -]; - export default function normalizeField< Item >( field: Field< Item > ): TypeProvidedProps< Item > { @@ -85,16 +51,35 @@ export default function normalizeField< Item >( return { type: 'datetime', - render: field.render ?? render, - Edit: getControl( field, 'datetime' ), - sort: field.sort ?? sort, + render, + Edit: 'datetime', + sort, isValid: { - ...isValid, - ...field.isValid, + elements: true, + custom: () => null, }, - enableSorting: field.enableSorting ?? true, - enableGlobalSearch: field.enableGlobalSearch ?? false, - filterBy: getFilterBy( field, defaultOperators, validOperators ), - format: {}, + enableSorting: true, + enableGlobalSearch: false, + defaultOperators: [ + OPERATOR_ON, + OPERATOR_NOT_ON, + OPERATOR_BEFORE, + OPERATOR_AFTER, + OPERATOR_BEFORE_INC, + OPERATOR_AFTER_INC, + OPERATOR_IN_THE_PAST, + OPERATOR_OVER, + ], + validOperators: [ + OPERATOR_ON, + OPERATOR_NOT_ON, + OPERATOR_BEFORE, + OPERATOR_AFTER, + OPERATOR_BEFORE_INC, + OPERATOR_AFTER_INC, + OPERATOR_IN_THE_PAST, + OPERATOR_OVER, + ], + getFormat: () => ( {} ), }; } diff --git a/packages/dataviews/src/field-types/email.tsx b/packages/dataviews/src/field-types/email.tsx index f5dbc32ca2c586..15120893eae296 100644 --- a/packages/dataviews/src/field-types/email.tsx +++ b/packages/dataviews/src/field-types/email.tsx @@ -9,7 +9,6 @@ import { __ } from '@wordpress/i18n'; import type { DataViewRenderFieldProps, Field, - Operator, Rules, SortDirection, } from '../types'; @@ -26,9 +25,7 @@ import { OPERATOR_NOT_CONTAINS, OPERATOR_STARTS_WITH, } from '../constants'; -import { getControl } from '../dataform-controls'; import getValueFromId from './utils/get-value-from-id'; -import getFilterBy from './utils/get-filter-by'; // Email validation regex based on HTML5 spec // https://html.spec.whatwg.org/multipage/input.html#valid-e-mail-address @@ -59,20 +56,6 @@ const isValid: Rules< any > = { }, }; -const defaultOperators: Operator[] = [ OPERATOR_IS_ANY, OPERATOR_IS_NONE ]; -const validOperators: Operator[] = [ - OPERATOR_IS, - OPERATOR_IS_NOT, - OPERATOR_CONTAINS, - OPERATOR_NOT_CONTAINS, - OPERATOR_STARTS_WITH, - // Multiple selection - OPERATOR_IS_ANY, - OPERATOR_IS_NONE, - OPERATOR_IS_ALL, - OPERATOR_IS_NOT_ALL, -]; - export default function normalizeField< Item >( field: Field< Item > ): TypeProvidedProps< Item > { @@ -88,16 +71,25 @@ export default function normalizeField< Item >( return { type: 'email', - render: field.render ?? render, - Edit: getControl( field, 'email' ), - sort: field.sort ?? sort, - isValid: { - ...isValid, - ...field.isValid, - }, - enableSorting: field.enableSorting ?? true, - enableGlobalSearch: field.enableGlobalSearch ?? false, - filterBy: getFilterBy( field, defaultOperators, validOperators ), - format: {}, + render, + Edit: 'email', + sort, + isValid, + enableSorting: true, + enableGlobalSearch: false, + defaultOperators: [ OPERATOR_IS_ANY, OPERATOR_IS_NONE ], + validOperators: [ + OPERATOR_IS, + OPERATOR_IS_NOT, + OPERATOR_CONTAINS, + OPERATOR_NOT_CONTAINS, + OPERATOR_STARTS_WITH, + // Multiple selection + OPERATOR_IS_ANY, + OPERATOR_IS_NONE, + OPERATOR_IS_ALL, + OPERATOR_IS_NOT_ALL, + ], + getFormat: () => ( {} ), }; } diff --git a/packages/dataviews/src/field-types/index.tsx b/packages/dataviews/src/field-types/index.tsx index 17fc6f789e2671..368985191a5484 100644 --- a/packages/dataviews/src/field-types/index.tsx +++ b/packages/dataviews/src/field-types/index.tsx @@ -5,8 +5,6 @@ import type { DataViewRenderFieldProps, Field, FieldType, - NormalizedField, - Operator, SortDirection, } from '../types'; import type { TypeProvidedProps } from '../types/private'; @@ -25,14 +23,7 @@ import { default as color } from './color'; import { default as url } from './url'; import RenderFromElements from './utils/render-from-elements'; import { ALL_OPERATORS, OPERATOR_IS, OPERATOR_IS_NOT } from '../constants'; -import { getControl } from '../dataform-controls'; import getValueFromId from './utils/get-value-from-id'; -import getFilterBy from './utils/get-filter-by'; - -const isValid = { - elements: true, - custom: () => null, -}; const render = ( { item, @@ -45,9 +36,6 @@ const render = ( { ); }; -const defaultOperators: Operator[] = [ OPERATOR_IS, OPERATOR_IS_NOT ]; -const validOperators: Operator[] = ALL_OPERATORS; - function normalizeField< Item >( field: Field< Item > ): TypeProvidedProps< Item > { @@ -68,17 +56,18 @@ function normalizeField< Item >( return { // type: no type for this - render: field.render ?? render, - Edit: getControl( field, null ), - sort: field.sort ?? sort, + render, + Edit: null, + sort, isValid: { - ...isValid, - ...field.isValid, + elements: true, + custom: () => null, }, - enableSorting: field.enableSorting ?? true, - enableGlobalSearch: field.enableGlobalSearch ?? false, - filterBy: getFilterBy( field, defaultOperators, validOperators ), - format: {}, + enableSorting: true, + enableGlobalSearch: false, + defaultOperators: [ OPERATOR_IS, OPERATOR_IS_NOT ], + validOperators: ALL_OPERATORS, + getFormat: () => ( {} ), }; } @@ -90,20 +79,7 @@ function normalizeField< Item >( */ export default function getNormalizeFieldFunction< Item >( type?: FieldType -): ( - field: Field< Item > -) => Pick< - NormalizedField< Item >, - | 'type' - | 'render' - | 'Edit' - | 'sort' - | 'isValid' - | 'enableSorting' - | 'enableGlobalSearch' - | 'filterBy' - | 'format' -> { +): ( field: Field< Item > ) => TypeProvidedProps< Item > { switch ( type ) { case 'email': return email; diff --git a/packages/dataviews/src/field-types/integer.tsx b/packages/dataviews/src/field-types/integer.tsx index d37a9bfe2f3f46..111fd324dcef21 100644 --- a/packages/dataviews/src/field-types/integer.tsx +++ b/packages/dataviews/src/field-types/integer.tsx @@ -9,7 +9,6 @@ import { __ } from '@wordpress/i18n'; import type { DataViewRenderFieldProps, Field, - Operator, Rules, SortDirection, } from '../types'; @@ -28,9 +27,7 @@ import { OPERATOR_IS_NOT_ALL, OPERATOR_BETWEEN, } from '../constants'; -import { getControl } from '../dataform-controls'; import getValueFromId from './utils/get-value-from-id'; -import getFilterBy from './utils/get-filter-by'; function render( { item, field }: DataViewRenderFieldProps< any > ) { return field.hasElements ? ( @@ -55,31 +52,6 @@ const isValid: Rules< any > = { }, }; -const defaultOperators: Operator[] = [ - OPERATOR_IS, - OPERATOR_IS_NOT, - OPERATOR_LESS_THAN, - OPERATOR_GREATER_THAN, - OPERATOR_LESS_THAN_OR_EQUAL, - OPERATOR_GREATER_THAN_OR_EQUAL, - OPERATOR_BETWEEN, -]; -const validOperators: Operator[] = [ - // Single-selection - OPERATOR_IS, - OPERATOR_IS_NOT, - OPERATOR_LESS_THAN, - OPERATOR_GREATER_THAN, - OPERATOR_LESS_THAN_OR_EQUAL, - OPERATOR_GREATER_THAN_OR_EQUAL, - OPERATOR_BETWEEN, - // Multiple-selection - OPERATOR_IS_ANY, - OPERATOR_IS_NONE, - OPERATOR_IS_ALL, - OPERATOR_IS_NOT_ALL, -]; - export default function normalizeField< Item >( field: Field< Item > ): TypeProvidedProps< Item > { @@ -93,16 +65,36 @@ export default function normalizeField< Item >( return { type: 'integer', - render: field.render ?? render, - Edit: getControl( field, 'integer' ), - sort: field.sort ?? sort, - isValid: { - ...isValid, - ...field.isValid, - }, - enableSorting: field.enableSorting ?? true, - enableGlobalSearch: field.enableGlobalSearch ?? false, - filterBy: getFilterBy( field, defaultOperators, validOperators ), - format: {}, + render, + Edit: 'integer', + sort, + isValid, + enableSorting: true, + enableGlobalSearch: false, + defaultOperators: [ + OPERATOR_IS, + OPERATOR_IS_NOT, + OPERATOR_LESS_THAN, + OPERATOR_GREATER_THAN, + OPERATOR_LESS_THAN_OR_EQUAL, + OPERATOR_GREATER_THAN_OR_EQUAL, + OPERATOR_BETWEEN, + ], + validOperators: [ + // Single-selection + OPERATOR_IS, + OPERATOR_IS_NOT, + OPERATOR_LESS_THAN, + OPERATOR_GREATER_THAN, + OPERATOR_LESS_THAN_OR_EQUAL, + OPERATOR_GREATER_THAN_OR_EQUAL, + OPERATOR_BETWEEN, + // Multiple-selection + OPERATOR_IS_ANY, + OPERATOR_IS_NONE, + OPERATOR_IS_ALL, + OPERATOR_IS_NOT_ALL, + ], + getFormat: () => ( {} ), }; } diff --git a/packages/dataviews/src/field-types/media.tsx b/packages/dataviews/src/field-types/media.tsx index 582082f52d1be6..c16e1e6d865566 100644 --- a/packages/dataviews/src/field-types/media.tsx +++ b/packages/dataviews/src/field-types/media.tsx @@ -1,38 +1,22 @@ /** * Internal dependencies */ -import type { Field, Rules } from '../types'; import type { TypeProvidedProps } from '../types/private'; -import { getControl } from '../dataform-controls'; -function sort() { - return 0; -} - -function render() { - return null; -} - -const isValid: Rules< any > = { - elements: true, - custom: () => null, -}; - -export default function normalizeField< Item >( - field: Field< Item > -): TypeProvidedProps< Item > { +export default function normalizeField< Item >(): TypeProvidedProps< Item > { return { type: 'media', - render: field.render ?? render, - Edit: getControl( field, null ), - sort: field.sort ?? sort, + render: () => null, + Edit: null, + sort: () => 0, isValid: { - ...isValid, - ...field.isValid, + elements: true, + custom: () => null, }, - enableSorting: field.enableSorting ?? false, - enableGlobalSearch: field.enableGlobalSearch ?? false, - filterBy: false, - format: {}, + enableSorting: false, + enableGlobalSearch: false, + defaultOperators: [], + validOperators: [], + getFormat: () => ( {} ), }; } diff --git a/packages/dataviews/src/field-types/normalize-fields.ts b/packages/dataviews/src/field-types/normalize-fields.ts index ae453a38eee69e..7cc7f775039f1f 100644 --- a/packages/dataviews/src/field-types/normalize-fields.ts +++ b/packages/dataviews/src/field-types/normalize-fields.ts @@ -6,7 +6,9 @@ * Internal dependencies */ import getNormalizeFieldFunction from '.'; +import { getControl } from '../dataform-controls'; import type { Field, NormalizedField } from '../types'; +import getFilterBy from './utils/get-filter-by'; import getValueFromId from './utils/get-value-from-id'; import hasElements from './utils/has-elements'; import setValueFromId from './utils/set-value-from-id'; @@ -22,6 +24,7 @@ export default function normalizeFields< Item >( ): NormalizedField< Item >[] { return fields.map( ( field ) => { const normalize = getNormalizeFieldFunction< Item >( field.type ); + const defaultProps = normalize( field ); return { id: field.id, @@ -37,7 +40,24 @@ export default function normalizeFields< Item >( isVisible: field.isVisible, enableHiding: field.enableHiding ?? true, readOnly: field.readOnly ?? false, - ...normalize( field ), + // The type provides defaults for the following props + type: defaultProps.type, + render: field.render ?? defaultProps.render, + Edit: getControl( field, defaultProps.Edit ), + sort: field.sort ?? defaultProps.sort, + enableSorting: field.enableSorting ?? defaultProps.enableSorting, + enableGlobalSearch: + field.enableGlobalSearch ?? defaultProps.enableGlobalSearch, + isValid: { + ...defaultProps.isValid, + ...field.isValid, + }, + filterBy: getFilterBy( + field, + defaultProps.defaultOperators, + defaultProps.validOperators + ), + format: defaultProps.getFormat( field ), }; } ); } diff --git a/packages/dataviews/src/field-types/number.tsx b/packages/dataviews/src/field-types/number.tsx index 080e2d0357e59e..07dcb5caf930d5 100644 --- a/packages/dataviews/src/field-types/number.tsx +++ b/packages/dataviews/src/field-types/number.tsx @@ -9,7 +9,6 @@ import { __ } from '@wordpress/i18n'; import type { DataViewRenderFieldProps, Field, - Operator, Rules, SortDirection, } from '../types'; @@ -28,9 +27,7 @@ import { OPERATOR_BETWEEN, } from '../constants'; import RenderFromElements from './utils/render-from-elements'; -import { getControl } from '../dataform-controls'; import getValueFromId from './utils/get-value-from-id'; -import getFilterBy from './utils/get-filter-by'; function isEmpty( value: unknown ): value is '' | undefined | null { return value === '' || value === undefined || value === null; @@ -62,31 +59,6 @@ const isValid: Rules< any > = { }, }; -const defaultOperators: Operator[] = [ - OPERATOR_IS, - OPERATOR_IS_NOT, - OPERATOR_LESS_THAN, - OPERATOR_GREATER_THAN, - OPERATOR_LESS_THAN_OR_EQUAL, - OPERATOR_GREATER_THAN_OR_EQUAL, - OPERATOR_BETWEEN, -]; -const validOperators: Operator[] = [ - // Single-selection - OPERATOR_IS, - OPERATOR_IS_NOT, - OPERATOR_LESS_THAN, - OPERATOR_GREATER_THAN, - OPERATOR_LESS_THAN_OR_EQUAL, - OPERATOR_GREATER_THAN_OR_EQUAL, - OPERATOR_BETWEEN, - // Multiple-selection - OPERATOR_IS_ANY, - OPERATOR_IS_NONE, - OPERATOR_IS_ALL, - OPERATOR_IS_NOT_ALL, -]; - export default function normalizeField< Item >( field: Field< Item > ): TypeProvidedProps< Item > { @@ -100,16 +72,36 @@ export default function normalizeField< Item >( return { type: 'number', - render: field.render ?? render, - Edit: getControl( field, 'number' ), - sort: field.sort ?? sort, - isValid: { - ...isValid, - ...field.isValid, - }, - enableSorting: field.enableSorting ?? true, - enableGlobalSearch: field.enableGlobalSearch ?? false, - filterBy: getFilterBy( field, defaultOperators, validOperators ), - format: {}, + render, + Edit: 'number', + sort, + isValid, + enableSorting: true, + enableGlobalSearch: false, + defaultOperators: [ + OPERATOR_IS, + OPERATOR_IS_NOT, + OPERATOR_LESS_THAN, + OPERATOR_GREATER_THAN, + OPERATOR_LESS_THAN_OR_EQUAL, + OPERATOR_GREATER_THAN_OR_EQUAL, + OPERATOR_BETWEEN, + ], + validOperators: [ + // Single-selection + OPERATOR_IS, + OPERATOR_IS_NOT, + OPERATOR_LESS_THAN, + OPERATOR_GREATER_THAN, + OPERATOR_LESS_THAN_OR_EQUAL, + OPERATOR_GREATER_THAN_OR_EQUAL, + OPERATOR_BETWEEN, + // Multiple-selection + OPERATOR_IS_ANY, + OPERATOR_IS_NONE, + OPERATOR_IS_ALL, + OPERATOR_IS_NOT_ALL, + ], + getFormat: () => ( {} ), }; } diff --git a/packages/dataviews/src/field-types/password.tsx b/packages/dataviews/src/field-types/password.tsx index 7a1aed99ca1013..1aba7613ce8f66 100644 --- a/packages/dataviews/src/field-types/password.tsx +++ b/packages/dataviews/src/field-types/password.tsx @@ -1,21 +1,9 @@ /** * Internal dependencies */ -import type { - DataViewRenderFieldProps, - Field, - Rules, - SortDirection, -} from '../types'; +import type { DataViewRenderFieldProps } from '../types'; import type { TypeProvidedProps } from '../types/private'; import RenderFromElements from './utils/render-from-elements'; -import { getControl } from '../dataform-controls'; - -/* eslint-disable-next-line @typescript-eslint/no-unused-vars */ -function sort( _valueA: any, _valueB: any, _direction: SortDirection ) { - // Passwords should not be sortable for security reasons - return 0; -} function render( { item, field }: DataViewRenderFieldProps< any > ) { return field.hasElements ? ( @@ -25,26 +13,20 @@ function render( { item, field }: DataViewRenderFieldProps< any > ) { ); } -const isValid: Rules< any > = { - elements: true, - custom: () => null, -}; - -export default function normalizeField< Item >( - field: Field< Item > -): TypeProvidedProps< Item > { +export default function normalizeField< Item >(): TypeProvidedProps< Item > { return { type: 'password', - render: field.render ?? render, - Edit: getControl( field, 'password' ), - sort: field.sort ?? sort, + render, + Edit: 'password', + sort: () => 0, // Passwords should not be sortable for security reasons isValid: { - ...isValid, - ...field.isValid, + elements: true, + custom: () => null, }, - enableSorting: field.enableSorting ?? false, - enableGlobalSearch: field.enableGlobalSearch ?? false, - filterBy: false, - format: {}, + enableSorting: false, + enableGlobalSearch: false, + defaultOperators: [], + validOperators: [], + getFormat: () => ( {} ), }; } diff --git a/packages/dataviews/src/field-types/telephone.tsx b/packages/dataviews/src/field-types/telephone.tsx index 8b14469a5d494b..b14cdfa8df1784 100644 --- a/packages/dataviews/src/field-types/telephone.tsx +++ b/packages/dataviews/src/field-types/telephone.tsx @@ -1,13 +1,7 @@ /** * Internal dependencies */ -import type { - DataViewRenderFieldProps, - Field, - Operator, - Rules, - SortDirection, -} from '../types'; +import type { DataViewRenderFieldProps, Field, SortDirection } from '../types'; import type { TypeProvidedProps } from '../types/private'; import RenderFromElements from './utils/render-from-elements'; import { @@ -21,9 +15,7 @@ import { OPERATOR_NOT_CONTAINS, OPERATOR_STARTS_WITH, } from '../constants'; -import { getControl } from '../dataform-controls'; import getValueFromId from './utils/get-value-from-id'; -import getFilterBy from './utils/get-filter-by'; function render( { item, field }: DataViewRenderFieldProps< any > ) { return field.hasElements ? ( @@ -33,25 +25,6 @@ function render( { item, field }: DataViewRenderFieldProps< any > ) { ); } -const isValid: Rules< any > = { - elements: true, - custom: () => null, -}; - -const defaultOperators: Operator[] = [ OPERATOR_IS_ANY, OPERATOR_IS_NONE ]; -const validOperators: Operator[] = [ - OPERATOR_IS, - OPERATOR_IS_NOT, - OPERATOR_CONTAINS, - OPERATOR_NOT_CONTAINS, - OPERATOR_STARTS_WITH, - // Multiple selection - OPERATOR_IS_ANY, - OPERATOR_IS_NONE, - OPERATOR_IS_ALL, - OPERATOR_IS_NOT_ALL, -]; - export default function normalizeField< Item >( field: Field< Item > ): TypeProvidedProps< Item > { @@ -67,16 +40,28 @@ export default function normalizeField< Item >( return { type: 'telephone', - render: field.render ?? render, - Edit: getControl( field, 'telephone' ), - sort: field.sort ?? sort, + render, + Edit: 'telephone', + sort, isValid: { - ...isValid, - ...field.isValid, + elements: true, + custom: () => null, }, - enableSorting: field.enableSorting ?? true, - enableGlobalSearch: field.enableGlobalSearch ?? false, - filterBy: getFilterBy( field, defaultOperators, validOperators ), - format: {}, + enableSorting: true, + enableGlobalSearch: false, + defaultOperators: [ OPERATOR_IS_ANY, OPERATOR_IS_NONE ], + validOperators: [ + OPERATOR_IS, + OPERATOR_IS_NOT, + OPERATOR_CONTAINS, + OPERATOR_NOT_CONTAINS, + OPERATOR_STARTS_WITH, + // Multiple selection + OPERATOR_IS_ANY, + OPERATOR_IS_NONE, + OPERATOR_IS_ALL, + OPERATOR_IS_NOT_ALL, + ], + getFormat: () => ( {} ), }; } diff --git a/packages/dataviews/src/field-types/text.tsx b/packages/dataviews/src/field-types/text.tsx index a17336a0670ce7..f77a7a97170494 100644 --- a/packages/dataviews/src/field-types/text.tsx +++ b/packages/dataviews/src/field-types/text.tsx @@ -1,13 +1,7 @@ /** * Internal dependencies */ -import type { - DataViewRenderFieldProps, - Field, - Operator, - Rules, - SortDirection, -} from '../types'; +import type { DataViewRenderFieldProps, Field, SortDirection } from '../types'; import type { TypeProvidedProps } from '../types/private'; import RenderFromElements from './utils/render-from-elements'; import { @@ -21,29 +15,7 @@ import { OPERATOR_NOT_CONTAINS, OPERATOR_STARTS_WITH, } from '../constants'; -import { getControl } from '../dataform-controls'; import getValueFromId from './utils/get-value-from-id'; -import getFilterBy from './utils/get-filter-by'; - -const isValid: Rules< any > = { - elements: true, - custom: () => null, -}; - -const defaultOperators: Operator[] = [ OPERATOR_IS_ANY, OPERATOR_IS_NONE ]; -const validOperators: Operator[] = [ - // Single selection - OPERATOR_IS, - OPERATOR_IS_NOT, - OPERATOR_CONTAINS, - OPERATOR_NOT_CONTAINS, - OPERATOR_STARTS_WITH, - // Multiple selection - OPERATOR_IS_ANY, - OPERATOR_IS_NONE, - OPERATOR_IS_ALL, - OPERATOR_IS_NOT_ALL, -]; function render( { item, field }: DataViewRenderFieldProps< any > ) { return field.hasElements ? ( @@ -68,16 +40,29 @@ export default function normalizeField< Item >( return { type: 'text', - render: field.render ?? render, - Edit: getControl( field, 'text' ), - sort: field.sort ?? sort, + render, + Edit: 'text', + sort, isValid: { - ...isValid, - ...field.isValid, + elements: true, + custom: () => null, }, - enableSorting: field.enableSorting ?? true, - enableGlobalSearch: field.enableGlobalSearch ?? false, - filterBy: getFilterBy( field, defaultOperators, validOperators ), - format: {}, + enableSorting: true, + enableGlobalSearch: false, + defaultOperators: [ OPERATOR_IS_ANY, OPERATOR_IS_NONE ], + validOperators: [ + // Single selection + OPERATOR_IS, + OPERATOR_IS_NOT, + OPERATOR_CONTAINS, + OPERATOR_NOT_CONTAINS, + OPERATOR_STARTS_WITH, + // Multiple selection + OPERATOR_IS_ANY, + OPERATOR_IS_NONE, + OPERATOR_IS_ALL, + OPERATOR_IS_NOT_ALL, + ], + getFormat: () => ( {} ), }; } diff --git a/packages/dataviews/src/field-types/url.tsx b/packages/dataviews/src/field-types/url.tsx index e7716dc5de6794..754e2b25b8b4d5 100644 --- a/packages/dataviews/src/field-types/url.tsx +++ b/packages/dataviews/src/field-types/url.tsx @@ -1,13 +1,7 @@ /** * Internal dependencies */ -import type { - DataViewRenderFieldProps, - Field, - Operator, - Rules, - SortDirection, -} from '../types'; +import type { DataViewRenderFieldProps, Field, SortDirection } from '../types'; import type { TypeProvidedProps } from '../types/private'; import RenderFromElements from './utils/render-from-elements'; import { @@ -21,9 +15,7 @@ import { OPERATOR_NOT_CONTAINS, OPERATOR_STARTS_WITH, } from '../constants'; -import { getControl } from '../dataform-controls'; import getValueFromId from './utils/get-value-from-id'; -import getFilterBy from './utils/get-filter-by'; function render( { item, field }: DataViewRenderFieldProps< any > ) { return field.hasElements ? ( @@ -33,25 +25,6 @@ function render( { item, field }: DataViewRenderFieldProps< any > ) { ); } -const isValid: Rules< any > = { - elements: true, - custom: () => null, -}; - -const defaultOperators: Operator[] = [ OPERATOR_IS_ANY, OPERATOR_IS_NONE ]; -const validOperators: Operator[] = [ - OPERATOR_IS, - OPERATOR_IS_NOT, - OPERATOR_CONTAINS, - OPERATOR_NOT_CONTAINS, - OPERATOR_STARTS_WITH, - // Multiple selection - OPERATOR_IS_ANY, - OPERATOR_IS_NONE, - OPERATOR_IS_ALL, - OPERATOR_IS_NOT_ALL, -]; - export default function normalizeField< Item >( field: Field< Item > ): TypeProvidedProps< Item > { @@ -67,16 +40,28 @@ export default function normalizeField< Item >( return { type: 'url', - render: field.render ?? render, - Edit: getControl( field, 'url' ), - sort: field.sort ?? sort, + render, + Edit: 'url', + sort, isValid: { - ...isValid, - ...field.isValid, + elements: true, + custom: () => null, }, - enableSorting: field.enableSorting ?? true, - enableGlobalSearch: field.enableGlobalSearch ?? false, - filterBy: getFilterBy( field, defaultOperators, validOperators ), - format: {}, + enableSorting: true, + enableGlobalSearch: false, + defaultOperators: [ OPERATOR_IS_ANY, OPERATOR_IS_NONE ], + validOperators: [ + OPERATOR_IS, + OPERATOR_IS_NOT, + OPERATOR_CONTAINS, + OPERATOR_NOT_CONTAINS, + OPERATOR_STARTS_WITH, + // Multiple selection + OPERATOR_IS_ANY, + OPERATOR_IS_NONE, + OPERATOR_IS_ALL, + OPERATOR_IS_NOT_ALL, + ], + getFormat: () => ( {} ), }; } diff --git a/packages/dataviews/src/types/private.ts b/packages/dataviews/src/types/private.ts index 72abc53547fd28..212da614a4ad09 100644 --- a/packages/dataviews/src/types/private.ts +++ b/packages/dataviews/src/types/private.ts @@ -1,7 +1,7 @@ /** * Internal dependencies */ -import type { NormalizedField } from './field-api'; +import type { Field, FormatDate, NormalizedField, Operator } from './field-api'; export type SelectionOrUpdater = string[] | ( ( prev: string[] ) => string[] ); export type SetSelection = ( selection: SelectionOrUpdater ) => void; @@ -9,11 +9,15 @@ export type TypeProvidedProps< Item > = Pick< NormalizedField< Item >, | 'type' | 'render' - | 'Edit' | 'sort' | 'isValid' | 'enableSorting' | 'enableGlobalSearch' - | 'filterBy' - | 'format' ->; +> & { + Edit: string | null; + validOperators: Operator[]; + defaultOperators: Operator[]; + getFormat: ( + field: Field< Item > + ) => Record< string, any > | Required< FormatDate >; +}; From 435e7339907443689138d216e8089c82adef970a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Maneiro?= <583546+oandregal@users.noreply.github.com> Date: Tue, 25 Nov 2025 12:21:56 +0100 Subject: [PATCH 06/15] Types provide sort function, normalizeFields makes sure they get the value --- packages/dataviews/src/field-types/array.tsx | 46 ++++------- .../dataviews/src/field-types/boolean.tsx | 42 ++++------ packages/dataviews/src/field-types/color.tsx | 62 +++++++-------- packages/dataviews/src/field-types/date.tsx | 78 ++++++++----------- .../dataviews/src/field-types/datetime.tsx | 21 ++--- packages/dataviews/src/field-types/email.tsx | 24 ++---- packages/dataviews/src/field-types/index.tsx | 24 ++---- .../dataviews/src/field-types/integer.tsx | 22 ++---- .../src/field-types/normalize-fields.ts | 15 +++- packages/dataviews/src/field-types/number.tsx | 22 ++---- .../dataviews/src/field-types/telephone.tsx | 19 ++--- packages/dataviews/src/field-types/text.tsx | 19 ++--- packages/dataviews/src/field-types/url.tsx | 19 ++--- 13 files changed, 146 insertions(+), 267 deletions(-) diff --git a/packages/dataviews/src/field-types/array.tsx b/packages/dataviews/src/field-types/array.tsx index 6e0085bbc1096a..6225a713885b67 100644 --- a/packages/dataviews/src/field-types/array.tsx +++ b/packages/dataviews/src/field-types/array.tsx @@ -6,12 +6,7 @@ import { __ } from '@wordpress/i18n'; /** * Internal dependencies */ -import type { - DataViewRenderFieldProps, - Field, - Rules, - SortDirection, -} from '../types'; +import type { DataViewRenderFieldProps, Rules, SortDirection } from '../types'; import type { TypeProvidedProps } from '../types/private'; import { OPERATOR_IS_ALL, @@ -19,7 +14,6 @@ import { OPERATOR_IS_NONE, OPERATOR_IS_NOT_ALL, } from '../constants'; -import getValueFromId from './utils/get-value-from-id'; function render( { item, field }: DataViewRenderFieldProps< any > ) { const value = field.getValue( { item } ) || []; @@ -47,30 +41,24 @@ const isValid: Rules< any > = { }, }; -export default function normalizeField< Item >( - field: Field< Item > -): TypeProvidedProps< Item > { - const getValue = field.getValue || getValueFromId( field.id ); - - const sort = ( a: any, b: any, direction: SortDirection ) => { - // Sort arrays by length, then alphabetically by joined string - const valueA = getValue( a ); - const valueB = getValue( b ); - const arrA = Array.isArray( valueA ) ? valueA : []; - const arrB = Array.isArray( valueB ) ? valueB : []; - if ( arrA.length !== arrB.length ) { - return direction === 'asc' - ? arrA.length - arrB.length - : arrB.length - arrA.length; - } - - const joinedA = arrA.join( ',' ); - const joinedB = arrB.join( ',' ); +const sort = ( a: any, b: any, direction: SortDirection ) => { + // Sort arrays by length, then alphabetically by joined string + const arrA = Array.isArray( a ) ? a : []; + const arrB = Array.isArray( b ) ? b : []; + if ( arrA.length !== arrB.length ) { return direction === 'asc' - ? joinedA.localeCompare( joinedB ) - : joinedB.localeCompare( joinedA ); - }; + ? arrA.length - arrB.length + : arrB.length - arrA.length; + } + + const joinedA = arrA.join( ',' ); + const joinedB = arrB.join( ',' ); + return direction === 'asc' + ? joinedA.localeCompare( joinedB ) + : joinedB.localeCompare( joinedA ); +}; +export default function normalizeField< Item >(): TypeProvidedProps< Item > { return { type: 'array', render, diff --git a/packages/dataviews/src/field-types/boolean.tsx b/packages/dataviews/src/field-types/boolean.tsx index 1e1091fd253564..be660b7d0cc02b 100644 --- a/packages/dataviews/src/field-types/boolean.tsx +++ b/packages/dataviews/src/field-types/boolean.tsx @@ -6,16 +6,10 @@ import { __ } from '@wordpress/i18n'; /** * Internal dependencies */ -import type { - DataViewRenderFieldProps, - Field, - Rules, - SortDirection, -} from '../types'; +import type { DataViewRenderFieldProps, Rules, SortDirection } from '../types'; import type { TypeProvidedProps } from '../types/private'; import RenderFromElements from './utils/render-from-elements'; import { OPERATOR_IS, OPERATOR_IS_NOT } from '../constants'; -import getValueFromId from './utils/get-value-from-id'; function render( { item, field }: DataViewRenderFieldProps< any > ) { if ( field.hasElements ) { @@ -49,30 +43,24 @@ const isValid: Rules< any > = { }, }; -export default function normalizeField< Item >( - field: Field< Item > -): TypeProvidedProps< Item > { - const getValue = field.getValue || getValueFromId( field.id ); +const sort = ( a: any, b: any, direction: SortDirection ) => { + const boolA = Boolean( a ); + const boolB = Boolean( b ); - const sort = ( a: any, b: any, direction: SortDirection ) => { - const valueA = getValue( { item: a } ); - const valueB = getValue( { item: b } ); - const boolA = Boolean( valueA ); - const boolB = Boolean( valueB ); - - if ( boolA === boolB ) { - return 0; - } + if ( boolA === boolB ) { + return 0; + } - // In ascending order, false comes before true - if ( direction === 'asc' ) { - return boolA ? 1 : -1; - } + // In ascending order, false comes before true + if ( direction === 'asc' ) { + return boolA ? 1 : -1; + } - // In descending order, true comes before false - return boolA ? -1 : 1; - }; + // In descending order, true comes before false + return boolA ? -1 : 1; +}; +export default function normalizeField< Item >(): TypeProvidedProps< Item > { return { type: 'boolean', render, diff --git a/packages/dataviews/src/field-types/color.tsx b/packages/dataviews/src/field-types/color.tsx index 800098e7654342..33f6aeb0846a8b 100644 --- a/packages/dataviews/src/field-types/color.tsx +++ b/packages/dataviews/src/field-types/color.tsx @@ -11,12 +11,7 @@ import { __ } from '@wordpress/i18n'; /** * Internal dependencies */ -import type { - DataViewRenderFieldProps, - Field, - Rules, - SortDirection, -} from '../types'; +import type { DataViewRenderFieldProps, Rules, SortDirection } from '../types'; import type { TypeProvidedProps } from '../types/private'; import RenderFromElements from './utils/render-from-elements'; import { @@ -25,7 +20,6 @@ import { OPERATOR_IS_NONE, OPERATOR_IS_NOT, } from '../constants'; -import getValueFromId from './utils/get-value-from-id'; function render( { item, field }: DataViewRenderFieldProps< any > ) { if ( field.hasElements ) { @@ -72,39 +66,35 @@ const isValid: Rules< any > = { }, }; -export default function normalizeField< Item >( - field: Field< Item > -): TypeProvidedProps< Item > { - const getValue = field.getValue || getValueFromId( field.id ); +const sort = ( a: any, b: any, direction: SortDirection ) => { + // Convert colors to HSL for better sorting + const colorA = colord( a ); + const colorB = colord( b ); - const sort = ( valueA: any, valueB: any, direction: SortDirection ) => { - // Convert colors to HSL for better sorting - const colorA = colord( getValue( { item: valueA } ) ); - const colorB = colord( getValue( { item: valueB } ) ); - - if ( ! colorA.isValid() && ! colorB.isValid() ) { - return 0; - } - if ( ! colorA.isValid() ) { - return direction === 'asc' ? 1 : -1; - } - if ( ! colorB.isValid() ) { - return direction === 'asc' ? -1 : 1; - } + if ( ! colorA.isValid() && ! colorB.isValid() ) { + return 0; + } + if ( ! colorA.isValid() ) { + return direction === 'asc' ? 1 : -1; + } + if ( ! colorB.isValid() ) { + return direction === 'asc' ? -1 : 1; + } - // Sort by hue, then saturation, then lightness - const hslA = colorA.toHsl(); - const hslB = colorB.toHsl(); + // Sort by hue, then saturation, then lightness + const hslA = colorA.toHsl(); + const hslB = colorB.toHsl(); - if ( hslA.h !== hslB.h ) { - return direction === 'asc' ? hslA.h - hslB.h : hslB.h - hslA.h; - } - if ( hslA.s !== hslB.s ) { - return direction === 'asc' ? hslA.s - hslB.s : hslB.s - hslA.s; - } - return direction === 'asc' ? hslA.l - hslB.l : hslB.l - hslA.l; - }; + if ( hslA.h !== hslB.h ) { + return direction === 'asc' ? hslA.h - hslB.h : hslB.h - hslA.h; + } + if ( hslA.s !== hslB.s ) { + return direction === 'asc' ? hslA.s - hslB.s : hslB.s - hslA.s; + } + return direction === 'asc' ? hslA.l - hslB.l : hslB.l - hslA.l; +}; +export default function normalizeField< Item >(): TypeProvidedProps< Item > { return { type: 'color', render, diff --git a/packages/dataviews/src/field-types/date.tsx b/packages/dataviews/src/field-types/date.tsx index f292a4c2a88562..72c5f065b83e78 100644 --- a/packages/dataviews/src/field-types/date.tsx +++ b/packages/dataviews/src/field-types/date.tsx @@ -10,8 +10,6 @@ import type { DataViewRenderFieldProps, Field, FormatDate, - Operator, - Rules, SortDirection, } from '../types'; import type { TypeProvidedProps } from '../types/private'; @@ -28,7 +26,6 @@ import { OPERATOR_BETWEEN, DAYS_OF_WEEK, } from '../constants'; -import getValueFromId from './utils/get-value-from-id'; function getFormat< Item >( field: Field< Item > ): Required< FormatDate > { return { @@ -70,58 +67,47 @@ function render( { item, field }: DataViewRenderFieldProps< any > ) { return dateI18n( format.date, getDate( value ) ); } -const isValid: Rules< any > = { - elements: true, - custom: () => null, -}; - -const defaultOperators: Operator[] = [ - OPERATOR_ON, - OPERATOR_NOT_ON, - OPERATOR_BEFORE, - OPERATOR_AFTER, - OPERATOR_BEFORE_INC, - OPERATOR_AFTER_INC, - OPERATOR_IN_THE_PAST, - OPERATOR_OVER, - OPERATOR_BETWEEN, -]; -const validOperators: Operator[] = [ - OPERATOR_ON, - OPERATOR_NOT_ON, - OPERATOR_BEFORE, - OPERATOR_AFTER, - OPERATOR_BEFORE_INC, - OPERATOR_AFTER_INC, - OPERATOR_IN_THE_PAST, - OPERATOR_OVER, - OPERATOR_BETWEEN, -]; - -export default function normalizeField< Item >( - field: Field< Item > -): TypeProvidedProps< Item > { - const getValue = field.getValue || getValueFromId( field.id ); +const sort = ( a: any, b: any, direction: SortDirection ) => { + const timeA = new Date( a ).getTime(); + const timeB = new Date( b ).getTime(); - const sort = ( a: Item, b: Item, direction: SortDirection ) => { - const valueA = getValue( { item: a } ); - const valueB = getValue( { item: b } ); - const timeA = new Date( valueA ).getTime(); - const timeB = new Date( valueB ).getTime(); - - return direction === 'asc' ? timeA - timeB : timeB - timeA; - }; + return direction === 'asc' ? timeA - timeB : timeB - timeA; +}; +export default function normalizeField< Item >(): TypeProvidedProps< Item > { return { type: 'date', render, Edit: 'date', sort, - isValid, + isValid: { + elements: true, + custom: () => null, + }, enableSorting: true, enableGlobalSearch: false, - defaultOperators, - validOperators, + defaultOperators: [ + OPERATOR_ON, + OPERATOR_NOT_ON, + OPERATOR_BEFORE, + OPERATOR_AFTER, + OPERATOR_BEFORE_INC, + OPERATOR_AFTER_INC, + OPERATOR_IN_THE_PAST, + OPERATOR_OVER, + OPERATOR_BETWEEN, + ], + validOperators: [ + OPERATOR_ON, + OPERATOR_NOT_ON, + OPERATOR_BEFORE, + OPERATOR_AFTER, + OPERATOR_BEFORE_INC, + OPERATOR_AFTER_INC, + OPERATOR_IN_THE_PAST, + OPERATOR_OVER, + OPERATOR_BETWEEN, + ], getFormat, }; } diff --git a/packages/dataviews/src/field-types/datetime.tsx b/packages/dataviews/src/field-types/datetime.tsx index 01f517247cec5b..b5b36b585ff452 100644 --- a/packages/dataviews/src/field-types/datetime.tsx +++ b/packages/dataviews/src/field-types/datetime.tsx @@ -1,7 +1,7 @@ /** * Internal dependencies */ -import type { DataViewRenderFieldProps, Field, SortDirection } from '../types'; +import type { DataViewRenderFieldProps, SortDirection } from '../types'; import type { TypeProvidedProps } from '../types/private'; import RenderFromElements from './utils/render-from-elements'; import parseDateTime from './utils/parse-date-time'; @@ -15,7 +15,6 @@ import { OPERATOR_IN_THE_PAST, OPERATOR_OVER, } from '../constants'; -import getValueFromId from './utils/get-value-from-id'; function render( { item, field }: DataViewRenderFieldProps< any > ) { if ( field.elements ) { @@ -35,20 +34,14 @@ function render( { item, field }: DataViewRenderFieldProps< any > ) { } } -export default function normalizeField< Item >( - field: Field< Item > -): TypeProvidedProps< Item > { - const getValue = field.getValue || getValueFromId( field.id ); +const sort = ( a: any, b: any, direction: SortDirection ) => { + const timeA = new Date( a ).getTime(); + const timeB = new Date( b ).getTime(); - const sort = ( a: Item, b: Item, direction: SortDirection ) => { - const valueA = getValue( { item: a } ); - const valueB = getValue( { item: b } ); - const timeA = new Date( valueA ).getTime(); - const timeB = new Date( valueB ).getTime(); - - return direction === 'asc' ? timeA - timeB : timeB - timeA; - }; + return direction === 'asc' ? timeA - timeB : timeB - timeA; +}; +export default function normalizeField< Item >(): TypeProvidedProps< Item > { return { type: 'datetime', render, diff --git a/packages/dataviews/src/field-types/email.tsx b/packages/dataviews/src/field-types/email.tsx index 15120893eae296..e89d7757d8a793 100644 --- a/packages/dataviews/src/field-types/email.tsx +++ b/packages/dataviews/src/field-types/email.tsx @@ -6,12 +6,7 @@ import { __ } from '@wordpress/i18n'; /** * Internal dependencies */ -import type { - DataViewRenderFieldProps, - Field, - Rules, - SortDirection, -} from '../types'; +import type { DataViewRenderFieldProps, Rules, SortDirection } from '../types'; import type { TypeProvidedProps } from '../types/private'; import RenderFromElements from './utils/render-from-elements'; import { @@ -25,7 +20,6 @@ import { OPERATOR_NOT_CONTAINS, OPERATOR_STARTS_WITH, } from '../constants'; -import getValueFromId from './utils/get-value-from-id'; // Email validation regex based on HTML5 spec // https://html.spec.whatwg.org/multipage/input.html#valid-e-mail-address @@ -56,19 +50,11 @@ const isValid: Rules< any > = { }, }; -export default function normalizeField< Item >( - field: Field< Item > -): TypeProvidedProps< Item > { - const getValue = field.getValue || getValueFromId( field.id ); - - const sort = ( a: any, b: any, direction: SortDirection ) => { - const valueA = getValue( { item: a } ); - const valueB = getValue( { item: b } ); - return direction === 'asc' - ? valueA.localeCompare( valueB ) - : valueB.localeCompare( valueA ); - }; +const sort = ( a: any, b: any, direction: SortDirection ) => { + return direction === 'asc' ? a.localeCompare( b ) : b.localeCompare( a ); +}; +export default function normalizeField< Item >(): TypeProvidedProps< Item > { return { type: 'email', render, diff --git a/packages/dataviews/src/field-types/index.tsx b/packages/dataviews/src/field-types/index.tsx index 368985191a5484..e8563887b8416f 100644 --- a/packages/dataviews/src/field-types/index.tsx +++ b/packages/dataviews/src/field-types/index.tsx @@ -23,7 +23,6 @@ import { default as color } from './color'; import { default as url } from './url'; import RenderFromElements from './utils/render-from-elements'; import { ALL_OPERATORS, OPERATOR_IS, OPERATOR_IS_NOT } from '../constants'; -import getValueFromId from './utils/get-value-from-id'; const render = ( { item, @@ -36,24 +35,15 @@ const render = ( { ); }; -function normalizeField< Item >( - field: Field< Item > -): TypeProvidedProps< Item > { - const getValue = field.getValue || getValueFromId( field.id ); - - const sort = ( a: any, b: any, direction: SortDirection ) => { - const valueA = getValue( { item: a } ); - const valueB = getValue( { item: b } ); - - if ( typeof valueA === 'number' && typeof valueB === 'number' ) { - return direction === 'asc' ? valueA - valueB : valueB - valueA; - } +const sort = ( a: any, b: any, direction: SortDirection ) => { + if ( typeof a === 'number' && typeof b === 'number' ) { + return direction === 'asc' ? a - b : b - a; + } - return direction === 'asc' - ? valueA.localeCompare( valueB ) - : valueB.localeCompare( valueA ); - }; + return direction === 'asc' ? a.localeCompare( b ) : b.localeCompare( a ); +}; +function normalizeField< Item >(): TypeProvidedProps< Item > { return { // type: no type for this render, diff --git a/packages/dataviews/src/field-types/integer.tsx b/packages/dataviews/src/field-types/integer.tsx index 111fd324dcef21..52e723166b6510 100644 --- a/packages/dataviews/src/field-types/integer.tsx +++ b/packages/dataviews/src/field-types/integer.tsx @@ -6,12 +6,7 @@ import { __ } from '@wordpress/i18n'; /** * Internal dependencies */ -import type { - DataViewRenderFieldProps, - Field, - Rules, - SortDirection, -} from '../types'; +import type { DataViewRenderFieldProps, Rules, SortDirection } from '../types'; import type { TypeProvidedProps } from '../types/private'; import RenderFromElements from './utils/render-from-elements'; import { @@ -27,7 +22,6 @@ import { OPERATOR_IS_NOT_ALL, OPERATOR_BETWEEN, } from '../constants'; -import getValueFromId from './utils/get-value-from-id'; function render( { item, field }: DataViewRenderFieldProps< any > ) { return field.hasElements ? ( @@ -52,17 +46,11 @@ const isValid: Rules< any > = { }, }; -export default function normalizeField< Item >( - field: Field< Item > -): TypeProvidedProps< Item > { - const getValue = field.getValue || getValueFromId( field.id ); - - const sort = ( a: Item, b: Item, direction: SortDirection ) => { - const valueA = getValue( { item: a } ); - const valueB = getValue( { item: b } ); - return direction === 'asc' ? valueA - valueB : valueB - valueA; - }; +const sort = ( a: any, b: any, direction: SortDirection ) => { + return direction === 'asc' ? a - b : b - a; +}; +export default function normalizeField< Item >(): TypeProvidedProps< Item > { return { type: 'integer', render, diff --git a/packages/dataviews/src/field-types/normalize-fields.ts b/packages/dataviews/src/field-types/normalize-fields.ts index 7cc7f775039f1f..48f47964bebc15 100644 --- a/packages/dataviews/src/field-types/normalize-fields.ts +++ b/packages/dataviews/src/field-types/normalize-fields.ts @@ -7,7 +7,7 @@ */ import getNormalizeFieldFunction from '.'; import { getControl } from '../dataform-controls'; -import type { Field, NormalizedField } from '../types'; +import type { Field, NormalizedField, SortDirection } from '../types'; import getFilterBy from './utils/get-filter-by'; import getValueFromId from './utils/get-value-from-id'; import hasElements from './utils/has-elements'; @@ -26,13 +26,22 @@ export default function normalizeFields< Item >( const normalize = getNormalizeFieldFunction< Item >( field.type ); const defaultProps = normalize( field ); + const getValue = field.getValue || getValueFromId( field.id ); + const sort = function ( a: any, b: any, direction: SortDirection ) { + const aValue = getValue( a ); + const bValue = getValue( b ); + return field.sort + ? field.sort( aValue, bValue, direction ) + : defaultProps.sort( aValue, bValue, direction ); + }; + return { id: field.id, label: field.label || field.id, header: field.header || field.label || field.id, description: field.description, placeholder: field.placeholder, - getValue: field.getValue || getValueFromId( field.id ), + getValue, setValue: field.setValue || setValueFromId( field.id ), elements: field.elements, getElements: field.getElements, @@ -44,7 +53,7 @@ export default function normalizeFields< Item >( type: defaultProps.type, render: field.render ?? defaultProps.render, Edit: getControl( field, defaultProps.Edit ), - sort: field.sort ?? defaultProps.sort, + sort, enableSorting: field.enableSorting ?? defaultProps.enableSorting, enableGlobalSearch: field.enableGlobalSearch ?? defaultProps.enableGlobalSearch, diff --git a/packages/dataviews/src/field-types/number.tsx b/packages/dataviews/src/field-types/number.tsx index 07dcb5caf930d5..ae56965bd94c83 100644 --- a/packages/dataviews/src/field-types/number.tsx +++ b/packages/dataviews/src/field-types/number.tsx @@ -6,12 +6,7 @@ import { __ } from '@wordpress/i18n'; /** * Internal dependencies */ -import type { - DataViewRenderFieldProps, - Field, - Rules, - SortDirection, -} from '../types'; +import type { DataViewRenderFieldProps, Rules, SortDirection } from '../types'; import type { TypeProvidedProps } from '../types/private'; import { OPERATOR_IS, @@ -27,7 +22,6 @@ import { OPERATOR_BETWEEN, } from '../constants'; import RenderFromElements from './utils/render-from-elements'; -import getValueFromId from './utils/get-value-from-id'; function isEmpty( value: unknown ): value is '' | undefined | null { return value === '' || value === undefined || value === null; @@ -59,17 +53,11 @@ const isValid: Rules< any > = { }, }; -export default function normalizeField< Item >( - field: Field< Item > -): TypeProvidedProps< Item > { - const getValue = field.getValue || getValueFromId( field.id ); - - const sort = ( a: Item, b: Item, direction: SortDirection ) => { - const valueA = getValue( { item: a } ); - const valueB = getValue( { item: b } ); - return direction === 'asc' ? valueA - valueB : valueB - valueA; - }; +const sort = ( a: any, b: any, direction: SortDirection ) => { + return direction === 'asc' ? a - b : b - a; +}; +export default function normalizeField< Item >(): TypeProvidedProps< Item > { return { type: 'number', render, diff --git a/packages/dataviews/src/field-types/telephone.tsx b/packages/dataviews/src/field-types/telephone.tsx index b14cdfa8df1784..d47aed45e80ff0 100644 --- a/packages/dataviews/src/field-types/telephone.tsx +++ b/packages/dataviews/src/field-types/telephone.tsx @@ -1,7 +1,7 @@ /** * Internal dependencies */ -import type { DataViewRenderFieldProps, Field, SortDirection } from '../types'; +import type { DataViewRenderFieldProps, SortDirection } from '../types'; import type { TypeProvidedProps } from '../types/private'; import RenderFromElements from './utils/render-from-elements'; import { @@ -15,7 +15,6 @@ import { OPERATOR_NOT_CONTAINS, OPERATOR_STARTS_WITH, } from '../constants'; -import getValueFromId from './utils/get-value-from-id'; function render( { item, field }: DataViewRenderFieldProps< any > ) { return field.hasElements ? ( @@ -25,19 +24,11 @@ function render( { item, field }: DataViewRenderFieldProps< any > ) { ); } -export default function normalizeField< Item >( - field: Field< Item > -): TypeProvidedProps< Item > { - const getValue = field.getValue || getValueFromId( field.id ); - - const sort = ( a: any, b: any, direction: SortDirection ) => { - const valueA = getValue( { item: a } ); - const valueB = getValue( { item: b } ); - return direction === 'asc' - ? valueA.localeCompare( valueB ) - : valueB.localeCompare( valueA ); - }; +const sort = ( a: any, b: any, direction: SortDirection ) => { + return direction === 'asc' ? a.localeCompare( b ) : b.localeCompare( a ); +}; +export default function normalizeField< Item >(): TypeProvidedProps< Item > { return { type: 'telephone', render, diff --git a/packages/dataviews/src/field-types/text.tsx b/packages/dataviews/src/field-types/text.tsx index f77a7a97170494..f0e39611517b3c 100644 --- a/packages/dataviews/src/field-types/text.tsx +++ b/packages/dataviews/src/field-types/text.tsx @@ -1,7 +1,7 @@ /** * Internal dependencies */ -import type { DataViewRenderFieldProps, Field, SortDirection } from '../types'; +import type { DataViewRenderFieldProps, SortDirection } from '../types'; import type { TypeProvidedProps } from '../types/private'; import RenderFromElements from './utils/render-from-elements'; import { @@ -15,7 +15,6 @@ import { OPERATOR_NOT_CONTAINS, OPERATOR_STARTS_WITH, } from '../constants'; -import getValueFromId from './utils/get-value-from-id'; function render( { item, field }: DataViewRenderFieldProps< any > ) { return field.hasElements ? ( @@ -25,19 +24,11 @@ function render( { item, field }: DataViewRenderFieldProps< any > ) { ); } -export default function normalizeField< Item >( - field: Field< Item > -): TypeProvidedProps< Item > { - const getValue = field.getValue || getValueFromId( field.id ); - - const sort = ( a: Item, b: Item, direction: SortDirection ) => { - const valueA = getValue( { item: a } ); - const valueB = getValue( { item: b } ); - return direction === 'asc' - ? valueA.localeCompare( valueB ) - : valueB.localeCompare( valueA ); - }; +const sort = ( a: any, b: any, direction: SortDirection ) => { + return direction === 'asc' ? a.localeCompare( b ) : b.localeCompare( a ); +}; +export default function normalizeField< Item >(): TypeProvidedProps< Item > { return { type: 'text', render, diff --git a/packages/dataviews/src/field-types/url.tsx b/packages/dataviews/src/field-types/url.tsx index 754e2b25b8b4d5..2aa38ae357d6b2 100644 --- a/packages/dataviews/src/field-types/url.tsx +++ b/packages/dataviews/src/field-types/url.tsx @@ -1,7 +1,7 @@ /** * Internal dependencies */ -import type { DataViewRenderFieldProps, Field, SortDirection } from '../types'; +import type { DataViewRenderFieldProps, SortDirection } from '../types'; import type { TypeProvidedProps } from '../types/private'; import RenderFromElements from './utils/render-from-elements'; import { @@ -15,7 +15,6 @@ import { OPERATOR_NOT_CONTAINS, OPERATOR_STARTS_WITH, } from '../constants'; -import getValueFromId from './utils/get-value-from-id'; function render( { item, field }: DataViewRenderFieldProps< any > ) { return field.hasElements ? ( @@ -25,19 +24,11 @@ function render( { item, field }: DataViewRenderFieldProps< any > ) { ); } -export default function normalizeField< Item >( - field: Field< Item > -): TypeProvidedProps< Item > { - const getValue = field.getValue || getValueFromId( field.id ); - - const sort = ( a: any, b: any, direction: SortDirection ) => { - const valueA = getValue( { item: a } ); - const valueB = getValue( { item: b } ); - return direction === 'asc' - ? valueA.localeCompare( valueB ) - : valueB.localeCompare( valueA ); - }; +const sort = ( a: any, b: any, direction: SortDirection ) => { + return direction === 'asc' ? a.localeCompare( b ) : b.localeCompare( a ); +}; +export default function normalizeField< Item >(): TypeProvidedProps< Item > { return { type: 'url', render, From effa8ac21de363f246417e6094ade721d7c78c6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Maneiro?= <583546+oandregal@users.noreply.github.com> Date: Tue, 25 Nov 2025 12:34:42 +0100 Subject: [PATCH 07/15] Remove normalize fn for type, return default props instead --- .../src/components/dataform/index.tsx | 2 +- .../src/components/dataviews-picker/index.tsx | 2 +- .../src/components/dataviews/index.tsx | 2 +- packages/dataviews/src/field-types/array.tsx | 36 +++--- .../dataviews/src/field-types/boolean.tsx | 26 ++--- packages/dataviews/src/field-types/color.tsx | 36 +++--- packages/dataviews/src/field-types/date.tsx | 72 ++++++------ .../dataviews/src/field-types/datetime.tsx | 68 ++++++----- packages/dataviews/src/field-types/email.tsx | 48 ++++---- packages/dataviews/src/field-types/index.tsx | 110 +++++++++++------- .../dataviews/src/field-types/integer.tsx | 70 ++++++----- packages/dataviews/src/field-types/media.tsx | 32 +++-- .../dataviews/src/field-types/no-type.tsx | 42 +++++++ .../src/field-types/normalize-fields.ts | 72 ------------ packages/dataviews/src/field-types/number.tsx | 70 ++++++----- .../dataviews/src/field-types/password.tsx | 32 +++-- .../dataviews/src/field-types/telephone.tsx | 54 +++++---- packages/dataviews/src/field-types/text.tsx | 56 +++++---- packages/dataviews/src/field-types/url.tsx | 54 +++++---- .../dataviews/src/hooks/use-form-validity.ts | 2 +- .../dataviews/src/test/normalize-fields.ts | 2 +- .../src/utils/filter-sort-and-paginate.ts | 2 +- 22 files changed, 429 insertions(+), 461 deletions(-) create mode 100644 packages/dataviews/src/field-types/no-type.tsx delete mode 100644 packages/dataviews/src/field-types/normalize-fields.ts diff --git a/packages/dataviews/src/components/dataform/index.tsx b/packages/dataviews/src/components/dataform/index.tsx index f31c1db09de91c..65f4aad3fb7c5e 100644 --- a/packages/dataviews/src/components/dataform/index.tsx +++ b/packages/dataviews/src/components/dataform/index.tsx @@ -8,7 +8,7 @@ import { useMemo } from '@wordpress/element'; */ import type { DataFormProps } from '../../types'; import { DataFormProvider } from '../dataform-context'; -import normalizeFields from '../../field-types/normalize-fields'; +import normalizeFields from '../../field-types'; import { DataFormLayout } from '../../dataform-layouts/data-form-layout'; import normalizeForm from '../../dataform-layouts/normalize-form'; diff --git a/packages/dataviews/src/components/dataviews-picker/index.tsx b/packages/dataviews/src/components/dataviews-picker/index.tsx index 258f0d68d7e8a0..11e64ee9b21312 100644 --- a/packages/dataviews/src/components/dataviews-picker/index.tsx +++ b/packages/dataviews/src/components/dataviews-picker/index.tsx @@ -29,7 +29,7 @@ import DataViewsViewConfig, { DataviewsViewConfigDropdown, ViewTypeMenu, } from '../dataviews-view-config'; -import normalizeFields from '../../field-types/normalize-fields'; +import normalizeFields from '../../field-types'; import type { ActionButton, Field, View, SupportedLayouts } from '../../types'; import type { SelectionOrUpdater } from '../../types/private'; type ItemWithId = { id: string }; diff --git a/packages/dataviews/src/components/dataviews/index.tsx b/packages/dataviews/src/components/dataviews/index.tsx index bf8dbf539b5328..b3200b36b1045a 100644 --- a/packages/dataviews/src/components/dataviews/index.tsx +++ b/packages/dataviews/src/components/dataviews/index.tsx @@ -30,7 +30,7 @@ import DataViewsViewConfig, { DataviewsViewConfigDropdown, ViewTypeMenu, } from '../dataviews-view-config'; -import normalizeFields from '../../field-types/normalize-fields'; +import normalizeFields from '../../field-types'; import type { Action, Field, View, SupportedLayouts } from '../../types'; import type { SelectionOrUpdater } from '../../types/private'; type ItemWithId = { id: string }; diff --git a/packages/dataviews/src/field-types/array.tsx b/packages/dataviews/src/field-types/array.tsx index 6225a713885b67..4ac1f85a007633 100644 --- a/packages/dataviews/src/field-types/array.tsx +++ b/packages/dataviews/src/field-types/array.tsx @@ -58,22 +58,20 @@ const sort = ( a: any, b: any, direction: SortDirection ) => { : joinedB.localeCompare( joinedA ); }; -export default function normalizeField< Item >(): TypeProvidedProps< Item > { - return { - type: 'array', - render, - Edit: 'array', - sort, - isValid, - enableSorting: true, - enableGlobalSearch: false, - defaultOperators: [ OPERATOR_IS_ANY, OPERATOR_IS_NONE ], - validOperators: [ - OPERATOR_IS_ANY, - OPERATOR_IS_NONE, - OPERATOR_IS_ALL, - OPERATOR_IS_NOT_ALL, - ], - getFormat: () => ( {} ), - }; -} +export default { + type: 'array', + render, + Edit: 'array', + sort, + isValid, + enableSorting: true, + enableGlobalSearch: false, + defaultOperators: [ OPERATOR_IS_ANY, OPERATOR_IS_NONE ], + validOperators: [ + OPERATOR_IS_ANY, + OPERATOR_IS_NONE, + OPERATOR_IS_ALL, + OPERATOR_IS_NOT_ALL, + ], + getFormat: () => ( {} ), +} satisfies TypeProvidedProps< any >; diff --git a/packages/dataviews/src/field-types/boolean.tsx b/packages/dataviews/src/field-types/boolean.tsx index be660b7d0cc02b..a811dd1a107d0d 100644 --- a/packages/dataviews/src/field-types/boolean.tsx +++ b/packages/dataviews/src/field-types/boolean.tsx @@ -60,17 +60,15 @@ const sort = ( a: any, b: any, direction: SortDirection ) => { return boolA ? -1 : 1; }; -export default function normalizeField< Item >(): TypeProvidedProps< Item > { - return { - type: 'boolean', - render, - Edit: 'checkbox', - sort, - isValid, - enableSorting: true, - enableGlobalSearch: false, - defaultOperators: [ OPERATOR_IS, OPERATOR_IS_NOT ], - validOperators: [ OPERATOR_IS, OPERATOR_IS_NOT ], - getFormat: () => ( {} ), - }; -} +export default { + type: 'boolean', + render, + Edit: 'checkbox', + sort, + isValid, + enableSorting: true, + enableGlobalSearch: false, + defaultOperators: [ OPERATOR_IS, OPERATOR_IS_NOT ], + validOperators: [ OPERATOR_IS, OPERATOR_IS_NOT ], + getFormat: () => ( {} ), +} satisfies TypeProvidedProps< any >; diff --git a/packages/dataviews/src/field-types/color.tsx b/packages/dataviews/src/field-types/color.tsx index 33f6aeb0846a8b..ca69241ac0ca9a 100644 --- a/packages/dataviews/src/field-types/color.tsx +++ b/packages/dataviews/src/field-types/color.tsx @@ -94,22 +94,20 @@ const sort = ( a: any, b: any, direction: SortDirection ) => { return direction === 'asc' ? hslA.l - hslB.l : hslB.l - hslA.l; }; -export default function normalizeField< Item >(): TypeProvidedProps< Item > { - return { - type: 'color', - render, - Edit: 'color', - sort, - isValid, - enableSorting: true, - enableGlobalSearch: false, - defaultOperators: [ OPERATOR_IS_ANY, OPERATOR_IS_NONE ], - validOperators: [ - OPERATOR_IS, - OPERATOR_IS_NOT, - OPERATOR_IS_ANY, - OPERATOR_IS_NONE, - ], - getFormat: () => ( {} ), - }; -} +export default { + type: 'color', + render, + Edit: 'color', + sort, + isValid, + enableSorting: true, + enableGlobalSearch: false, + defaultOperators: [ OPERATOR_IS_ANY, OPERATOR_IS_NONE ], + validOperators: [ + OPERATOR_IS, + OPERATOR_IS_NOT, + OPERATOR_IS_ANY, + OPERATOR_IS_NONE, + ], + getFormat: () => ( {} ), +} satisfies TypeProvidedProps< any >; diff --git a/packages/dataviews/src/field-types/date.tsx b/packages/dataviews/src/field-types/date.tsx index 72c5f065b83e78..74c3953ca245e4 100644 --- a/packages/dataviews/src/field-types/date.tsx +++ b/packages/dataviews/src/field-types/date.tsx @@ -74,40 +74,38 @@ const sort = ( a: any, b: any, direction: SortDirection ) => { return direction === 'asc' ? timeA - timeB : timeB - timeA; }; -export default function normalizeField< Item >(): TypeProvidedProps< Item > { - return { - type: 'date', - render, - Edit: 'date', - sort, - isValid: { - elements: true, - custom: () => null, - }, - enableSorting: true, - enableGlobalSearch: false, - defaultOperators: [ - OPERATOR_ON, - OPERATOR_NOT_ON, - OPERATOR_BEFORE, - OPERATOR_AFTER, - OPERATOR_BEFORE_INC, - OPERATOR_AFTER_INC, - OPERATOR_IN_THE_PAST, - OPERATOR_OVER, - OPERATOR_BETWEEN, - ], - validOperators: [ - OPERATOR_ON, - OPERATOR_NOT_ON, - OPERATOR_BEFORE, - OPERATOR_AFTER, - OPERATOR_BEFORE_INC, - OPERATOR_AFTER_INC, - OPERATOR_IN_THE_PAST, - OPERATOR_OVER, - OPERATOR_BETWEEN, - ], - getFormat, - }; -} +export default { + type: 'date', + render, + Edit: 'date', + sort, + isValid: { + elements: true, + custom: () => null, + }, + enableSorting: true, + enableGlobalSearch: false, + defaultOperators: [ + OPERATOR_ON, + OPERATOR_NOT_ON, + OPERATOR_BEFORE, + OPERATOR_AFTER, + OPERATOR_BEFORE_INC, + OPERATOR_AFTER_INC, + OPERATOR_IN_THE_PAST, + OPERATOR_OVER, + OPERATOR_BETWEEN, + ], + validOperators: [ + OPERATOR_ON, + OPERATOR_NOT_ON, + OPERATOR_BEFORE, + OPERATOR_AFTER, + OPERATOR_BEFORE_INC, + OPERATOR_AFTER_INC, + OPERATOR_IN_THE_PAST, + OPERATOR_OVER, + OPERATOR_BETWEEN, + ], + getFormat, +} satisfies TypeProvidedProps< any >; diff --git a/packages/dataviews/src/field-types/datetime.tsx b/packages/dataviews/src/field-types/datetime.tsx index b5b36b585ff452..dce78918a3db03 100644 --- a/packages/dataviews/src/field-types/datetime.tsx +++ b/packages/dataviews/src/field-types/datetime.tsx @@ -41,38 +41,36 @@ const sort = ( a: any, b: any, direction: SortDirection ) => { return direction === 'asc' ? timeA - timeB : timeB - timeA; }; -export default function normalizeField< Item >(): TypeProvidedProps< Item > { - return { - type: 'datetime', - render, - Edit: 'datetime', - sort, - isValid: { - elements: true, - custom: () => null, - }, - enableSorting: true, - enableGlobalSearch: false, - defaultOperators: [ - OPERATOR_ON, - OPERATOR_NOT_ON, - OPERATOR_BEFORE, - OPERATOR_AFTER, - OPERATOR_BEFORE_INC, - OPERATOR_AFTER_INC, - OPERATOR_IN_THE_PAST, - OPERATOR_OVER, - ], - validOperators: [ - OPERATOR_ON, - OPERATOR_NOT_ON, - OPERATOR_BEFORE, - OPERATOR_AFTER, - OPERATOR_BEFORE_INC, - OPERATOR_AFTER_INC, - OPERATOR_IN_THE_PAST, - OPERATOR_OVER, - ], - getFormat: () => ( {} ), - }; -} +export default { + type: 'datetime', + render, + Edit: 'datetime', + sort, + isValid: { + elements: true, + custom: () => null, + }, + enableSorting: true, + enableGlobalSearch: false, + defaultOperators: [ + OPERATOR_ON, + OPERATOR_NOT_ON, + OPERATOR_BEFORE, + OPERATOR_AFTER, + OPERATOR_BEFORE_INC, + OPERATOR_AFTER_INC, + OPERATOR_IN_THE_PAST, + OPERATOR_OVER, + ], + validOperators: [ + OPERATOR_ON, + OPERATOR_NOT_ON, + OPERATOR_BEFORE, + OPERATOR_AFTER, + OPERATOR_BEFORE_INC, + OPERATOR_AFTER_INC, + OPERATOR_IN_THE_PAST, + OPERATOR_OVER, + ], + getFormat: () => ( {} ), +} satisfies TypeProvidedProps< any >; diff --git a/packages/dataviews/src/field-types/email.tsx b/packages/dataviews/src/field-types/email.tsx index e89d7757d8a793..4aa6a4d4d40206 100644 --- a/packages/dataviews/src/field-types/email.tsx +++ b/packages/dataviews/src/field-types/email.tsx @@ -54,28 +54,26 @@ const sort = ( a: any, b: any, direction: SortDirection ) => { return direction === 'asc' ? a.localeCompare( b ) : b.localeCompare( a ); }; -export default function normalizeField< Item >(): TypeProvidedProps< Item > { - return { - type: 'email', - render, - Edit: 'email', - sort, - isValid, - enableSorting: true, - enableGlobalSearch: false, - defaultOperators: [ OPERATOR_IS_ANY, OPERATOR_IS_NONE ], - validOperators: [ - OPERATOR_IS, - OPERATOR_IS_NOT, - OPERATOR_CONTAINS, - OPERATOR_NOT_CONTAINS, - OPERATOR_STARTS_WITH, - // Multiple selection - OPERATOR_IS_ANY, - OPERATOR_IS_NONE, - OPERATOR_IS_ALL, - OPERATOR_IS_NOT_ALL, - ], - getFormat: () => ( {} ), - }; -} +export default { + type: 'email', + render, + Edit: 'email', + sort, + isValid, + enableSorting: true, + enableGlobalSearch: false, + defaultOperators: [ OPERATOR_IS_ANY, OPERATOR_IS_NONE ], + validOperators: [ + OPERATOR_IS, + OPERATOR_IS_NOT, + OPERATOR_CONTAINS, + OPERATOR_NOT_CONTAINS, + OPERATOR_STARTS_WITH, + // Multiple selection + OPERATOR_IS_ANY, + OPERATOR_IS_NONE, + OPERATOR_IS_ALL, + OPERATOR_IS_NOT_ALL, + ], + getFormat: () => ( {} ), +} satisfies TypeProvidedProps< any >; diff --git a/packages/dataviews/src/field-types/index.tsx b/packages/dataviews/src/field-types/index.tsx index e8563887b8416f..95b9c7123e3918 100644 --- a/packages/dataviews/src/field-types/index.tsx +++ b/packages/dataviews/src/field-types/index.tsx @@ -2,12 +2,17 @@ * Internal dependencies */ import type { - DataViewRenderFieldProps, Field, FieldType, + NormalizedField, SortDirection, } from '../types'; import type { TypeProvidedProps } from '../types/private'; +import { getControl } from '../dataform-controls'; +import getFilterBy from './utils/get-filter-by'; +import getValueFromId from './utils/get-value-from-id'; +import hasElements from './utils/has-elements'; +import setValueFromId from './utils/set-value-from-id'; import { default as email } from './email'; import { default as integer } from './integer'; import { default as number } from './number'; @@ -21,45 +26,7 @@ import { default as password } from './password'; import { default as telephone } from './telephone'; import { default as color } from './color'; import { default as url } from './url'; -import RenderFromElements from './utils/render-from-elements'; -import { ALL_OPERATORS, OPERATOR_IS, OPERATOR_IS_NOT } from '../constants'; - -const render = ( { - item, - field: normalizedField, -}: DataViewRenderFieldProps< any > ) => { - return normalizedField.hasElements ? ( - - ) : ( - normalizedField.getValue( { item } ) - ); -}; - -const sort = ( a: any, b: any, direction: SortDirection ) => { - if ( typeof a === 'number' && typeof b === 'number' ) { - return direction === 'asc' ? a - b : b - a; - } - - return direction === 'asc' ? a.localeCompare( b ) : b.localeCompare( a ); -}; - -function normalizeField< Item >(): TypeProvidedProps< Item > { - return { - // type: no type for this - render, - Edit: null, - sort, - isValid: { - elements: true, - custom: () => null, - }, - enableSorting: true, - enableGlobalSearch: false, - defaultOperators: [ OPERATOR_IS, OPERATOR_IS_NOT ], - validOperators: ALL_OPERATORS, - getFormat: () => ( {} ), - }; -} +import { default as noType } from './no-type'; /** * @@ -67,9 +34,9 @@ function normalizeField< Item >(): TypeProvidedProps< Item > { * * @return A field type definition. */ -export default function getNormalizeFieldFunction< Item >( +function getDefaultProperties< Item >( type?: FieldType -): ( field: Field< Item > ) => TypeProvidedProps< Item > { +): TypeProvidedProps< Item > { switch ( type ) { case 'email': return email; @@ -100,6 +67,63 @@ export default function getNormalizeFieldFunction< Item >( // This is a fallback for fields that don't provide a type. // It can be removed when the field.type is mandatory. default: - return normalizeField; + return noType; } } + +/** + * Apply default values and normalize the fields config. + * + * @param fields Fields config. + * @return Normalized fields config. + */ +export default function normalizeFields< Item >( + fields: Field< Item >[] +): NormalizedField< Item >[] { + return fields.map( ( field ) => { + const defaultProps = getDefaultProperties< Item >( field.type ); + + const getValue = field.getValue || getValueFromId( field.id ); + const sort = function ( a: any, b: any, direction: SortDirection ) { + const aValue = getValue( a ); + const bValue = getValue( b ); + return field.sort + ? field.sort( aValue, bValue, direction ) + : defaultProps.sort( aValue, bValue, direction ); + }; + + return { + id: field.id, + label: field.label || field.id, + header: field.header || field.label || field.id, + description: field.description, + placeholder: field.placeholder, + getValue, + setValue: field.setValue || setValueFromId( field.id ), + elements: field.elements, + getElements: field.getElements, + hasElements: hasElements( field ), + isVisible: field.isVisible, + enableHiding: field.enableHiding ?? true, + readOnly: field.readOnly ?? false, + // The type provides defaults for the following props + type: defaultProps.type, + render: field.render ?? defaultProps.render, + Edit: getControl( field, defaultProps.Edit ), + sort, + enableSorting: field.enableSorting ?? defaultProps.enableSorting, + enableGlobalSearch: + field.enableGlobalSearch ?? defaultProps.enableGlobalSearch, + isValid: { + ...defaultProps.isValid, + ...field.isValid, + }, + filterBy: getFilterBy( + field, + defaultProps.defaultOperators, + defaultProps.validOperators + ), + format: defaultProps.getFormat( field ), + }; + } ); +} diff --git a/packages/dataviews/src/field-types/integer.tsx b/packages/dataviews/src/field-types/integer.tsx index 52e723166b6510..57b89d917ee519 100644 --- a/packages/dataviews/src/field-types/integer.tsx +++ b/packages/dataviews/src/field-types/integer.tsx @@ -50,39 +50,37 @@ const sort = ( a: any, b: any, direction: SortDirection ) => { return direction === 'asc' ? a - b : b - a; }; -export default function normalizeField< Item >(): TypeProvidedProps< Item > { - return { - type: 'integer', - render, - Edit: 'integer', - sort, - isValid, - enableSorting: true, - enableGlobalSearch: false, - defaultOperators: [ - OPERATOR_IS, - OPERATOR_IS_NOT, - OPERATOR_LESS_THAN, - OPERATOR_GREATER_THAN, - OPERATOR_LESS_THAN_OR_EQUAL, - OPERATOR_GREATER_THAN_OR_EQUAL, - OPERATOR_BETWEEN, - ], - validOperators: [ - // Single-selection - OPERATOR_IS, - OPERATOR_IS_NOT, - OPERATOR_LESS_THAN, - OPERATOR_GREATER_THAN, - OPERATOR_LESS_THAN_OR_EQUAL, - OPERATOR_GREATER_THAN_OR_EQUAL, - OPERATOR_BETWEEN, - // Multiple-selection - OPERATOR_IS_ANY, - OPERATOR_IS_NONE, - OPERATOR_IS_ALL, - OPERATOR_IS_NOT_ALL, - ], - getFormat: () => ( {} ), - }; -} +export default { + type: 'integer', + render, + Edit: 'integer', + sort, + isValid, + enableSorting: true, + enableGlobalSearch: false, + defaultOperators: [ + OPERATOR_IS, + OPERATOR_IS_NOT, + OPERATOR_LESS_THAN, + OPERATOR_GREATER_THAN, + OPERATOR_LESS_THAN_OR_EQUAL, + OPERATOR_GREATER_THAN_OR_EQUAL, + OPERATOR_BETWEEN, + ], + validOperators: [ + // Single-selection + OPERATOR_IS, + OPERATOR_IS_NOT, + OPERATOR_LESS_THAN, + OPERATOR_GREATER_THAN, + OPERATOR_LESS_THAN_OR_EQUAL, + OPERATOR_GREATER_THAN_OR_EQUAL, + OPERATOR_BETWEEN, + // Multiple-selection + OPERATOR_IS_ANY, + OPERATOR_IS_NONE, + OPERATOR_IS_ALL, + OPERATOR_IS_NOT_ALL, + ], + getFormat: () => ( {} ), +} satisfies TypeProvidedProps< any >; diff --git a/packages/dataviews/src/field-types/media.tsx b/packages/dataviews/src/field-types/media.tsx index c16e1e6d865566..67cb6f83a54f8c 100644 --- a/packages/dataviews/src/field-types/media.tsx +++ b/packages/dataviews/src/field-types/media.tsx @@ -3,20 +3,18 @@ */ import type { TypeProvidedProps } from '../types/private'; -export default function normalizeField< Item >(): TypeProvidedProps< Item > { - return { - type: 'media', - render: () => null, - Edit: null, - sort: () => 0, - isValid: { - elements: true, - custom: () => null, - }, - enableSorting: false, - enableGlobalSearch: false, - defaultOperators: [], - validOperators: [], - getFormat: () => ( {} ), - }; -} +export default { + type: 'media', + render: () => null, + Edit: null, + sort: () => 0, + isValid: { + elements: true, + custom: () => null, + }, + enableSorting: false, + enableGlobalSearch: false, + defaultOperators: [], + validOperators: [], + getFormat: () => ( {} ), +} satisfies TypeProvidedProps< any >; diff --git a/packages/dataviews/src/field-types/no-type.tsx b/packages/dataviews/src/field-types/no-type.tsx new file mode 100644 index 00000000000000..6f6e9d71ab5936 --- /dev/null +++ b/packages/dataviews/src/field-types/no-type.tsx @@ -0,0 +1,42 @@ +/** + * Internal dependencies + */ +import type { DataViewRenderFieldProps, SortDirection } from '../types'; +import type { TypeProvidedProps } from '../types/private'; +import RenderFromElements from './utils/render-from-elements'; +import { ALL_OPERATORS, OPERATOR_IS, OPERATOR_IS_NOT } from '../constants'; + +const render = ( { + item, + field: normalizedField, +}: DataViewRenderFieldProps< any > ) => { + return normalizedField.hasElements ? ( + + ) : ( + normalizedField.getValue( { item } ) + ); +}; + +const sort = ( a: any, b: any, direction: SortDirection ) => { + if ( typeof a === 'number' && typeof b === 'number' ) { + return direction === 'asc' ? a - b : b - a; + } + + return direction === 'asc' ? a.localeCompare( b ) : b.localeCompare( a ); +}; + +export default { + // type: no type for this one + render, + Edit: null, + sort, + isValid: { + elements: true, + custom: () => null, + }, + enableSorting: true, + enableGlobalSearch: false, + defaultOperators: [ OPERATOR_IS, OPERATOR_IS_NOT ], + validOperators: ALL_OPERATORS, + getFormat: () => ( {} ), +} satisfies TypeProvidedProps< any >; diff --git a/packages/dataviews/src/field-types/normalize-fields.ts b/packages/dataviews/src/field-types/normalize-fields.ts deleted file mode 100644 index 48f47964bebc15..00000000000000 --- a/packages/dataviews/src/field-types/normalize-fields.ts +++ /dev/null @@ -1,72 +0,0 @@ -/** - * External dependencies - */ - -/** - * Internal dependencies - */ -import getNormalizeFieldFunction from '.'; -import { getControl } from '../dataform-controls'; -import type { Field, NormalizedField, SortDirection } from '../types'; -import getFilterBy from './utils/get-filter-by'; -import getValueFromId from './utils/get-value-from-id'; -import hasElements from './utils/has-elements'; -import setValueFromId from './utils/set-value-from-id'; - -/** - * Apply default values and normalize the fields config. - * - * @param fields Fields config. - * @return Normalized fields config. - */ -export default function normalizeFields< Item >( - fields: Field< Item >[] -): NormalizedField< Item >[] { - return fields.map( ( field ) => { - const normalize = getNormalizeFieldFunction< Item >( field.type ); - const defaultProps = normalize( field ); - - const getValue = field.getValue || getValueFromId( field.id ); - const sort = function ( a: any, b: any, direction: SortDirection ) { - const aValue = getValue( a ); - const bValue = getValue( b ); - return field.sort - ? field.sort( aValue, bValue, direction ) - : defaultProps.sort( aValue, bValue, direction ); - }; - - return { - id: field.id, - label: field.label || field.id, - header: field.header || field.label || field.id, - description: field.description, - placeholder: field.placeholder, - getValue, - setValue: field.setValue || setValueFromId( field.id ), - elements: field.elements, - getElements: field.getElements, - hasElements: hasElements( field ), - isVisible: field.isVisible, - enableHiding: field.enableHiding ?? true, - readOnly: field.readOnly ?? false, - // The type provides defaults for the following props - type: defaultProps.type, - render: field.render ?? defaultProps.render, - Edit: getControl( field, defaultProps.Edit ), - sort, - enableSorting: field.enableSorting ?? defaultProps.enableSorting, - enableGlobalSearch: - field.enableGlobalSearch ?? defaultProps.enableGlobalSearch, - isValid: { - ...defaultProps.isValid, - ...field.isValid, - }, - filterBy: getFilterBy( - field, - defaultProps.defaultOperators, - defaultProps.validOperators - ), - format: defaultProps.getFormat( field ), - }; - } ); -} diff --git a/packages/dataviews/src/field-types/number.tsx b/packages/dataviews/src/field-types/number.tsx index ae56965bd94c83..d8bfc3dc12f0a7 100644 --- a/packages/dataviews/src/field-types/number.tsx +++ b/packages/dataviews/src/field-types/number.tsx @@ -57,39 +57,37 @@ const sort = ( a: any, b: any, direction: SortDirection ) => { return direction === 'asc' ? a - b : b - a; }; -export default function normalizeField< Item >(): TypeProvidedProps< Item > { - return { - type: 'number', - render, - Edit: 'number', - sort, - isValid, - enableSorting: true, - enableGlobalSearch: false, - defaultOperators: [ - OPERATOR_IS, - OPERATOR_IS_NOT, - OPERATOR_LESS_THAN, - OPERATOR_GREATER_THAN, - OPERATOR_LESS_THAN_OR_EQUAL, - OPERATOR_GREATER_THAN_OR_EQUAL, - OPERATOR_BETWEEN, - ], - validOperators: [ - // Single-selection - OPERATOR_IS, - OPERATOR_IS_NOT, - OPERATOR_LESS_THAN, - OPERATOR_GREATER_THAN, - OPERATOR_LESS_THAN_OR_EQUAL, - OPERATOR_GREATER_THAN_OR_EQUAL, - OPERATOR_BETWEEN, - // Multiple-selection - OPERATOR_IS_ANY, - OPERATOR_IS_NONE, - OPERATOR_IS_ALL, - OPERATOR_IS_NOT_ALL, - ], - getFormat: () => ( {} ), - }; -} +export default { + type: 'number', + render, + Edit: 'number', + sort, + isValid, + enableSorting: true, + enableGlobalSearch: false, + defaultOperators: [ + OPERATOR_IS, + OPERATOR_IS_NOT, + OPERATOR_LESS_THAN, + OPERATOR_GREATER_THAN, + OPERATOR_LESS_THAN_OR_EQUAL, + OPERATOR_GREATER_THAN_OR_EQUAL, + OPERATOR_BETWEEN, + ], + validOperators: [ + // Single-selection + OPERATOR_IS, + OPERATOR_IS_NOT, + OPERATOR_LESS_THAN, + OPERATOR_GREATER_THAN, + OPERATOR_LESS_THAN_OR_EQUAL, + OPERATOR_GREATER_THAN_OR_EQUAL, + OPERATOR_BETWEEN, + // Multiple-selection + OPERATOR_IS_ANY, + OPERATOR_IS_NONE, + OPERATOR_IS_ALL, + OPERATOR_IS_NOT_ALL, + ], + getFormat: () => ( {} ), +} satisfies TypeProvidedProps< any >; diff --git a/packages/dataviews/src/field-types/password.tsx b/packages/dataviews/src/field-types/password.tsx index 1aba7613ce8f66..12e108a2e43fa0 100644 --- a/packages/dataviews/src/field-types/password.tsx +++ b/packages/dataviews/src/field-types/password.tsx @@ -13,20 +13,18 @@ function render( { item, field }: DataViewRenderFieldProps< any > ) { ); } -export default function normalizeField< Item >(): TypeProvidedProps< Item > { - return { - type: 'password', - render, - Edit: 'password', - sort: () => 0, // Passwords should not be sortable for security reasons - isValid: { - elements: true, - custom: () => null, - }, - enableSorting: false, - enableGlobalSearch: false, - defaultOperators: [], - validOperators: [], - getFormat: () => ( {} ), - }; -} +export default { + type: 'password', + render, + Edit: 'password', + sort: () => 0, // Passwords should not be sortable for security reasons + isValid: { + elements: true, + custom: () => null, + }, + enableSorting: false, + enableGlobalSearch: false, + defaultOperators: [], + validOperators: [], + getFormat: () => ( {} ), +} satisfies TypeProvidedProps< any >; diff --git a/packages/dataviews/src/field-types/telephone.tsx b/packages/dataviews/src/field-types/telephone.tsx index d47aed45e80ff0..3aa604aedf4277 100644 --- a/packages/dataviews/src/field-types/telephone.tsx +++ b/packages/dataviews/src/field-types/telephone.tsx @@ -28,31 +28,29 @@ const sort = ( a: any, b: any, direction: SortDirection ) => { return direction === 'asc' ? a.localeCompare( b ) : b.localeCompare( a ); }; -export default function normalizeField< Item >(): TypeProvidedProps< Item > { - return { - type: 'telephone', - render, - Edit: 'telephone', - sort, - isValid: { - elements: true, - custom: () => null, - }, - enableSorting: true, - enableGlobalSearch: false, - defaultOperators: [ OPERATOR_IS_ANY, OPERATOR_IS_NONE ], - validOperators: [ - OPERATOR_IS, - OPERATOR_IS_NOT, - OPERATOR_CONTAINS, - OPERATOR_NOT_CONTAINS, - OPERATOR_STARTS_WITH, - // Multiple selection - OPERATOR_IS_ANY, - OPERATOR_IS_NONE, - OPERATOR_IS_ALL, - OPERATOR_IS_NOT_ALL, - ], - getFormat: () => ( {} ), - }; -} +export default { + type: 'telephone', + render, + Edit: 'telephone', + sort, + isValid: { + elements: true, + custom: () => null, + }, + enableSorting: true, + enableGlobalSearch: false, + defaultOperators: [ OPERATOR_IS_ANY, OPERATOR_IS_NONE ], + validOperators: [ + OPERATOR_IS, + OPERATOR_IS_NOT, + OPERATOR_CONTAINS, + OPERATOR_NOT_CONTAINS, + OPERATOR_STARTS_WITH, + // Multiple selection + OPERATOR_IS_ANY, + OPERATOR_IS_NONE, + OPERATOR_IS_ALL, + OPERATOR_IS_NOT_ALL, + ], + getFormat: () => ( {} ), +} satisfies TypeProvidedProps< any >; diff --git a/packages/dataviews/src/field-types/text.tsx b/packages/dataviews/src/field-types/text.tsx index f0e39611517b3c..9670f5a129896a 100644 --- a/packages/dataviews/src/field-types/text.tsx +++ b/packages/dataviews/src/field-types/text.tsx @@ -28,32 +28,30 @@ const sort = ( a: any, b: any, direction: SortDirection ) => { return direction === 'asc' ? a.localeCompare( b ) : b.localeCompare( a ); }; -export default function normalizeField< Item >(): TypeProvidedProps< Item > { - return { - type: 'text', - render, - Edit: 'text', - sort, - isValid: { - elements: true, - custom: () => null, - }, - enableSorting: true, - enableGlobalSearch: false, - defaultOperators: [ OPERATOR_IS_ANY, OPERATOR_IS_NONE ], - validOperators: [ - // Single selection - OPERATOR_IS, - OPERATOR_IS_NOT, - OPERATOR_CONTAINS, - OPERATOR_NOT_CONTAINS, - OPERATOR_STARTS_WITH, - // Multiple selection - OPERATOR_IS_ANY, - OPERATOR_IS_NONE, - OPERATOR_IS_ALL, - OPERATOR_IS_NOT_ALL, - ], - getFormat: () => ( {} ), - }; -} +export default { + type: 'text', + render, + Edit: 'text', + sort, + isValid: { + elements: true, + custom: () => null, + }, + enableSorting: true, + enableGlobalSearch: false, + defaultOperators: [ OPERATOR_IS_ANY, OPERATOR_IS_NONE ], + validOperators: [ + // Single selection + OPERATOR_IS, + OPERATOR_IS_NOT, + OPERATOR_CONTAINS, + OPERATOR_NOT_CONTAINS, + OPERATOR_STARTS_WITH, + // Multiple selection + OPERATOR_IS_ANY, + OPERATOR_IS_NONE, + OPERATOR_IS_ALL, + OPERATOR_IS_NOT_ALL, + ], + getFormat: () => ( {} ), +} satisfies TypeProvidedProps< any >; diff --git a/packages/dataviews/src/field-types/url.tsx b/packages/dataviews/src/field-types/url.tsx index 2aa38ae357d6b2..f829a5c0745042 100644 --- a/packages/dataviews/src/field-types/url.tsx +++ b/packages/dataviews/src/field-types/url.tsx @@ -28,31 +28,29 @@ const sort = ( a: any, b: any, direction: SortDirection ) => { return direction === 'asc' ? a.localeCompare( b ) : b.localeCompare( a ); }; -export default function normalizeField< Item >(): TypeProvidedProps< Item > { - return { - type: 'url', - render, - Edit: 'url', - sort, - isValid: { - elements: true, - custom: () => null, - }, - enableSorting: true, - enableGlobalSearch: false, - defaultOperators: [ OPERATOR_IS_ANY, OPERATOR_IS_NONE ], - validOperators: [ - OPERATOR_IS, - OPERATOR_IS_NOT, - OPERATOR_CONTAINS, - OPERATOR_NOT_CONTAINS, - OPERATOR_STARTS_WITH, - // Multiple selection - OPERATOR_IS_ANY, - OPERATOR_IS_NONE, - OPERATOR_IS_ALL, - OPERATOR_IS_NOT_ALL, - ], - getFormat: () => ( {} ), - }; -} +export default { + type: 'url', + render, + Edit: 'url', + sort, + isValid: { + elements: true, + custom: () => null, + }, + enableSorting: true, + enableGlobalSearch: false, + defaultOperators: [ OPERATOR_IS_ANY, OPERATOR_IS_NONE ], + validOperators: [ + OPERATOR_IS, + OPERATOR_IS_NOT, + OPERATOR_CONTAINS, + OPERATOR_NOT_CONTAINS, + OPERATOR_STARTS_WITH, + // Multiple selection + OPERATOR_IS_ANY, + OPERATOR_IS_NONE, + OPERATOR_IS_ALL, + OPERATOR_IS_NOT_ALL, + ], + getFormat: () => ( {} ), +} satisfies TypeProvidedProps< any >; diff --git a/packages/dataviews/src/hooks/use-form-validity.ts b/packages/dataviews/src/hooks/use-form-validity.ts index f37d8e87b75291..d068bfca50ceee 100644 --- a/packages/dataviews/src/hooks/use-form-validity.ts +++ b/packages/dataviews/src/hooks/use-form-validity.ts @@ -13,7 +13,7 @@ import { __ } from '@wordpress/i18n'; /** * Internal dependencies */ -import normalizeFields from '../field-types/normalize-fields'; +import normalizeFields from '../field-types'; import normalizeForm from '../dataform-layouts/normalize-form'; import type { Field, diff --git a/packages/dataviews/src/test/normalize-fields.ts b/packages/dataviews/src/test/normalize-fields.ts index 7696edcac25e8f..b38b9b5fcac3d1 100644 --- a/packages/dataviews/src/test/normalize-fields.ts +++ b/packages/dataviews/src/test/normalize-fields.ts @@ -1,7 +1,7 @@ /** * Internal dependencies */ -import normalizeFields from '../field-types/normalize-fields'; +import normalizeFields from '../field-types'; import type { Field } from '../types'; describe( 'normalizeFields: default getValue', () => { diff --git a/packages/dataviews/src/utils/filter-sort-and-paginate.ts b/packages/dataviews/src/utils/filter-sort-and-paginate.ts index 4fb9f440276314..fa273ac8366138 100644 --- a/packages/dataviews/src/utils/filter-sort-and-paginate.ts +++ b/packages/dataviews/src/utils/filter-sort-and-paginate.ts @@ -36,7 +36,7 @@ import { OPERATOR_IN_THE_PAST, OPERATOR_OVER, } from '../constants'; -import normalizeFields from '../field-types/normalize-fields'; +import normalizeFields from '../field-types'; import type { Field, View } from '../types'; function normalizeSearchInput( input = '' ) { From fa11afd7cf960a95d0a2c408df1ee1f7b0217606 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Maneiro?= <583546+oandregal@users.noreply.github.com> Date: Tue, 25 Nov 2025 12:48:06 +0100 Subject: [PATCH 08/15] Extract common render util --- packages/dataviews/src/field-types/email.tsx | 12 ++---------- packages/dataviews/src/field-types/integer.tsx | 12 ++---------- packages/dataviews/src/field-types/no-type.tsx | 15 ++------------- packages/dataviews/src/field-types/telephone.tsx | 12 ++---------- packages/dataviews/src/field-types/text.tsx | 12 ++---------- packages/dataviews/src/field-types/url.tsx | 12 ++---------- .../src/field-types/utils/render-default.tsx | 16 ++++++++++++++++ 7 files changed, 28 insertions(+), 63 deletions(-) create mode 100644 packages/dataviews/src/field-types/utils/render-default.tsx diff --git a/packages/dataviews/src/field-types/email.tsx b/packages/dataviews/src/field-types/email.tsx index 4aa6a4d4d40206..9bb1783c461dd8 100644 --- a/packages/dataviews/src/field-types/email.tsx +++ b/packages/dataviews/src/field-types/email.tsx @@ -6,9 +6,8 @@ import { __ } from '@wordpress/i18n'; /** * Internal dependencies */ -import type { DataViewRenderFieldProps, Rules, SortDirection } from '../types'; +import type { Rules, SortDirection } from '../types'; import type { TypeProvidedProps } from '../types/private'; -import RenderFromElements from './utils/render-from-elements'; import { OPERATOR_IS, OPERATOR_IS_ALL, @@ -20,20 +19,13 @@ import { OPERATOR_NOT_CONTAINS, OPERATOR_STARTS_WITH, } from '../constants'; +import render from './utils/render-default'; // Email validation regex based on HTML5 spec // https://html.spec.whatwg.org/multipage/input.html#valid-e-mail-address const emailRegex = /^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/; -function render( { item, field }: DataViewRenderFieldProps< any > ) { - return field.hasElements ? ( - - ) : ( - field.getValue( { item } ) - ); -} - const isValid: Rules< any > = { elements: true, custom: ( item: any, normalizedField ) => { diff --git a/packages/dataviews/src/field-types/integer.tsx b/packages/dataviews/src/field-types/integer.tsx index 57b89d917ee519..18635ed50bf17d 100644 --- a/packages/dataviews/src/field-types/integer.tsx +++ b/packages/dataviews/src/field-types/integer.tsx @@ -6,9 +6,8 @@ import { __ } from '@wordpress/i18n'; /** * Internal dependencies */ -import type { DataViewRenderFieldProps, Rules, SortDirection } from '../types'; +import type { Rules, SortDirection } from '../types'; import type { TypeProvidedProps } from '../types/private'; -import RenderFromElements from './utils/render-from-elements'; import { OPERATOR_IS, OPERATOR_IS_NOT, @@ -22,14 +21,7 @@ import { OPERATOR_IS_NOT_ALL, OPERATOR_BETWEEN, } from '../constants'; - -function render( { item, field }: DataViewRenderFieldProps< any > ) { - return field.hasElements ? ( - - ) : ( - field.getValue( { item } ) - ); -} +import render from './utils/render-default'; const isValid: Rules< any > = { elements: true, diff --git a/packages/dataviews/src/field-types/no-type.tsx b/packages/dataviews/src/field-types/no-type.tsx index 6f6e9d71ab5936..e926adfeedfa6f 100644 --- a/packages/dataviews/src/field-types/no-type.tsx +++ b/packages/dataviews/src/field-types/no-type.tsx @@ -1,21 +1,10 @@ /** * Internal dependencies */ -import type { DataViewRenderFieldProps, SortDirection } from '../types'; +import type { SortDirection } from '../types'; import type { TypeProvidedProps } from '../types/private'; -import RenderFromElements from './utils/render-from-elements'; import { ALL_OPERATORS, OPERATOR_IS, OPERATOR_IS_NOT } from '../constants'; - -const render = ( { - item, - field: normalizedField, -}: DataViewRenderFieldProps< any > ) => { - return normalizedField.hasElements ? ( - - ) : ( - normalizedField.getValue( { item } ) - ); -}; +import render from './utils/render-default'; const sort = ( a: any, b: any, direction: SortDirection ) => { if ( typeof a === 'number' && typeof b === 'number' ) { diff --git a/packages/dataviews/src/field-types/telephone.tsx b/packages/dataviews/src/field-types/telephone.tsx index 3aa604aedf4277..1a9c7168bb424c 100644 --- a/packages/dataviews/src/field-types/telephone.tsx +++ b/packages/dataviews/src/field-types/telephone.tsx @@ -1,9 +1,8 @@ /** * Internal dependencies */ -import type { DataViewRenderFieldProps, SortDirection } from '../types'; +import type { SortDirection } from '../types'; import type { TypeProvidedProps } from '../types/private'; -import RenderFromElements from './utils/render-from-elements'; import { OPERATOR_IS, OPERATOR_IS_ALL, @@ -15,14 +14,7 @@ import { OPERATOR_NOT_CONTAINS, OPERATOR_STARTS_WITH, } from '../constants'; - -function render( { item, field }: DataViewRenderFieldProps< any > ) { - return field.hasElements ? ( - - ) : ( - field.getValue( { item } ) - ); -} +import render from './utils/render-default'; const sort = ( a: any, b: any, direction: SortDirection ) => { return direction === 'asc' ? a.localeCompare( b ) : b.localeCompare( a ); diff --git a/packages/dataviews/src/field-types/text.tsx b/packages/dataviews/src/field-types/text.tsx index 9670f5a129896a..17d3d309436f51 100644 --- a/packages/dataviews/src/field-types/text.tsx +++ b/packages/dataviews/src/field-types/text.tsx @@ -1,9 +1,8 @@ /** * Internal dependencies */ -import type { DataViewRenderFieldProps, SortDirection } from '../types'; +import type { SortDirection } from '../types'; import type { TypeProvidedProps } from '../types/private'; -import RenderFromElements from './utils/render-from-elements'; import { OPERATOR_CONTAINS, OPERATOR_IS, @@ -15,14 +14,7 @@ import { OPERATOR_NOT_CONTAINS, OPERATOR_STARTS_WITH, } from '../constants'; - -function render( { item, field }: DataViewRenderFieldProps< any > ) { - return field.hasElements ? ( - - ) : ( - field.getValue( { item } ) - ); -} +import render from './utils/render-default'; const sort = ( a: any, b: any, direction: SortDirection ) => { return direction === 'asc' ? a.localeCompare( b ) : b.localeCompare( a ); diff --git a/packages/dataviews/src/field-types/url.tsx b/packages/dataviews/src/field-types/url.tsx index f829a5c0745042..124973cc705f8b 100644 --- a/packages/dataviews/src/field-types/url.tsx +++ b/packages/dataviews/src/field-types/url.tsx @@ -1,9 +1,8 @@ /** * Internal dependencies */ -import type { DataViewRenderFieldProps, SortDirection } from '../types'; +import type { SortDirection } from '../types'; import type { TypeProvidedProps } from '../types/private'; -import RenderFromElements from './utils/render-from-elements'; import { OPERATOR_IS, OPERATOR_IS_ALL, @@ -15,14 +14,7 @@ import { OPERATOR_NOT_CONTAINS, OPERATOR_STARTS_WITH, } from '../constants'; - -function render( { item, field }: DataViewRenderFieldProps< any > ) { - return field.hasElements ? ( - - ) : ( - field.getValue( { item } ) - ); -} +import render from './utils/render-default'; const sort = ( a: any, b: any, direction: SortDirection ) => { return direction === 'asc' ? a.localeCompare( b ) : b.localeCompare( a ); diff --git a/packages/dataviews/src/field-types/utils/render-default.tsx b/packages/dataviews/src/field-types/utils/render-default.tsx new file mode 100644 index 00000000000000..bb9ad44589ebad --- /dev/null +++ b/packages/dataviews/src/field-types/utils/render-default.tsx @@ -0,0 +1,16 @@ +/** + * Internal dependencies + */ +import type { DataViewRenderFieldProps } from '../../types'; +import RenderFromElements from './render-from-elements'; + +export default function render( { + item, + field, +}: DataViewRenderFieldProps< any > ) { + return field.hasElements ? ( + + ) : ( + field.getValue( { item } ) + ); +} From 2b8d237515a89b258ac9db0ae065997ee0921ed3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Maneiro?= <583546+oandregal@users.noreply.github.com> Date: Tue, 25 Nov 2025 12:54:59 +0100 Subject: [PATCH 09/15] Extract common sort utils --- packages/dataviews/src/field-types/email.tsx | 7 ++----- packages/dataviews/src/field-types/index.tsx | 4 ++-- packages/dataviews/src/field-types/integer.tsx | 7 ++----- packages/dataviews/src/field-types/no-type.tsx | 6 ++++-- packages/dataviews/src/field-types/number.tsx | 7 ++----- packages/dataviews/src/field-types/telephone.tsx | 6 +----- packages/dataviews/src/field-types/text.tsx | 6 +----- packages/dataviews/src/field-types/url.tsx | 6 +----- packages/dataviews/src/field-types/utils/sort-number.ts | 8 ++++++++ packages/dataviews/src/field-types/utils/sort-text.ts | 8 ++++++++ 10 files changed, 31 insertions(+), 34 deletions(-) create mode 100644 packages/dataviews/src/field-types/utils/sort-number.ts create mode 100644 packages/dataviews/src/field-types/utils/sort-text.ts diff --git a/packages/dataviews/src/field-types/email.tsx b/packages/dataviews/src/field-types/email.tsx index 9bb1783c461dd8..72b879d3ffa3a8 100644 --- a/packages/dataviews/src/field-types/email.tsx +++ b/packages/dataviews/src/field-types/email.tsx @@ -6,7 +6,7 @@ import { __ } from '@wordpress/i18n'; /** * Internal dependencies */ -import type { Rules, SortDirection } from '../types'; +import type { Rules } from '../types'; import type { TypeProvidedProps } from '../types/private'; import { OPERATOR_IS, @@ -20,6 +20,7 @@ import { OPERATOR_STARTS_WITH, } from '../constants'; import render from './utils/render-default'; +import sort from './utils/sort-text'; // Email validation regex based on HTML5 spec // https://html.spec.whatwg.org/multipage/input.html#valid-e-mail-address @@ -42,10 +43,6 @@ const isValid: Rules< any > = { }, }; -const sort = ( a: any, b: any, direction: SortDirection ) => { - return direction === 'asc' ? a.localeCompare( b ) : b.localeCompare( a ); -}; - export default { type: 'email', render, diff --git a/packages/dataviews/src/field-types/index.tsx b/packages/dataviews/src/field-types/index.tsx index 95b9c7123e3918..c4b8a2b3eef2c5 100644 --- a/packages/dataviews/src/field-types/index.tsx +++ b/packages/dataviews/src/field-types/index.tsx @@ -85,8 +85,8 @@ export default function normalizeFields< Item >( const getValue = field.getValue || getValueFromId( field.id ); const sort = function ( a: any, b: any, direction: SortDirection ) { - const aValue = getValue( a ); - const bValue = getValue( b ); + const aValue = getValue( { item: a } ); + const bValue = getValue( { item: b } ); return field.sort ? field.sort( aValue, bValue, direction ) : defaultProps.sort( aValue, bValue, direction ); diff --git a/packages/dataviews/src/field-types/integer.tsx b/packages/dataviews/src/field-types/integer.tsx index 18635ed50bf17d..3fc319248dbea5 100644 --- a/packages/dataviews/src/field-types/integer.tsx +++ b/packages/dataviews/src/field-types/integer.tsx @@ -6,7 +6,7 @@ import { __ } from '@wordpress/i18n'; /** * Internal dependencies */ -import type { Rules, SortDirection } from '../types'; +import type { Rules } from '../types'; import type { TypeProvidedProps } from '../types/private'; import { OPERATOR_IS, @@ -22,6 +22,7 @@ import { OPERATOR_BETWEEN, } from '../constants'; import render from './utils/render-default'; +import sort from './utils/sort-number'; const isValid: Rules< any > = { elements: true, @@ -38,10 +39,6 @@ const isValid: Rules< any > = { }, }; -const sort = ( a: any, b: any, direction: SortDirection ) => { - return direction === 'asc' ? a - b : b - a; -}; - export default { type: 'integer', render, diff --git a/packages/dataviews/src/field-types/no-type.tsx b/packages/dataviews/src/field-types/no-type.tsx index e926adfeedfa6f..07e508b9bf9e8e 100644 --- a/packages/dataviews/src/field-types/no-type.tsx +++ b/packages/dataviews/src/field-types/no-type.tsx @@ -5,13 +5,15 @@ import type { SortDirection } from '../types'; import type { TypeProvidedProps } from '../types/private'; import { ALL_OPERATORS, OPERATOR_IS, OPERATOR_IS_NOT } from '../constants'; import render from './utils/render-default'; +import sortText from './utils/sort-text'; +import sortNumber from './utils/sort-number'; const sort = ( a: any, b: any, direction: SortDirection ) => { if ( typeof a === 'number' && typeof b === 'number' ) { - return direction === 'asc' ? a - b : b - a; + return sortNumber( a, b, direction ); } - return direction === 'asc' ? a.localeCompare( b ) : b.localeCompare( a ); + return sortText( a, b, direction ); }; export default { diff --git a/packages/dataviews/src/field-types/number.tsx b/packages/dataviews/src/field-types/number.tsx index d8bfc3dc12f0a7..7e733d5d30a9bc 100644 --- a/packages/dataviews/src/field-types/number.tsx +++ b/packages/dataviews/src/field-types/number.tsx @@ -6,7 +6,7 @@ import { __ } from '@wordpress/i18n'; /** * Internal dependencies */ -import type { DataViewRenderFieldProps, Rules, SortDirection } from '../types'; +import type { DataViewRenderFieldProps, Rules } from '../types'; import type { TypeProvidedProps } from '../types/private'; import { OPERATOR_IS, @@ -22,6 +22,7 @@ import { OPERATOR_BETWEEN, } from '../constants'; import RenderFromElements from './utils/render-from-elements'; +import sort from './utils/sort-number'; function isEmpty( value: unknown ): value is '' | undefined | null { return value === '' || value === undefined || value === null; @@ -53,10 +54,6 @@ const isValid: Rules< any > = { }, }; -const sort = ( a: any, b: any, direction: SortDirection ) => { - return direction === 'asc' ? a - b : b - a; -}; - export default { type: 'number', render, diff --git a/packages/dataviews/src/field-types/telephone.tsx b/packages/dataviews/src/field-types/telephone.tsx index 1a9c7168bb424c..21296061ab65ca 100644 --- a/packages/dataviews/src/field-types/telephone.tsx +++ b/packages/dataviews/src/field-types/telephone.tsx @@ -1,7 +1,6 @@ /** * Internal dependencies */ -import type { SortDirection } from '../types'; import type { TypeProvidedProps } from '../types/private'; import { OPERATOR_IS, @@ -15,10 +14,7 @@ import { OPERATOR_STARTS_WITH, } from '../constants'; import render from './utils/render-default'; - -const sort = ( a: any, b: any, direction: SortDirection ) => { - return direction === 'asc' ? a.localeCompare( b ) : b.localeCompare( a ); -}; +import sort from './utils/sort-text'; export default { type: 'telephone', diff --git a/packages/dataviews/src/field-types/text.tsx b/packages/dataviews/src/field-types/text.tsx index 17d3d309436f51..07c7a6560470ea 100644 --- a/packages/dataviews/src/field-types/text.tsx +++ b/packages/dataviews/src/field-types/text.tsx @@ -1,7 +1,6 @@ /** * Internal dependencies */ -import type { SortDirection } from '../types'; import type { TypeProvidedProps } from '../types/private'; import { OPERATOR_CONTAINS, @@ -15,10 +14,7 @@ import { OPERATOR_STARTS_WITH, } from '../constants'; import render from './utils/render-default'; - -const sort = ( a: any, b: any, direction: SortDirection ) => { - return direction === 'asc' ? a.localeCompare( b ) : b.localeCompare( a ); -}; +import sort from './utils/sort-text'; export default { type: 'text', diff --git a/packages/dataviews/src/field-types/url.tsx b/packages/dataviews/src/field-types/url.tsx index 124973cc705f8b..4a32f6a44cbf79 100644 --- a/packages/dataviews/src/field-types/url.tsx +++ b/packages/dataviews/src/field-types/url.tsx @@ -1,7 +1,6 @@ /** * Internal dependencies */ -import type { SortDirection } from '../types'; import type { TypeProvidedProps } from '../types/private'; import { OPERATOR_IS, @@ -15,10 +14,7 @@ import { OPERATOR_STARTS_WITH, } from '../constants'; import render from './utils/render-default'; - -const sort = ( a: any, b: any, direction: SortDirection ) => { - return direction === 'asc' ? a.localeCompare( b ) : b.localeCompare( a ); -}; +import sort from './utils/sort-text'; export default { type: 'url', diff --git a/packages/dataviews/src/field-types/utils/sort-number.ts b/packages/dataviews/src/field-types/utils/sort-number.ts new file mode 100644 index 00000000000000..1cdff01d963857 --- /dev/null +++ b/packages/dataviews/src/field-types/utils/sort-number.ts @@ -0,0 +1,8 @@ +/** + * Internal dependencies + */ +import type { SortDirection } from '../../types'; + +export default ( a: any, b: any, direction: SortDirection ) => { + return direction === 'asc' ? a - b : b - a; +}; diff --git a/packages/dataviews/src/field-types/utils/sort-text.ts b/packages/dataviews/src/field-types/utils/sort-text.ts new file mode 100644 index 00000000000000..ba4d55dfb60909 --- /dev/null +++ b/packages/dataviews/src/field-types/utils/sort-text.ts @@ -0,0 +1,8 @@ +/** + * Internal dependencies + */ +import type { SortDirection } from '../../types'; + +export default ( a: any, b: any, direction: SortDirection ) => { + return direction === 'asc' ? a.localeCompare( b ) : b.localeCompare( a ); +}; From a05c826fcc7c1d1314b1df950f9e989376eaf3d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Maneiro?= <583546+oandregal@users.noreply.github.com> Date: Tue, 25 Nov 2025 13:31:34 +0100 Subject: [PATCH 10/15] changelog --- packages/dataviews/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/dataviews/CHANGELOG.md b/packages/dataviews/CHANGELOG.md index 30cdcb6566e0ab..14e59364531089 100644 --- a/packages/dataviews/CHANGELOG.md +++ b/packages/dataviews/CHANGELOG.md @@ -4,6 +4,7 @@ ### Enhancements +- Code quality: field types return an object. [#73546](https://github.com/WordPress/gutenberg/pull/73546) - Simplify field normalization and types. [#73387](https://github.com/WordPress/gutenberg/pull/73387) - DataViews table layout: make checkboxes permanently visible when bulk actions are available. [#73245](https://github.com/WordPress/gutenberg/pull/73245) - DataViews: Add insert left/right in table column header. [#72929](https://github.com/WordPress/gutenberg/pull/72929) From b61fc403af12679f1a0e8f542175288db604f6f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Maneiro?= <583546+oandregal@users.noreply.github.com> Date: Tue, 25 Nov 2025 13:42:30 +0100 Subject: [PATCH 11/15] Improve getFilterBy --- .../src/field-types/utils/get-filter-by.ts | 38 +++++-------------- 1 file changed, 10 insertions(+), 28 deletions(-) diff --git a/packages/dataviews/src/field-types/utils/get-filter-by.ts b/packages/dataviews/src/field-types/utils/get-filter-by.ts index 333ed12b959365..f26ea4b5caa7e3 100644 --- a/packages/dataviews/src/field-types/utils/get-filter-by.ts +++ b/packages/dataviews/src/field-types/utils/get-filter-by.ts @@ -12,38 +12,20 @@ function getFilterBy< Item >( return false; } - if ( typeof field.filterBy === 'object' ) { - let operators = field.filterBy.operators; - - // Assign default values if no operator was provided. - if ( ! operators || ! Array.isArray( operators ) ) { - operators = defaultOperators; - } - - // Make sure only valid operators are included. - operators = operators.filter( ( operator ) => - validOperators.includes( operator ) - ); - - // If no operators are left at this point, - // the filters should be disabled. - if ( operators.length === 0 ) { - return false; - } - - return { - isPrimary: !! field.filterBy.isPrimary, - operators, - }; - } - - if ( defaultOperators.length === 0 ) { + const operators = + field.filterBy?.operators?.filter( ( op ) => + validOperators.includes( op ) + ) ?? defaultOperators; + + // If no operators are left at this point, + // the filters should be disabled. + if ( operators.length === 0 ) { return false; } return { - isPrimary: false, - operators: defaultOperators, + isPrimary: !! field.filterBy?.isPrimary, + operators, }; } From d4722299624a159ae1bd64cb8dafd6ebe6d7cd6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Maneiro?= <583546+oandregal@users.noreply.github.com> Date: Tue, 25 Nov 2025 15:17:48 +0100 Subject: [PATCH 12/15] Rename and simplify --- packages/dataviews/src/field-types/index.tsx | 57 +++++++++----------- 1 file changed, 24 insertions(+), 33 deletions(-) diff --git a/packages/dataviews/src/field-types/index.tsx b/packages/dataviews/src/field-types/index.tsx index c4b8a2b3eef2c5..106bfcc1474481 100644 --- a/packages/dataviews/src/field-types/index.tsx +++ b/packages/dataviews/src/field-types/index.tsx @@ -34,41 +34,32 @@ import { default as noType } from './no-type'; * * @return A field type definition. */ -function getDefaultProperties< Item >( +function getFieldTypeByName< Item >( type?: FieldType ): TypeProvidedProps< Item > { - switch ( type ) { - case 'email': - return email; - case 'integer': - return integer; - case 'number': - return number; - case 'text': - return text; - case 'datetime': - return datetime; - case 'date': - return date; - case 'boolean': - return boolean; - case 'media': - return media; - case 'array': - return array; - case 'password': - return password; - case 'telephone': - return telephone; - case 'color': - return color; - case 'url': - return url; - // This is a fallback for fields that don't provide a type. - // It can be removed when the field.type is mandatory. - default: - return noType; + const found = [ + email, + integer, + number, + text, + datetime, + date, + boolean, + media, + array, + password, + telephone, + color, + url, + ].find( ( fieldType ) => fieldType?.type === type ); + + if ( !! found ) { + return found; } + + // This is a fallback for fields that don't provide a type. + // It can be removed when/if the field.type becomes mandatory. + return noType; } /** @@ -81,7 +72,7 @@ export default function normalizeFields< Item >( fields: Field< Item >[] ): NormalizedField< Item >[] { return fields.map( ( field ) => { - const defaultProps = getDefaultProperties< Item >( field.type ); + const defaultProps = getFieldTypeByName< Item >( field.type ); const getValue = field.getValue || getValueFromId( field.id ); const sort = function ( a: any, b: any, direction: SortDirection ) { From 70eefefc3665c164d3604d7622738baddf5bd7d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Maneiro?= <583546+oandregal@users.noreply.github.com> Date: Tue, 25 Nov 2025 15:42:43 +0100 Subject: [PATCH 13/15] Rename FieldType=>Type, TypeProvidedProps=>FieldType --- packages/dataviews/src/field-types/array.tsx | 4 ++-- packages/dataviews/src/field-types/boolean.tsx | 4 ++-- packages/dataviews/src/field-types/color.tsx | 4 ++-- packages/dataviews/src/field-types/date.tsx | 4 ++-- packages/dataviews/src/field-types/datetime.tsx | 4 ++-- packages/dataviews/src/field-types/email.tsx | 4 ++-- packages/dataviews/src/field-types/index.tsx | 17 +++++------------ packages/dataviews/src/field-types/integer.tsx | 4 ++-- packages/dataviews/src/field-types/media.tsx | 4 ++-- packages/dataviews/src/field-types/no-type.tsx | 4 ++-- packages/dataviews/src/field-types/number.tsx | 4 ++-- packages/dataviews/src/field-types/password.tsx | 4 ++-- .../dataviews/src/field-types/telephone.tsx | 4 ++-- packages/dataviews/src/field-types/text.tsx | 4 ++-- packages/dataviews/src/field-types/url.tsx | 4 ++-- packages/dataviews/src/types/field-api.ts | 6 +++--- packages/dataviews/src/types/private.ts | 2 +- 17 files changed, 37 insertions(+), 44 deletions(-) diff --git a/packages/dataviews/src/field-types/array.tsx b/packages/dataviews/src/field-types/array.tsx index 4ac1f85a007633..4120a15626d29e 100644 --- a/packages/dataviews/src/field-types/array.tsx +++ b/packages/dataviews/src/field-types/array.tsx @@ -7,7 +7,7 @@ import { __ } from '@wordpress/i18n'; * Internal dependencies */ import type { DataViewRenderFieldProps, Rules, SortDirection } from '../types'; -import type { TypeProvidedProps } from '../types/private'; +import type { FieldType } from '../types/private'; import { OPERATOR_IS_ALL, OPERATOR_IS_ANY, @@ -74,4 +74,4 @@ export default { OPERATOR_IS_NOT_ALL, ], getFormat: () => ( {} ), -} satisfies TypeProvidedProps< any >; +} satisfies FieldType< any >; diff --git a/packages/dataviews/src/field-types/boolean.tsx b/packages/dataviews/src/field-types/boolean.tsx index a811dd1a107d0d..7e2275e2ae7880 100644 --- a/packages/dataviews/src/field-types/boolean.tsx +++ b/packages/dataviews/src/field-types/boolean.tsx @@ -7,7 +7,7 @@ import { __ } from '@wordpress/i18n'; * Internal dependencies */ import type { DataViewRenderFieldProps, Rules, SortDirection } from '../types'; -import type { TypeProvidedProps } from '../types/private'; +import type { FieldType } from '../types/private'; import RenderFromElements from './utils/render-from-elements'; import { OPERATOR_IS, OPERATOR_IS_NOT } from '../constants'; @@ -71,4 +71,4 @@ export default { defaultOperators: [ OPERATOR_IS, OPERATOR_IS_NOT ], validOperators: [ OPERATOR_IS, OPERATOR_IS_NOT ], getFormat: () => ( {} ), -} satisfies TypeProvidedProps< any >; +} satisfies FieldType< any >; diff --git a/packages/dataviews/src/field-types/color.tsx b/packages/dataviews/src/field-types/color.tsx index ca69241ac0ca9a..2aed013d600bd7 100644 --- a/packages/dataviews/src/field-types/color.tsx +++ b/packages/dataviews/src/field-types/color.tsx @@ -12,7 +12,7 @@ import { __ } from '@wordpress/i18n'; * Internal dependencies */ import type { DataViewRenderFieldProps, Rules, SortDirection } from '../types'; -import type { TypeProvidedProps } from '../types/private'; +import type { FieldType } from '../types/private'; import RenderFromElements from './utils/render-from-elements'; import { OPERATOR_IS, @@ -110,4 +110,4 @@ export default { OPERATOR_IS_NONE, ], getFormat: () => ( {} ), -} satisfies TypeProvidedProps< any >; +} satisfies FieldType< any >; diff --git a/packages/dataviews/src/field-types/date.tsx b/packages/dataviews/src/field-types/date.tsx index 74c3953ca245e4..48aacaa28eb845 100644 --- a/packages/dataviews/src/field-types/date.tsx +++ b/packages/dataviews/src/field-types/date.tsx @@ -12,7 +12,7 @@ import type { FormatDate, SortDirection, } from '../types'; -import type { TypeProvidedProps } from '../types/private'; +import type { FieldType } from '../types/private'; import RenderFromElements from './utils/render-from-elements'; import { OPERATOR_ON, @@ -108,4 +108,4 @@ export default { OPERATOR_BETWEEN, ], getFormat, -} satisfies TypeProvidedProps< any >; +} satisfies FieldType< any >; diff --git a/packages/dataviews/src/field-types/datetime.tsx b/packages/dataviews/src/field-types/datetime.tsx index dce78918a3db03..6edd6eb74e66cb 100644 --- a/packages/dataviews/src/field-types/datetime.tsx +++ b/packages/dataviews/src/field-types/datetime.tsx @@ -2,7 +2,7 @@ * Internal dependencies */ import type { DataViewRenderFieldProps, SortDirection } from '../types'; -import type { TypeProvidedProps } from '../types/private'; +import type { FieldType } from '../types/private'; import RenderFromElements from './utils/render-from-elements'; import parseDateTime from './utils/parse-date-time'; import { @@ -73,4 +73,4 @@ export default { OPERATOR_OVER, ], getFormat: () => ( {} ), -} satisfies TypeProvidedProps< any >; +} satisfies FieldType< any >; diff --git a/packages/dataviews/src/field-types/email.tsx b/packages/dataviews/src/field-types/email.tsx index 72b879d3ffa3a8..dfb1f85f3eea85 100644 --- a/packages/dataviews/src/field-types/email.tsx +++ b/packages/dataviews/src/field-types/email.tsx @@ -7,7 +7,7 @@ import { __ } from '@wordpress/i18n'; * Internal dependencies */ import type { Rules } from '../types'; -import type { TypeProvidedProps } from '../types/private'; +import type { FieldType } from '../types/private'; import { OPERATOR_IS, OPERATOR_IS_ALL, @@ -65,4 +65,4 @@ export default { OPERATOR_IS_NOT_ALL, ], getFormat: () => ( {} ), -} satisfies TypeProvidedProps< any >; +} satisfies FieldType< any >; diff --git a/packages/dataviews/src/field-types/index.tsx b/packages/dataviews/src/field-types/index.tsx index 106bfcc1474481..90b89d88d807aa 100644 --- a/packages/dataviews/src/field-types/index.tsx +++ b/packages/dataviews/src/field-types/index.tsx @@ -1,13 +1,8 @@ /** * Internal dependencies */ -import type { - Field, - FieldType, - NormalizedField, - SortDirection, -} from '../types'; -import type { TypeProvidedProps } from '../types/private'; +import type { Field, Type, NormalizedField, SortDirection } from '../types'; +import type { FieldType } from '../types/private'; import { getControl } from '../dataform-controls'; import getFilterBy from './utils/get-filter-by'; import getValueFromId from './utils/get-value-from-id'; @@ -30,13 +25,11 @@ import { default as noType } from './no-type'; /** * - * @param {FieldType} type The field type definition to get. + * @param {Type} type The field type definition to get. * * @return A field type definition. */ -function getFieldTypeByName< Item >( - type?: FieldType -): TypeProvidedProps< Item > { +function getFieldType< Item >( type?: Type ): FieldType< Item > { const found = [ email, integer, @@ -72,7 +65,7 @@ export default function normalizeFields< Item >( fields: Field< Item >[] ): NormalizedField< Item >[] { return fields.map( ( field ) => { - const defaultProps = getFieldTypeByName< Item >( field.type ); + const defaultProps = getFieldType< Item >( field.type ); const getValue = field.getValue || getValueFromId( field.id ); const sort = function ( a: any, b: any, direction: SortDirection ) { diff --git a/packages/dataviews/src/field-types/integer.tsx b/packages/dataviews/src/field-types/integer.tsx index 3fc319248dbea5..96b9d1e17b8dd1 100644 --- a/packages/dataviews/src/field-types/integer.tsx +++ b/packages/dataviews/src/field-types/integer.tsx @@ -7,7 +7,7 @@ import { __ } from '@wordpress/i18n'; * Internal dependencies */ import type { Rules } from '../types'; -import type { TypeProvidedProps } from '../types/private'; +import type { FieldType } from '../types/private'; import { OPERATOR_IS, OPERATOR_IS_NOT, @@ -72,4 +72,4 @@ export default { OPERATOR_IS_NOT_ALL, ], getFormat: () => ( {} ), -} satisfies TypeProvidedProps< any >; +} satisfies FieldType< any >; diff --git a/packages/dataviews/src/field-types/media.tsx b/packages/dataviews/src/field-types/media.tsx index 67cb6f83a54f8c..9e668b7ca22437 100644 --- a/packages/dataviews/src/field-types/media.tsx +++ b/packages/dataviews/src/field-types/media.tsx @@ -1,7 +1,7 @@ /** * Internal dependencies */ -import type { TypeProvidedProps } from '../types/private'; +import type { FieldType } from '../types/private'; export default { type: 'media', @@ -17,4 +17,4 @@ export default { defaultOperators: [], validOperators: [], getFormat: () => ( {} ), -} satisfies TypeProvidedProps< any >; +} satisfies FieldType< any >; diff --git a/packages/dataviews/src/field-types/no-type.tsx b/packages/dataviews/src/field-types/no-type.tsx index 07e508b9bf9e8e..f9c978559b9e59 100644 --- a/packages/dataviews/src/field-types/no-type.tsx +++ b/packages/dataviews/src/field-types/no-type.tsx @@ -2,7 +2,7 @@ * Internal dependencies */ import type { SortDirection } from '../types'; -import type { TypeProvidedProps } from '../types/private'; +import type { FieldType } from '../types/private'; import { ALL_OPERATORS, OPERATOR_IS, OPERATOR_IS_NOT } from '../constants'; import render from './utils/render-default'; import sortText from './utils/sort-text'; @@ -30,4 +30,4 @@ export default { defaultOperators: [ OPERATOR_IS, OPERATOR_IS_NOT ], validOperators: ALL_OPERATORS, getFormat: () => ( {} ), -} satisfies TypeProvidedProps< any >; +} satisfies FieldType< any >; diff --git a/packages/dataviews/src/field-types/number.tsx b/packages/dataviews/src/field-types/number.tsx index 7e733d5d30a9bc..15e5ea29870c04 100644 --- a/packages/dataviews/src/field-types/number.tsx +++ b/packages/dataviews/src/field-types/number.tsx @@ -7,7 +7,7 @@ import { __ } from '@wordpress/i18n'; * Internal dependencies */ import type { DataViewRenderFieldProps, Rules } from '../types'; -import type { TypeProvidedProps } from '../types/private'; +import type { FieldType } from '../types/private'; import { OPERATOR_IS, OPERATOR_IS_NOT, @@ -87,4 +87,4 @@ export default { OPERATOR_IS_NOT_ALL, ], getFormat: () => ( {} ), -} satisfies TypeProvidedProps< any >; +} satisfies FieldType< any >; diff --git a/packages/dataviews/src/field-types/password.tsx b/packages/dataviews/src/field-types/password.tsx index 12e108a2e43fa0..b091998e183026 100644 --- a/packages/dataviews/src/field-types/password.tsx +++ b/packages/dataviews/src/field-types/password.tsx @@ -2,7 +2,7 @@ * Internal dependencies */ import type { DataViewRenderFieldProps } from '../types'; -import type { TypeProvidedProps } from '../types/private'; +import type { FieldType } from '../types/private'; import RenderFromElements from './utils/render-from-elements'; function render( { item, field }: DataViewRenderFieldProps< any > ) { @@ -27,4 +27,4 @@ export default { defaultOperators: [], validOperators: [], getFormat: () => ( {} ), -} satisfies TypeProvidedProps< any >; +} satisfies FieldType< any >; diff --git a/packages/dataviews/src/field-types/telephone.tsx b/packages/dataviews/src/field-types/telephone.tsx index 21296061ab65ca..545a324c34164d 100644 --- a/packages/dataviews/src/field-types/telephone.tsx +++ b/packages/dataviews/src/field-types/telephone.tsx @@ -1,7 +1,7 @@ /** * Internal dependencies */ -import type { TypeProvidedProps } from '../types/private'; +import type { FieldType } from '../types/private'; import { OPERATOR_IS, OPERATOR_IS_ALL, @@ -41,4 +41,4 @@ export default { OPERATOR_IS_NOT_ALL, ], getFormat: () => ( {} ), -} satisfies TypeProvidedProps< any >; +} satisfies FieldType< any >; diff --git a/packages/dataviews/src/field-types/text.tsx b/packages/dataviews/src/field-types/text.tsx index 07c7a6560470ea..1c1c8c17e2bf58 100644 --- a/packages/dataviews/src/field-types/text.tsx +++ b/packages/dataviews/src/field-types/text.tsx @@ -1,7 +1,7 @@ /** * Internal dependencies */ -import type { TypeProvidedProps } from '../types/private'; +import type { FieldType } from '../types/private'; import { OPERATOR_CONTAINS, OPERATOR_IS, @@ -42,4 +42,4 @@ export default { OPERATOR_IS_NOT_ALL, ], getFormat: () => ( {} ), -} satisfies TypeProvidedProps< any >; +} satisfies FieldType< any >; diff --git a/packages/dataviews/src/field-types/url.tsx b/packages/dataviews/src/field-types/url.tsx index 4a32f6a44cbf79..efcd07ab21143a 100644 --- a/packages/dataviews/src/field-types/url.tsx +++ b/packages/dataviews/src/field-types/url.tsx @@ -1,7 +1,7 @@ /** * Internal dependencies */ -import type { TypeProvidedProps } from '../types/private'; +import type { FieldType } from '../types/private'; import { OPERATOR_IS, OPERATOR_IS_ALL, @@ -41,4 +41,4 @@ export default { OPERATOR_IS_NOT_ALL, ], getFormat: () => ( {} ), -} satisfies TypeProvidedProps< any >; +} satisfies FieldType< any >; diff --git a/packages/dataviews/src/types/field-api.ts b/packages/dataviews/src/types/field-api.ts index db901bccbd8e61..7650d66d15790e 100644 --- a/packages/dataviews/src/types/field-api.ts +++ b/packages/dataviews/src/types/field-api.ts @@ -61,7 +61,7 @@ export type Operator = | 'inThePast' | 'over'; -export type FieldType = +export type Type = | 'text' | 'integer' | 'number' @@ -118,7 +118,7 @@ export type EditConfigText = { * Edit configuration for other control types (excluding 'text' and 'textarea'). */ export type EditConfigGeneric = { - control: Exclude< FieldType, 'text' | 'textarea' >; + control: Exclude< Type, 'text' | 'textarea' >; }; /** @@ -137,7 +137,7 @@ export type Field< Item > = { /** * Type of the fields. */ - type?: FieldType; + type?: Type; /** * The unique identifier of the field. diff --git a/packages/dataviews/src/types/private.ts b/packages/dataviews/src/types/private.ts index 212da614a4ad09..18941d97cd89a1 100644 --- a/packages/dataviews/src/types/private.ts +++ b/packages/dataviews/src/types/private.ts @@ -5,7 +5,7 @@ import type { Field, FormatDate, NormalizedField, Operator } from './field-api'; export type SelectionOrUpdater = string[] | ( ( prev: string[] ) => string[] ); export type SetSelection = ( selection: SelectionOrUpdater ) => void; -export type TypeProvidedProps< Item > = Pick< +export type FieldType< Item > = Pick< NormalizedField< Item >, | 'type' | 'render' From 5d2f267c4f0e14dc583be1d7650b5ed5bd1ff863 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Maneiro?= <583546+oandregal@users.noreply.github.com> Date: Tue, 25 Nov 2025 15:49:49 +0100 Subject: [PATCH 14/15] Type to FieldTypeName --- packages/dataviews/src/field-types/index.tsx | 13 +++++++++---- packages/dataviews/src/types/field-api.ts | 6 +++--- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/packages/dataviews/src/field-types/index.tsx b/packages/dataviews/src/field-types/index.tsx index 90b89d88d807aa..70ced3904843b8 100644 --- a/packages/dataviews/src/field-types/index.tsx +++ b/packages/dataviews/src/field-types/index.tsx @@ -1,7 +1,12 @@ /** * Internal dependencies */ -import type { Field, Type, NormalizedField, SortDirection } from '../types'; +import type { + Field, + FieldTypeName, + NormalizedField, + SortDirection, +} from '../types'; import type { FieldType } from '../types/private'; import { getControl } from '../dataform-controls'; import getFilterBy from './utils/get-filter-by'; @@ -25,11 +30,11 @@ import { default as noType } from './no-type'; /** * - * @param {Type} type The field type definition to get. + * @param {FieldTypeName} type The field type definition to get. * * @return A field type definition. */ -function getFieldType< Item >( type?: Type ): FieldType< Item > { +function getFieldTypeByName< Item >( type?: FieldTypeName ): FieldType< Item > { const found = [ email, integer, @@ -65,7 +70,7 @@ export default function normalizeFields< Item >( fields: Field< Item >[] ): NormalizedField< Item >[] { return fields.map( ( field ) => { - const defaultProps = getFieldType< Item >( field.type ); + const defaultProps = getFieldTypeByName< Item >( field.type ); const getValue = field.getValue || getValueFromId( field.id ); const sort = function ( a: any, b: any, direction: SortDirection ) { diff --git a/packages/dataviews/src/types/field-api.ts b/packages/dataviews/src/types/field-api.ts index 7650d66d15790e..bb3fcf52da5be8 100644 --- a/packages/dataviews/src/types/field-api.ts +++ b/packages/dataviews/src/types/field-api.ts @@ -61,7 +61,7 @@ export type Operator = | 'inThePast' | 'over'; -export type Type = +export type FieldTypeName = | 'text' | 'integer' | 'number' @@ -118,7 +118,7 @@ export type EditConfigText = { * Edit configuration for other control types (excluding 'text' and 'textarea'). */ export type EditConfigGeneric = { - control: Exclude< Type, 'text' | 'textarea' >; + control: Exclude< FieldTypeName, 'text' | 'textarea' >; }; /** @@ -137,7 +137,7 @@ export type Field< Item > = { /** * Type of the fields. */ - type?: Type; + type?: FieldTypeName; /** * The unique identifier of the field. From 1f453c1ea5f5961f9c79c831205be9834889335a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Maneiro?= <583546+oandregal@users.noreply.github.com> Date: Tue, 25 Nov 2025 16:55:25 +0100 Subject: [PATCH 15/15] Mark it as a breaking change --- packages/dataviews/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/dataviews/CHANGELOG.md b/packages/dataviews/CHANGELOG.md index 14e59364531089..62601c114ad395 100644 --- a/packages/dataviews/CHANGELOG.md +++ b/packages/dataviews/CHANGELOG.md @@ -4,7 +4,6 @@ ### Enhancements -- Code quality: field types return an object. [#73546](https://github.com/WordPress/gutenberg/pull/73546) - Simplify field normalization and types. [#73387](https://github.com/WordPress/gutenberg/pull/73387) - DataViews table layout: make checkboxes permanently visible when bulk actions are available. [#73245](https://github.com/WordPress/gutenberg/pull/73245) - DataViews: Add insert left/right in table column header. [#72929](https://github.com/WordPress/gutenberg/pull/72929) @@ -32,6 +31,7 @@ ### Breaking changes - DataViews: rename `groupByField` to `groupBy.field` to allow control over both the field and the direction of the grouping. [#72780](https://github.com/WordPress/gutenberg/pull/72780) +- Types: FieldType is now FieldTypeName. [#73546](https://github.com/WordPress/gutenberg/pull/73546) ## 10.3.0 (2025-11-12)