From 8572fec2ab9fee4d4100bb0c718cbf273ebd5446 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9?= <583546+oandregal@users.noreply.github.com> Date: Thu, 8 Aug 2024 12:51:07 +0200 Subject: [PATCH 1/6] Add comment_status field to quick edit --- packages/dataviews/src/field-types/text.tsx | 18 +++++++++++++++++- packages/dataviews/src/types.ts | 5 +++++ .../src/components/post-edit/index.js | 4 ++-- .../src/components/post-fields/index.js | 10 ++++++++++ 4 files changed, 34 insertions(+), 3 deletions(-) diff --git a/packages/dataviews/src/field-types/text.tsx b/packages/dataviews/src/field-types/text.tsx index c6efb85f6f446b..6316d9544ca8dc 100644 --- a/packages/dataviews/src/field-types/text.tsx +++ b/packages/dataviews/src/field-types/text.tsx @@ -1,7 +1,11 @@ /** * WordPress dependencies */ -import { SelectControl, TextControl } from '@wordpress/components'; +import { + SelectControl, + TextControl, + RadioControl, +} from '@wordpress/components'; import { useCallback } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; @@ -49,6 +53,18 @@ function Edit< Item >( { [ id, onChange ] ); + if ( field.elements && field.editAs === 'radio' ) { + return ( + + ); + } + if ( field.elements ) { const elements = [ /* diff --git a/packages/dataviews/src/types.ts b/packages/dataviews/src/types.ts index 2e87d1371acb61..0b32f78a4eb0b4 100644 --- a/packages/dataviews/src/types.ts +++ b/packages/dataviews/src/types.ts @@ -92,6 +92,11 @@ export type Field< Item > = { */ Edit?: ComponentType< DataFormControlProps< Item > >; + /** + * Optional config for editing the field. + */ + editAs?: 'radio'; + /** * Callback used to sort the field. */ diff --git a/packages/edit-site/src/components/post-edit/index.js b/packages/edit-site/src/components/post-edit/index.js index 03158e00862154..f189fb9ece640e 100644 --- a/packages/edit-site/src/components/post-edit/index.js +++ b/packages/edit-site/src/components/post-edit/index.js @@ -46,8 +46,8 @@ function PostEditForm( { postType, postId } ) { const { saveEntityRecord } = useDispatch( coreDataStore ); const { fields } = usePostFields(); const form = { - type: 'panel', - fields: [ 'title', 'author', 'date' ], + type: 'regular', + fields: [ 'title', 'author', 'date', 'comment_status' ], }; const [ edits, setEdits ] = useState( initialEdits ); const itemWithEdits = useMemo( () => { diff --git a/packages/edit-site/src/components/post-fields/index.js b/packages/edit-site/src/components/post-fields/index.js index 44625fbfbfafb9..1916c6bb09674b 100644 --- a/packages/edit-site/src/components/post-fields/index.js +++ b/packages/edit-site/src/components/post-fields/index.js @@ -345,6 +345,16 @@ function usePostFields( viewType ) { return ; }, }, + { + id: 'comment_status', + label: __( 'Discussion' ), + type: 'text', + editAs: 'radio', + elements: [ + { value: 'open', label: __( 'Open' ) }, + { value: 'closed', label: __( 'Closed' ) }, + ], + }, ], [ authors, viewType, frontPageId, postsPageId ] ); From 3a1f7c69506bc078155810f25a067d3683139d30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9?= <583546+oandregal@users.noreply.github.com> Date: Thu, 8 Aug 2024 13:03:12 +0200 Subject: [PATCH 2/6] Provide description for elements --- .../src/components/post-fields/index.js | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/packages/edit-site/src/components/post-fields/index.js b/packages/edit-site/src/components/post-fields/index.js index 1916c6bb09674b..442670072b4d3d 100644 --- a/packages/edit-site/src/components/post-fields/index.js +++ b/packages/edit-site/src/components/post-fields/index.js @@ -351,8 +351,20 @@ function usePostFields( viewType ) { type: 'text', editAs: 'radio', elements: [ - { value: 'open', label: __( 'Open' ) }, - { value: 'closed', label: __( 'Closed' ) }, + { + value: 'open', + label: __( 'Open' ), + description: __( + 'Visitors can add new comments and replies.' + ), + }, + { + value: 'closed', + label: __( 'Closed' ), + description: __( + 'Visitors cannot add new comments or replies. Existing comments remain visible.' + ), + }, ], }, ], From fcb8cc4d50408ccf07baf43ceefb42d2fe4a0ad0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9?= <583546+oandregal@users.noreply.github.com> Date: Thu, 8 Aug 2024 14:58:08 +0200 Subject: [PATCH 3/6] Disable sorting and filtering for comment_status field --- packages/edit-site/src/components/post-fields/index.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/edit-site/src/components/post-fields/index.js b/packages/edit-site/src/components/post-fields/index.js index 442670072b4d3d..c11c3f8745a659 100644 --- a/packages/edit-site/src/components/post-fields/index.js +++ b/packages/edit-site/src/components/post-fields/index.js @@ -350,6 +350,10 @@ function usePostFields( viewType ) { label: __( 'Discussion' ), type: 'text', editAs: 'radio', + enableSorting: false, + filterBy: { + operators: [], + }, elements: [ { value: 'open', From faf901db36f5643f098ea31d35c5511077c847a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9?= <583546+oandregal@users.noreply.github.com> Date: Fri, 9 Aug 2024 09:06:05 +0200 Subject: [PATCH 4/6] Implement radio control --- .../components/dataform-controls/index.tsx | 46 +++++++++++++++++++ .../components/dataform-controls/radio.tsx | 43 +++++++++++++++++ packages/dataviews/src/field-types/text.tsx | 18 +------- packages/dataviews/src/normalize-fields.ts | 3 +- packages/dataviews/src/types.ts | 27 ++++++++--- .../src/components/post-fields/index.js | 2 +- 6 files changed, 114 insertions(+), 25 deletions(-) create mode 100644 packages/dataviews/src/components/dataform-controls/index.tsx create mode 100644 packages/dataviews/src/components/dataform-controls/radio.tsx diff --git a/packages/dataviews/src/components/dataform-controls/index.tsx b/packages/dataviews/src/components/dataform-controls/index.tsx new file mode 100644 index 00000000000000..dd913269cd09ea --- /dev/null +++ b/packages/dataviews/src/components/dataform-controls/index.tsx @@ -0,0 +1,46 @@ +/** + * External dependencies + */ +import type { ComponentType } from 'react'; + +/** + * Internal dependencies + */ +import type { + DataFormControlProps, + Field, + FieldTypeDefinition, +} from '../../types'; +import radio from './radio'; + +interface FormControls { + [ key: string ]: ComponentType< DataFormControlProps< any > >; +} + +const FORM_CONTROLS: FormControls = { + radio, +}; + +export function getControl< Item >( + field: Field< Item >, + fieldTypeDefinition: FieldTypeDefinition< Item > +) { + if ( typeof field.Edit === 'function' ) { + return field.Edit; + } + + let control; + if ( typeof field.Edit === 'string' ) { + control = getControlByType( field.Edit ); + } + + return control || fieldTypeDefinition.Edit; +} + +export function getControlByType( type: string ) { + if ( Object.keys( FORM_CONTROLS ).includes( type ) ) { + return FORM_CONTROLS[ type ]; + } + + return null; +} diff --git a/packages/dataviews/src/components/dataform-controls/radio.tsx b/packages/dataviews/src/components/dataform-controls/radio.tsx new file mode 100644 index 00000000000000..d264aa6c24b7fb --- /dev/null +++ b/packages/dataviews/src/components/dataform-controls/radio.tsx @@ -0,0 +1,43 @@ +/** + * WordPress dependencies + */ +import { RadioControl } from '@wordpress/components'; +import { useCallback } from '@wordpress/element'; + +/** + * Internal dependencies + */ +import type { DataFormControlProps } from '../../types'; + +export default function Edit< Item >( { + data, + field, + onChange, + hideLabelFromVision, +}: DataFormControlProps< Item > ) { + const { id, label } = field; + const value = field.getValue( { item: data } ); + + const onChangeControl = useCallback( + ( newValue: string ) => + onChange( ( prevItem: Item ) => ( { + ...prevItem, + [ id ]: newValue, + } ) ), + [ id, onChange ] + ); + + if ( field.elements ) { + return ( + + ); + } + + return null; +} diff --git a/packages/dataviews/src/field-types/text.tsx b/packages/dataviews/src/field-types/text.tsx index 6316d9544ca8dc..c6efb85f6f446b 100644 --- a/packages/dataviews/src/field-types/text.tsx +++ b/packages/dataviews/src/field-types/text.tsx @@ -1,11 +1,7 @@ /** * WordPress dependencies */ -import { - SelectControl, - TextControl, - RadioControl, -} from '@wordpress/components'; +import { SelectControl, TextControl } from '@wordpress/components'; import { useCallback } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; @@ -53,18 +49,6 @@ function Edit< Item >( { [ id, onChange ] ); - if ( field.elements && field.editAs === 'radio' ) { - return ( - - ); - } - if ( field.elements ) { const elements = [ /* diff --git a/packages/dataviews/src/normalize-fields.ts b/packages/dataviews/src/normalize-fields.ts index 680749df5344a6..54992ff22fe2ae 100644 --- a/packages/dataviews/src/normalize-fields.ts +++ b/packages/dataviews/src/normalize-fields.ts @@ -3,6 +3,7 @@ */ import getFieldTypeDefinition from './field-types'; import type { Field, NormalizedField } from './types'; +import { getControl } from './components/dataform-controls'; /** * Apply default values and normalize the fields config. @@ -38,7 +39,7 @@ export function normalizeFields< Item >( ); }; - const Edit = field.Edit || fieldTypeDefinition.Edit; + const Edit = getControl( field, fieldTypeDefinition ); const renderFromElements = ( { item }: { item: Item } ) => { const value = getValue( { item } ); diff --git a/packages/dataviews/src/types.ts b/packages/dataviews/src/types.ts index 0b32f78a4eb0b4..d8a5ee8f68ecef 100644 --- a/packages/dataviews/src/types.ts +++ b/packages/dataviews/src/types.ts @@ -53,6 +53,26 @@ export type ValidationContext = { elements?: Option[]; }; +/** + * An abstract interface for Field based on the field type. + */ +export type FieldTypeDefinition< Item > = { + /** + * Callback used to sort the field. + */ + sort: ( a: Item, b: Item, direction: SortDirection ) => number; + + /** + * Callback used to validate the field. + */ + isValid: ( item: Item, context?: ValidationContext ) => boolean; + + /** + * Callback used to render an edit control for the field. + */ + Edit: ComponentType< DataFormControlProps< Item > >; +}; + /** * A dataview field for a specific property of a data type. */ @@ -90,12 +110,7 @@ export type Field< Item > = { /** * Callback used to render an edit control for the field. */ - Edit?: ComponentType< DataFormControlProps< Item > >; - - /** - * Optional config for editing the field. - */ - editAs?: 'radio'; + Edit?: ComponentType< DataFormControlProps< Item > > | 'radio'; /** * Callback used to sort the field. diff --git a/packages/edit-site/src/components/post-fields/index.js b/packages/edit-site/src/components/post-fields/index.js index c11c3f8745a659..b03b2c6f5be3c4 100644 --- a/packages/edit-site/src/components/post-fields/index.js +++ b/packages/edit-site/src/components/post-fields/index.js @@ -349,7 +349,7 @@ function usePostFields( viewType ) { id: 'comment_status', label: __( 'Discussion' ), type: 'text', - editAs: 'radio', + Edit: 'radio', enableSorting: false, filterBy: { operators: [], From 5cb2991ff9e498e620fc55699170e76e965d9b51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9?= <583546+oandregal@users.noreply.github.com> Date: Fri, 9 Aug 2024 09:27:35 +0200 Subject: [PATCH 5/6] Fix rebase --- packages/edit-site/src/components/post-edit/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/edit-site/src/components/post-edit/index.js b/packages/edit-site/src/components/post-edit/index.js index f189fb9ece640e..7c1243fcf6e885 100644 --- a/packages/edit-site/src/components/post-edit/index.js +++ b/packages/edit-site/src/components/post-edit/index.js @@ -46,7 +46,7 @@ function PostEditForm( { postType, postId } ) { const { saveEntityRecord } = useDispatch( coreDataStore ); const { fields } = usePostFields(); const form = { - type: 'regular', + type: 'panel', fields: [ 'title', 'author', 'date', 'comment_status' ], }; const [ edits, setEdits ] = useState( initialEdits ); From 5d19c9b373ec2963289b45deada95783d772b34b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9?= <583546+oandregal@users.noreply.github.com> Date: Fri, 9 Aug 2024 10:23:17 +0200 Subject: [PATCH 6/6] Add story about Edit:radio --- .../dataform/stories/index.story.tsx | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/packages/dataviews/src/components/dataform/stories/index.story.tsx b/packages/dataviews/src/components/dataform/stories/index.story.tsx index 7808756b7b6557..7f3c5ff879b72a 100644 --- a/packages/dataviews/src/components/dataform/stories/index.story.tsx +++ b/packages/dataviews/src/components/dataform/stories/index.story.tsx @@ -56,6 +56,17 @@ const fields = [ { value: 2, label: 'John' }, ], }, + { + id: 'reviewer', + label: 'Reviewer', + type: 'text' as const, + Edit: 'radio' as const, + elements: [ + { value: 'fulano', label: 'Fulano' }, + { value: 'mengano', label: 'Mengano' }, + { value: 'zutano', label: 'Zutano' }, + ], + }, { id: 'status', label: 'Status', @@ -73,12 +84,21 @@ export const Default = ( { type }: { type: 'panel' | 'regular' } ) => { order: 2, author: 1, status: 'draft', + reviewer: 'fulano', date: '2021-01-01T12:00:00', birthdate: '1950-02-23T12:00:00', } ); const form = { - fields: [ 'title', 'order', 'author', 'status', 'date', 'birthdate' ], + fields: [ + 'title', + 'order', + 'author', + 'reviewer', + 'status', + 'date', + 'birthdate', + ], }; return (