-
Notifications
You must be signed in to change notification settings - Fork 4.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add status
entity and use it in "admin views" experiment
#55050
Changes from all commits
7600286
16cd768
1347cec
96a0feb
86c8b42
1ddc450
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -22,6 +22,7 @@ import PageActions from '../page-actions'; | |
import { DataViews, PAGE_SIZE_VALUES } from '../dataviews'; | ||
|
||
const EMPTY_ARRAY = []; | ||
const EMPTY_OBJECT = {}; | ||
|
||
export default function PagePages() { | ||
const [ reset, setResetQuery ] = useState( ( v ) => ! v ); | ||
|
@@ -32,12 +33,14 @@ export default function PagePages() { | |
pageSize: PAGE_SIZE_VALUES[ 0 ], | ||
} ); | ||
// Request post statuses to get the proper labels. | ||
const [ postStatuses, setPostStatuses ] = useState( EMPTY_ARRAY ); | ||
useEffect( () => { | ||
apiFetch( { | ||
path: '/wp/v2/statuses', | ||
} ).then( setPostStatuses ); | ||
}, [] ); | ||
const { records: statuses } = useEntityRecords( 'root', 'status' ); | ||
const postStatuses = | ||
statuses === null | ||
? EMPTY_OBJECT | ||
: statuses.reduce( ( acc, status ) => { | ||
acc[ status.slug ] = status.name; | ||
return acc; | ||
}, EMPTY_OBJECT ); | ||
Comment on lines
+37
to
+43
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @oandregal: This breaks a few things in the component — even though right now that's asymptomatic. :) The cause is the use of
Proof of bug: const EMPTY_OBJECT = {};
function getPostStatuses( rawStatuses ) {
return rawStatuses === null
? EMPTY_OBJECT
: rawStatuses.reduce( ( acc, status ) => {
acc[ status.slug ] = status.name;
return acc;
}, EMPTY_OBJECT );
}
const before = getPostStatuses( null );
const after = getPostStatuses( [ { slug: 'draft', name: 'Draft' } ] );
console.log( 'Has the reference changed?', before !== after );
console.log(
'Is EMPTY_OBJECT empty?',
Object.keys( EMPTY_OBJECT ).length === 0
); The immediate fix is to not use const postStatuses =
statuses === null
? EMPTY_OBJECT
: statuses.reduce( ( acc, status ) => {
acc[ status.slug ] = status.name;
return acc;
- }, EMPTY_OBJECT );
+ }, {} ); But of course this means that const postStatuses = useMemo(
() =>
statuses === null
? EMPTY_OBJECT
: Object.fromEntries(
statuses.map( ( { slug, name } ) => [ slug, name ] )
),
[ statuses ]
); I'll turn this into a PR, but I wanted to give you my full explanation first! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. -> #55314 |
||
|
||
// TODO: probably memo other objects passed as state(ex:https://tanstack.com/table/v8/docs/examples/react/pagination-controlled). | ||
const pagination = useMemo( | ||
|
@@ -66,7 +69,7 @@ export default function PagePages() { | |
reset, | ||
] | ||
); | ||
const { records, isResolving: isLoading } = useEntityRecords( | ||
const { records: pages, isResolving: isLoadingPages } = useEntityRecords( | ||
'postType', | ||
'page', | ||
queryArgs | ||
|
@@ -136,7 +139,8 @@ export default function PagePages() { | |
header: 'Status', | ||
id: 'status', | ||
cell: ( props ) => | ||
postStatuses[ props.row.original.status ]?.name, | ||
postStatuses[ props.row.original.status ] ?? | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I thought I'd also update the fallback we show when the post statuses retrieval goes wrong (statuses are unavailable or just take a while to load): instead of leaving them blank, we can use the already available |
||
props.row.original.status, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Where does this come from? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. oh you show the key. Fine 👍 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we need to show the key here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There's an advantage to pre-filling the table with the slug status over starting with an empty string: it acts as a better placeholder for the content. By using the slug as fallback, the table already has the size of the content (because the slug for |
||
}, | ||
{ | ||
header: <VisuallyHidden>{ __( 'Actions' ) }</VisuallyHidden>, | ||
|
@@ -161,8 +165,8 @@ export default function PagePages() { | |
<Page title={ __( 'Pages' ) }> | ||
<DataViews | ||
paginationInfo={ paginationInfo } | ||
data={ records || EMPTY_ARRAY } | ||
isLoading={ isLoading } | ||
data={ pages || EMPTY_ARRAY } | ||
isLoading={ isLoadingPages } | ||
fields={ fields } | ||
options={ { | ||
manualSorting: true, | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wanted to optimize the status retrieval to:
name
andslug
, not all schema fields.publish
,draft
), as the page entity only requests pages with those statuses.Though it doesn't seem the statuses endpoint supports that kind of filtering.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sometimes it's better to load the full object for performance, that way it's cached and shared with other usage of the same entity.
Not sure it applies here but yeah, this seems fine to me I think