Make WordPress Core

Opened 4 weeks ago

Last modified 12 days ago

#65890 new enhancement

Add a Notes section in the Dashboard Activity widget

Reported by: adamsilverstein Owned by:
Priority: normal Milestone: Awaiting Review
Component: Editor Version:
Severity: normal Keywords: has-patch
Cc: Focuses:

Description

Claude drafted the write-up below after a pass through the existing Notes and Activity widget tickets.

Notes landed in 6.9 with #64096 and have kept growing since: post author notifications in 6.9 (#64204), inline notes anchored to a text selection in 7.1 (#65482), and @mention notifications in 7.1 (#65639). The one place to actually read a note is still the block editor, one post at a time.

So there is no answer anywhere in wp-admin to "where is collaboration happening right now?" A note left on your draft reaches you by email, or it does not reach you at all until you happen to open the post. The Dashboard is where a lot of editors start their day, and the Activity widget already answers the two questions either side of this one - what published recently, and what did visitors say - while staying quiet about the editorial conversation.

Proposal

Add a Notes section to the Activity widget, alongside Publishing Soon, Recently Published and Recent Comments.

  • Unresolved notes only, newest first, capped at 5, matching the other sections.
  • Only notes on posts the current user can edit_post, which is the same visibility rule WP_REST_Comments_Controller already applies to notes.
  • Each row shows the note author, a short excerpt, the post title and a relative date, linking through to the post editor.
  • The section is omitted entirely when there is nothing to show, so a single author site sees no change.
  • A dashboard_recent_notes_query_args filter, mirroring the existing dashboard_recent_posts_query_args.

Shape-wise that is a wp_dashboard_recent_notes() sibling to wp_dashboard_recent_comments() in wp-admin/includes/dashboard.php, called from wp_dashboard_site_activity().

