From 8570bc4667d944c3f14fbc9b6ae8cb8f6e487b64 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Fri, 9 Aug 2024 10:44:14 +0200 Subject: [PATCH] DataViews Quick Edit: Rely on the global save flow instead of a custom save button --- packages/dataviews/CHANGELOG.md | 1 + .../dataform/stories/index.story.tsx | 7 +- .../dataviews/src/field-types/datetime.tsx | 6 +- .../dataviews/src/field-types/integer.tsx | 7 +- packages/dataviews/src/field-types/text.tsx | 5 +- packages/dataviews/src/types.ts | 11 +-- .../src/components/post-edit/index.js | 73 ++++++------------- .../src/components/post-actions/actions.js | 7 +- .../src/dataviews/actions/reorder-page.tsx | 7 +- 9 files changed, 51 insertions(+), 73 deletions(-) diff --git a/packages/dataviews/CHANGELOG.md b/packages/dataviews/CHANGELOG.md index 239a69651a1f27..b1cb4504e72fad 100644 --- a/packages/dataviews/CHANGELOG.md +++ b/packages/dataviews/CHANGELOG.md @@ -16,6 +16,7 @@ - `setSelection` prop has been removed. Please use `onChangeSelection` instead. - `header` field property has been renamed to `label`. - `DataForm`'s `visibleFields` prop has been renamed to `fields`. +- `DataForm`'s `onChange` prop has been update to receive as argument only the fields that have changed. ### New features diff --git a/packages/dataviews/src/components/dataform/stories/index.story.tsx b/packages/dataviews/src/components/dataform/stories/index.story.tsx index 7808756b7b6557..3daabed9e237f3 100644 --- a/packages/dataviews/src/components/dataform/stories/index.story.tsx +++ b/packages/dataviews/src/components/dataform/stories/index.story.tsx @@ -89,7 +89,12 @@ export const Default = ( { type }: { type: 'panel' | 'regular' } ) => { ...form, type, } } - onChange={ setPost } + onChange={ ( edits ) => + setPost( ( prev ) => ( { + ...prev, + ...edits, + } ) ) + } /> ); }; diff --git a/packages/dataviews/src/field-types/datetime.tsx b/packages/dataviews/src/field-types/datetime.tsx index 3861a0db635d7b..c6b69048efe13c 100644 --- a/packages/dataviews/src/field-types/datetime.tsx +++ b/packages/dataviews/src/field-types/datetime.tsx @@ -41,11 +41,7 @@ function Edit< Item >( { const value = field.getValue( { item: data } ); const onChangeControl = useCallback( - ( newValue: string | null ) => - onChange( ( prevItem: Item ) => ( { - ...prevItem, - [ id ]: newValue, - } ) ), + ( newValue: string | null ) => onChange( { [ id ]: newValue } ), [ id, onChange ] ); diff --git a/packages/dataviews/src/field-types/integer.tsx b/packages/dataviews/src/field-types/integer.tsx index 1233c3ab555567..38570ea6fec1a5 100644 --- a/packages/dataviews/src/field-types/integer.tsx +++ b/packages/dataviews/src/field-types/integer.tsx @@ -51,10 +51,9 @@ function Edit< Item >( { const value = field.getValue( { item: data } ) ?? ''; const onChangeControl = useCallback( ( newValue: string | undefined ) => - onChange( ( prevItem: Item ) => ( { - ...prevItem, - [ id ]: newValue, - } ) ), + onChange( { + [ id ]: Number( newValue ), + } ), [ id, onChange ] ); diff --git a/packages/dataviews/src/field-types/text.tsx b/packages/dataviews/src/field-types/text.tsx index c6efb85f6f446b..5364017c629b00 100644 --- a/packages/dataviews/src/field-types/text.tsx +++ b/packages/dataviews/src/field-types/text.tsx @@ -42,10 +42,9 @@ function Edit< Item >( { const onChangeControl = useCallback( ( newValue: string ) => - onChange( ( prevItem: Item ) => ( { - ...prevItem, + onChange( { [ id ]: newValue, - } ) ), + } ), [ id, onChange ] ); diff --git a/packages/dataviews/src/types.ts b/packages/dataviews/src/types.ts index 2e87d1371acb61..c45f3be1d1a6a3 100644 --- a/packages/dataviews/src/types.ts +++ b/packages/dataviews/src/types.ts @@ -1,12 +1,7 @@ /** * External dependencies */ -import type { - ReactElement, - ComponentType, - Dispatch, - SetStateAction, -} from 'react'; +import type { ReactElement, ComponentType } from 'react'; /** * Internal dependencies @@ -161,7 +156,7 @@ export type Form = { export type DataFormControlProps< Item > = { data: Item; field: NormalizedField< Item >; - onChange: Dispatch< SetStateAction< Item > >; + onChange: ( value: Record< string, any > ) => void; hideLabelFromVision?: boolean; }; @@ -496,5 +491,5 @@ export interface DataFormProps< Item > { data: Item; fields: Field< Item >[]; form: Form; - onChange: Dispatch< SetStateAction< Item > >; + onChange: ( value: Record< string, any > ) => void; } diff --git a/packages/edit-site/src/components/post-edit/index.js b/packages/edit-site/src/components/post-edit/index.js index 35141f743cd2e3..198cfeb50461a9 100644 --- a/packages/edit-site/src/components/post-edit/index.js +++ b/packages/edit-site/src/components/post-edit/index.js @@ -7,15 +7,11 @@ import clsx from 'clsx'; * WordPress dependencies */ import { __ } from '@wordpress/i18n'; -import { DataForm, isItemValid } from '@wordpress/dataviews'; -import { useDispatch, useSelect, useRegistry } from '@wordpress/data'; +import { DataForm } from '@wordpress/dataviews'; +import { useDispatch, useSelect } from '@wordpress/data'; import { store as coreDataStore } from '@wordpress/core-data'; -import { - Button, - FlexItem, - __experimentalVStack as VStack, -} from '@wordpress/components'; -import { useState, useMemo } from '@wordpress/element'; +import { __experimentalVStack as VStack } from '@wordpress/components'; +import { useState, useMemo, useEffect } from '@wordpress/element'; import { privateApis as editorPrivateApis } from '@wordpress/editor'; /** @@ -29,14 +25,12 @@ const { PostCardPanel } = unlock( editorPrivateApis ); function PostEditForm( { postType, postId } ) { const ids = useMemo( () => postId.split( ',' ), [ postId ] ); - const { initialEdits } = useSelect( + const { record } = useSelect( ( select ) => { - if ( ids.length !== 1 ) { - } return { - initialEdits: + record: ids.length === 1 - ? select( coreDataStore ).getEntityRecord( + ? select( coreDataStore ).getEditedEntityRecord( 'postType', postType, ids[ 0 ] @@ -46,60 +40,39 @@ function PostEditForm( { postType, postId } ) { }, [ postType, ids ] ); - const registry = useRegistry(); - const { saveEntityRecord } = useDispatch( coreDataStore ); + const [ multiEdits, setMultiEdits ] = useState( {} ); + const { editEntityRecord } = useDispatch( coreDataStore ); const { fields } = usePostFields(); const form = { type: 'panel', fields: [ 'title', 'author', 'date' ], }; - const [ edits, setEdits ] = useState( initialEdits ); - const itemWithEdits = useMemo( () => { - return { - ...initialEdits, - ...edits, - }; - }, [ initialEdits, edits ] ); - const onSubmit = async ( event ) => { - event.preventDefault(); - - if ( ! isItemValid( itemWithEdits, fields, form ) ) { - return; - } - - const { getEntityRecord } = registry.resolveSelect( coreDataStore ); + const onChange = ( edits ) => { for ( const id of ids ) { - const item = await getEntityRecord( 'postType', postType, id ); - saveEntityRecord( 'postType', postType, { - ...item, - ...edits, - } ); + editEntityRecord( 'postType', postType, id, edits ); + if ( ids.length > 1 ) { + setMultiEdits( ( prev ) => ( { + ...prev, + ...edits, + } ) ); + } } }; + useEffect( () => { + setMultiEdits( {} ); + }, [ ids ] ); - const isUpdateDisabled = ! isItemValid( itemWithEdits, fields, form ); return ( - + { ids.length === 1 && ( ) } - - - ); } diff --git a/packages/editor/src/components/post-actions/actions.js b/packages/editor/src/components/post-actions/actions.js index 5e727376a92258..ff5cd7ddbb5452 100644 --- a/packages/editor/src/components/post-actions/actions.js +++ b/packages/editor/src/components/post-actions/actions.js @@ -234,7 +234,12 @@ const useDuplicatePostAction = ( postType ) => { data={ item } fields={ fields } form={ formDuplicateAction } - onChange={ setItem } + onChange={ ( changes ) => + setItem( { + ...item, + ...changes, + } ) + } />