Implementation notes

  • wp_dashboard_recent_comments() calls get_comments() with no type, and since 6.9 WP_Comment_Query excludes note by default (#63999, #64145), so Recent Comments is already clean. Notes need a separate query passing 'type' => 'note' explicitly.
  • Resolution status lives in the _wp_note_status comment meta (resolved / reopen), registered in wp_create_initial_comment_meta(). Filtering down to unresolved means a comment meta query, which is worth measuring before it gets committed to - the Activity widget already carries a query complaint in #64506.
  • Note content can contain <span class="wp-note-mention user-N"> markup. The excerpt needs to render or strip that sensibly rather than dumping raw HTML into the widget. wp_get_note_mentioned_user_ids() (added in 7.1) is the existing parser for it.
  • Limit to post types that actually support notes, ie. 'editor' => array( 'notes' => true ) in supports, the same check WP_REST_Comments_Controller::check_post_type_supports_notes() makes.
  • There is no deep link to an individual note yet. The editor registers an edit-post/collab-history-sidebar sidebar but no URL parameter opens it on a specific note, so linking to the post editor is the honest first step and anchoring can be a follow up.

Prior art

This ground has been circled before, so worth being explicit about what is different here.

#64377 adds a Notes column to the posts list table (has-patch, PR https://github.com/WordPress/wordpress-develop/pull/10611). That answers "does this post have notes?" while you are already browsing posts. A dashboard section answers "is anything waiting for me?" before you go looking. Those feel complementary rather than overlapping, but if only one of the two is wanted, that is worth settling here.

Gutenberg explored a broader version of this in https://github.com/WordPress/gutenberg/issues/71622 and the closed PR https://github.com/WordPress/gutenberg/pull/71743, which added a posts list column plus a dedicated editorial comments screen. The design feedback there was that notes are scoped to a block, and increasingly to a text selection, so listing them away from that context risks confusion - and moderation UI in particular does not belong outside the editor.

The proposal here tries to respect that. It is read only, carries no moderation actions, and points back into the editor rather than trying to replace it. That is still the main concern to weigh though, and design input would be welcome before any patch.

Open questions

  • All notes on posts the user can edit, or only notes that @mention them? Mentions are parseable via wp_get_note_mentioned_user_ids() but they are not indexed, so "mentions you" cannot be done in SQL without storing something extra.
  • Should replies collapse into their parent thread, or list individually?
  • Should resolved notes appear at all, or only unresolved ones?
  • Does this belong inside the Activity widget, or as its own dashboard widget that users can move and hide?

Related: #64096, #64204, #64377, #64506, #65537, #65639, #37578.

Gutenberg: https://github.com/WordPress/gutenberg/issues/80015, https://github.com/WordPress/gutenberg/issues/72184, https://github.com/WordPress/gutenberg/issues/73273

Change History (6)

This ticket was mentioned in PR #13076 on WordPress/wordpress-develop by mcrisp1972.


4 weeks ago
#1

  • Keywords has-patch added; needs-patch removed

NOT Ready for review and merge yet.

We are adding notes posted to blocks in the editor to the Recent Activity widget in the admin dashboard.

@adamsilverstein commented on PR #13076:


4 weeks ago
#2

Working on this a few points emerged:

  • Rather than showing recent Notes, we decided to show the _Posts with the most recent notes or replies_. There is no "Notes" screen to link to, when you have a new note, the main action is to view the note on the edit post screen.
  • Showing the most date is tricky, we need only unresolved threads, which is recorded at the top level note - but we still want the date from the most recent reply. This complicated querying for the notes to get what we needed.

@adamsilverstein commented on PR #13076:


4 weeks ago
#3

_I had Claude review the branch, and pushed what it turned up:_

Two commits, both on top of the existing work here.

d4d46783a1 bounds the paging loop. Notes are only listed for posts the current user can edit, so a user who can edit none of them - a Subscriber, or an Author on a multi-author site - never satisfied the while condition and paged through every open note on the site, 50 at a time. On a busy site that is a lot of get_comments() calls per dashboard load. Paging now stops after a hundred notes per row have been examined. The same commit adds update_comment_post_cache (the current_user_can( 'edit_post', ... ) check was pulling one get_post() query per note) and turns off update_comment_meta_cache, which was priming meta on every scanned note that nothing ever reads.

c8c9b7f167 is the row layout. The markup was title, count, date, so the title landed in the narrow clamped column that #published-posts reserves for the date, and the "4 open notes" string stretched across the free space instead. Any title of normal length wrapped in a ~170px column with a wide gap next to it. Rows are now date, title, count, which lines the Notes section up with Recently Published directly above it - see the refreshed screenshots in the description. That commit also drops a duplicated #latest-notes block at the bottom of dashboard.css (every declaration in it was already set earlier in the file), and guards get_edit_post_link(), which returns null for a post deleted between the query and the render and was reaching esc_url() as a PHP 8.1 deprecation.

Tests came along with each: the paging bound, the edit link guard, and the two row helpers that read the date out of the markup. --group notes,dashboard,admin,comment is green at 1657 tests, and PHPCS and PHPStan are clean.

One review note that turned out to be a non-issue, for the record: orderby looked like it needed a comment_ID tiebreaker for stable paging, but WP_Comment_Query already appends one to any orderby - see https://github.com/WordPress/wordpress-develop/blob/trunk/src/wp-includes/class-wp-comment-query.php#L672-L703. Nothing to do there.

@mcrisp1972 does the date-first row order look right to you? Happy to put it back if you had a reason for leading with the title.

@mcrisp1972 commented on PR #13076:


4 weeks ago
#4

_I had Claude review the branch, and pushed what it turned up:_

Two commits, both on top of the existing work here.

d4d4678 bounds the paging loop. Notes are only listed for posts the current user can edit, so a user who can edit none of them - a Subscriber, or an Author on a multi-author site - never satisfied the while condition and paged through every open note on the site, 50 at a time. On a busy site that is a lot of get_comments() calls per dashboard load. Paging now stops after a hundred notes per row have been examined. The same commit adds update_comment_post_cache (the current_user_can( 'edit_post', ... ) check was pulling one get_post() query per note) and turns off update_comment_meta_cache, which was priming meta on every scanned note that nothing ever reads.

c8c9b7f is the row layout. The markup was title, count, date, so the title landed in the narrow clamped column that #published-posts reserves for the date, and the "4 open notes" string stretched across the free space instead. Any title of normal length wrapped in a ~170px column with a wide gap next to it. Rows are now date, title, count, which lines the Notes section up with Recently Published directly above it - see the refreshed screenshots in the description. That commit also drops a duplicated #latest-notes block at the bottom of dashboard.css (every declaration in it was already set earlier in the file), and guards get_edit_post_link(), which returns null for a post deleted between the query and the render and was reaching esc_url() as a PHP 8.1 deprecation.

Tests came along with each: the paging bound, the edit link guard, and the two row helpers that read the date out of the markup. --group notes,dashboard,admin,comment is green at 1657 tests, and PHPCS and PHPStan are clean.

One review note that turned out to be a non-issue, for the record: orderby looked like it needed a comment_ID tiebreaker for stable paging, but WP_Comment_Query already appends one to any orderby - see https://github.com/WordPress/wordpress-develop/blob/trunk/src/wp-includes/class-wp-comment-query.php#L672-L703. Nothing to do there.

@mcrisp1972 does the date-first row order look right to you? Happy to put it back if you had a reason for leading with the title.

@adamsilverstein

_I had Claude review the branch, and pushed what it turned up:_

Two commits, both on top of the existing work here.

d4d4678 bounds the paging loop. Notes are only listed for posts the current user can edit, so a user who can edit none of them - a Subscriber, or an Author on a multi-author site - never satisfied the while condition and paged through every open note on the site, 50 at a time. On a busy site that is a lot of get_comments() calls per dashboard load. Paging now stops after a hundred notes per row have been examined. The same commit adds update_comment_post_cache (the current_user_can( 'edit_post', ... ) check was pulling one get_post() query per note) and turns off update_comment_meta_cache, which was priming meta on every scanned note that nothing ever reads.

c8c9b7f is the row layout. The markup was title, count, date, so the title landed in the narrow clamped column that #published-posts reserves for the date, and the "4 open notes" string stretched across the free space instead. Any title of normal length wrapped in a ~170px column with a wide gap next to it. Rows are now date, title, count, which lines the Notes section up with Recently Published directly above it - see the refreshed screenshots in the description. That commit also drops a duplicated #latest-notes block at the bottom of dashboard.css (every declaration in it was already set earlier in the file), and guards get_edit_post_link(), which returns null for a post deleted between the query and the render and was reaching esc_url() as a PHP 8.1 deprecation.

Tests came along with each: the paging bound, the edit link guard, and the two row helpers that read the date out of the markup. --group notes,dashboard,admin,comment is green at 1657 tests, and PHPCS and PHPStan are clean.

One review note that turned out to be a non-issue, for the record: orderby looked like it needed a comment_ID tiebreaker for stable paging, but WP_Comment_Query already appends one to any orderby - see https://github.com/WordPress/wordpress-develop/blob/trunk/src/wp-includes/class-wp-comment-query.php#L672-L703. Nothing to do there.

@mcrisp1972 does the date-first row order look right to you? Happy to put it back if you had a reason for leading with the title.

@adamsilverstein , Jen

Update the layout and view

@adamsilverstein , this is looking good. Regarding the ordering of row date and title, Jen and @aosmichenko built out the rows, so we might want their input on that, but I think the date first makes sense, especially if that is the sorted field.

@aosmichenko commented on PR #13076:


4 weeks ago
#5

I was initially thing of making "time ago" format, so if you would rather do that instead. I have no hard preferences on the format and column order, was trying to find the most useful to read.

@adamsilverstein commented on PR #13076:


12 days ago
#6

I was initially thinking of making "time ago" format, so if you would rather do that instead. I have no hard preferences on the format and column order, was trying to find the most useful to read.

I like the human readable time ago format, we use that for most user facing dates.

Note: See TracTickets for help on using tickets.