Skip to content

Conversation

@enejb
Copy link
Member

@enejb enejb commented Feb 3, 2026

Draft:
Screenshot 2026-02-02 at 4 50 19 PM

Pending:
Screenshot 2026-02-02 at 4 50 02 PM

Private:
Screenshot 2026-02-02 at 4 49 46 PM

Scheduled:
Screenshot 2026-02-02 at 4 49 22 PM

Trashed:
Screenshot 2026-02-02 at 4 51 54 PM

Proposed changes:

When a synced form is displayed in the block editor, users
currently have no indication of the form's post status. A form
could be trashed or in draft status, but this is invisible to
editors.

This PR adds a notice that displays when a synced form has a
status other than "publish":

  • Error notice for trashed forms
  • Warning notice for draft and pending forms
  • Info notice for scheduled (future) and private forms

For non-trashed forms, a "Publish now" button allows users to
publish the form directly from the notice.

Other information:

  • Have you written new tests for your changes, if applicable?
  • Have you checked the E2E test CI results, and verified that your changes do not break them?
  • Have you tested your changes on WordPress.com, if applicable (if so, you'll see a generated comment below with a script to run)?

Jetpack product discussion

No

Does this pull request change what data or activity we track or use?

No

Testing instructions:

Enable CFM via

add_filter( 'jetpack_block_editor_feature_flags', 'eb_register_feature' );

function eb_register_feature( $flags ) {
    $flags['central-form-management'] = ! isset( $_GET[  'not-cfm' ] );
    return $flags;
}
  1. Create a new synced form (insert a Contact Form block and

save)
2. In the WordPress admin, go to Posts > All Posts (or use the
database) and find the jetpack_form post type entry
3. Change the form's status to draft via quick edit or the
database
4. Insert the same form into a post using the Form block with
a reference
5. Verify that a warning notice appears above the form
stating "This form is a draft and will not be displayed on the frontend until published."
6. Verify there is a "Publish now" button in the notice
7. Click "Publish now" and verify the notice disappears after the form is published
8. Repeat testing with other statuses:
- trash - should show error notice without publish button
- pending - should show warning notice with publish button
- private - should show info notice with publish button
9. Verify that published forms show no notice

Add an editor notice for synced forms that are not published and provide a "Publish now" action. Changes include: new changelog entry; import Button, useState and sprintf in edit.tsx; add saveEditedEntityRecord dispatch and isPublishing state; implement handlePublishForm to set status to publish and save the entity; add a statusNotice config and render it above the block content; include SCSS for notice spacing and button margin; update the JetpackForm type to include status. Purpose: inform editors when a synced form won't display on the frontend and allow quick publishing from the block editor.
@enejb enejb requested review from a team and Copilot February 3, 2026 00:54
@enejb enejb added [Type] Enhancement Changes to an existing feature — removing, adding, or changing parts of it [Status] Needs Review This PR is ready for review. [Package] Forms labels Feb 3, 2026
@github-actions
Copy link
Contributor

github-actions bot commented Feb 3, 2026

Are you an Automattician? Please test your changes on all WordPress.com environments to help mitigate accidental explosions.

  • To test on WoA, go to the Plugins menu on a WoA dev site. Click on the "Upload" button and follow the upgrade flow to be able to upload, install, and activate the Jetpack Beta plugin. Once the plugin is active, go to Jetpack > Jetpack Beta, select your plugin (Jetpack), and enable the fix/form-statuses-notice branch.
  • To test on Simple, run the following command on your sandbox:
bin/jetpack-downloader test jetpack fix/form-statuses-notice

Interested in more tips and information?

  • In your local development environment, use the jetpack rsync command to sync your changes to a WoA dev blog.
  • Read more about our development workflow here: PCYsg-eg0-p2
  • Figure out when your changes will be shipped to customers here: PCYsg-eg5-p2

@github-actions github-actions bot added [Block] Contact Form Form block (also see Contact Form label) [Feature] Contact Form labels Feb 3, 2026
@github-actions
Copy link
Contributor

github-actions bot commented Feb 3, 2026

Thank you for your PR!

When contributing to Jetpack, we have a few suggestions that can help us test and review your patch:

  • ✅ Include a description of your PR changes.
  • ✅ Add a "[Status]" label (In Progress, Needs Review, ...).
  • ✅ Add testing instructions.
  • ✅ Specify whether this PR includes any changes to data or privacy.
  • ✅ Add changelog entries to affected projects

This comment will be updated as you work on your PR and make changes. If you think that some of those checks are not needed for your PR, please explain why you think so. Thanks for cooperation 🤖


Follow this PR Review Process:

  1. Ensure all required checks appearing at the bottom of this PR are passing.
  2. Make sure to test your changes on all platforms that it applies to. You're responsible for the quality of the code you ship.
  3. You can use GitHub's Reviewers functionality to request a review.
  4. When it's reviewed and merged, you will be pinged in Slack to deploy the changes to WordPress.com simple once the build is done.

If you have questions about anything, reach out in #jetpack-developers for guidance!

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds an editor-only status notice for synced Contact Form blocks so editors can see when the referenced jetpack_form is not publish, and (when possible) publish it directly from the notice.

Changes:

  • Extend synced form loading to include the referenced form’s status.
  • Render a non-dismissible Notice above the synced form in the block editor for non-publish statuses, with a “Publish now” action for eligible statuses.
  • Add styling and a changelog entry for the new editor notice.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 5 comments.

File Description
projects/packages/forms/src/blocks/contact-form/hooks/use-synced-form.ts Adds status to the typed shape of the fetched synced form record.
projects/packages/forms/src/blocks/contact-form/editor.scss Styles the new synced-form status notice and its button spacing.
projects/packages/forms/src/blocks/contact-form/edit.tsx Implements status notice UI and publish action for synced forms in the editor.
projects/packages/forms/changelog/fix-form-statuses-notice Adds a patch-level changelog entry for the editor status notice feature.

Comment on lines 379 to 383
setIsPublishingForm( true );
try {
await editEntityRecord( 'postType', FORM_POST_TYPE, ref, { status: 'publish' } );
await saveEditedEntityRecord( 'postType', FORM_POST_TYPE, ref );
} finally {
Copy link

Copilot AI Feb 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

handlePublishForm doesn’t handle save failures. If saveEditedEntityRecord rejects (permissions/network/etc.), the button just stops spinning with no feedback. Please add error handling (e.g., show a createErrorNotice from @wordpress/notices, similar to convert-form-toolbar.tsx) so users understand the publish action failed.

Copilot uses AI. Check for mistakes.
Comment on lines 1232 to 1235

.components-button {
margin-left: 8px;
}
Copy link

Copilot AI Feb 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SCSS uses physical direction (margin-left) which is not RTL/writing-mode friendly. Prefer logical properties here (e.g., margin-inline-start) so spacing works automatically in RTL layouts. See https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Logical_Properties

Copilot uses AI. Check for mistakes.
@jp-launch-control
Copy link

jp-launch-control bot commented Feb 3, 2026

Code Coverage Summary

No summary data is available for parent commit 1139c32, so cannot calculate coverage changes. 😴

If that commit is a feature branch rather than a trunk commit, this is expected. Otherwise, this should be updated once coverage for 1139c32 is available.

Full summary · PHP report · JS report

Copilot AI review requested due to automatic review settings February 3, 2026 01:57
@lezama
Copy link
Contributor

lezama commented Feb 3, 2026

@claude @enejb would love some feedback on the wording + design.

@claude
Copy link

claude bot commented Feb 3, 2026

Claude finished @lezama's task in 1m 3s —— View job


Reviewing wording and design for synced form status notices

  • Read implementation files
  • Analyze UI copy and wording
  • Review design and styling
  • Provide feedback

Wording Feedback

Critical Issues

  1. Inaccurate copy for private status (edit.tsx:918-921)

    The current message says:

    "This form is private and will not be displayed on the frontend until published."

    This is technically correct per the rendering logic in class-contact-form-block.php, which only renders forms with publish status. However, the phrase "until published" could be misleading since "private" is a valid post status in WordPress that serves a specific purpose (visible only to authenticated users with appropriate permissions).

    Suggested improvement:

    'This form is private and will not be displayed on the frontend. To make it visible, change its status to published.'
    

    This makes it clearer that private is intentional, not a temporary state.

  2. Pending review message clarity (edit.tsx:904-907)

    Current: "This form is pending review and will not be displayed on the frontend."

    This is clear, but consider adding context about the review workflow:

    'This form is pending review and will not be displayed on the frontend until approved and published.'
    
  3. Fallback message for unknown statuses (edit.tsx:936-941)

    The fallback uses sprintf with the status name, which is good. However, it says "until it is published" which implies the user should change the status, but doesn't guide them on how or why.

Minor Suggestions

  1. Scheduled forms (edit.tsx:910-914)

    Current: "This form is scheduled and will not be displayed until its publish date."

    This is clear and accurate. Consider adding the actual scheduled date if available:

    message: syncedForm?.date 
      ? sprintf(__('This form is scheduled for %s and will not be displayed until that date.', 'jetpack-forms'), formatDate(syncedForm.date))
      : __('This form is scheduled and will not be displayed until its publish date.', 'jetpack-forms')
  2. Draft message (edit.tsx:896-900)

    The draft message is clear and appropriate.

  3. Trash message (edit.tsx:889-893)

    Good use of "error" status for trashed forms. The message is clear that this is a serious state.


Design Feedback

Styling Issues

  1. RTL Language Support (editor.scss:1234)

    Problem: Uses physical direction property margin-left: 8px which won't flip in RTL layouts.

    Solution: Use logical property:

    .components-button {
        margin-inline-start: 8px;
    }
  2. Button visual hierarchy

    The "Publish now" link button might not be prominent enough for such an important action. Consider:

    • Using a primary button style for non-error statuses
    • Adding an icon (e.g., check mark or publish icon)
    • Ensuring sufficient color contrast
  3. Notice placement (edit.tsx:1167)

    The notice is rendered before the form content, which is good. The non-dismissible nature is appropriate since this is important status information.

  4. Responsive considerations

    The notice text might wrap awkwardly on mobile. Consider testing the layout at narrow widths, especially with the button inline.

UX Improvements

  1. Missing error handling (edit.tsx:374-386)

    The handlePublishForm doesn't handle errors. Users will see the spinner stop but won't know if publishing failed. Add error feedback:

    const { createErrorNotice, createSuccessNotice } = useDispatch( noticesStore );
    
    const handlePublishForm = useCallback( async () => {
        if ( ! ref ) return;
        setIsPublishingForm( true );
        try {
            await editEntityRecord( 'postType', FORM_POST_TYPE, ref, { status: 'publish' } );
            await saveEditedEntityRecord( 'postType', FORM_POST_TYPE, ref );
            createSuccessNotice( __( 'Form published successfully.', 'jetpack-forms' ), { type: 'snackbar' } );
        } catch ( error ) {
            createErrorNotice( 
                __( 'Failed to publish form. Please try again or check your permissions.', 'jetpack-forms' ),
                { type: 'snackbar' }
            );
        } finally {
            setIsPublishingForm( false );
        }
    }, [ ref, editEntityRecord, saveEditedEntityRecord, createErrorNotice, createSuccessNotice ] );
  2. Loading state affordance

    The isBusy prop on the button provides visual feedback, but consider adding aria-live announcements for screen reader users.

  3. Notice color/status mapping

    The severity levels are well chosen:

    • error for trash ✓
    • warning for draft/pending ✓
    • info for scheduled/private ✓

    However, consider whether private should be warning instead of info since it's actively blocking display (not just informational).


Summary

Strengths:

  • Clear, concise messages for most statuses
  • Appropriate use of notice severity levels
  • Non-dismissible notices ensure users see important status info
  • "Publish now" action provides quick resolution

Areas for improvement:

  • Add error handling for publish action
  • Fix RTL support with logical CSS properties
  • Clarify "private" status messaging
  • Consider enhanced button styling for primary actions
  • Test responsive layout at narrow widths

The copilot review also caught several of these issues. I'd prioritize:

  1. Error handling (critical for UX)
  2. RTL support (accessibility/i18n)
  3. Message clarity improvements (especially "private" status)

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

Comment on lines 917 to 921
status: 'info',
message: __(
'This form is private and will not be displayed on the frontend until published.',
'jetpack-forms'
),
Copy link

Copilot AI Feb 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The “private” status notice text is inaccurate. Synced forms are only rendered on the frontend when the referenced jetpack_form post status is publish (see projects/packages/forms/src/blocks/contact-form/class-contact-form-block.php where render_synced_form() returns empty for any non-publish status). The notice should not imply private forms are visible to administrators; it should instead state that private forms won’t be displayed on the frontend unless/until published (or otherwise match the actual rendering rules).

Copilot uses AI. Check for mistakes.
Comment on lines 375 to 386
const handlePublishForm = useCallback( async () => {
if ( ! ref ) {
return;
}
setIsPublishingForm( true );
try {
await editEntityRecord( 'postType', FORM_POST_TYPE, ref, { status: 'publish' } );
await saveEditedEntityRecord( 'postType', FORM_POST_TYPE, ref );
} finally {
setIsPublishingForm( false );
}
}, [ ref, editEntityRecord, saveEditedEntityRecord ] );
Copy link

Copilot AI Feb 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

handlePublishForm always clears the busy state in finally, but it swallows save/publish failures (no catch) so users get no feedback if the publish request is rejected (permissions, network, validation, etc.). Consider catching errors and surfacing them via the notices store (snackbar) and/or keeping the status notice visible until the save succeeds (matching the error-handling pattern used elsewhere, e.g. the convert toolbar).

Copilot uses AI. Check for mistakes.
Significance: patch
Type: added

Contact Form: Add status notice for non-published synced forms in block editor.
Copy link

Copilot AI Feb 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changelog entry text doesn’t follow the repo’s changelog style guidance: after the component prefix it should use imperative mood with a capitalized verb (e.g., “Contact Form: Add …” / “Contact Form: Show …”), rather than “Contact Form: add …”.

Suggested change
Contact Form: Add status notice for non-published synced forms in block editor.
Contact Form: Show status notice for non-published synced forms in the block editor.

Copilot uses AI. Check for mistakes.
enejb and others added 6 commits February 2, 2026 20:16
- Fix RTL support by using margin-inline-start instead of margin-left
- Update private status to warning (since it blocks display)
- Clarify private status message with actionable guidance
- Add context to pending review message about approval workflow
- Add error handling for publish action with snackbar notifications

Co-Authored-By: Claude Opus 4.5 <[email protected]>
} catch {
createErrorNotice(
__(
'Failed to publish form. Please try again or check your permissions.',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's clarify which permissions they can check to make this more actionable.

try {
await editEntityRecord( 'postType', FORM_POST_TYPE, ref, { status: 'publish' } );
await saveEditedEntityRecord( 'postType', FORM_POST_TYPE, ref );
createSuccessNotice( __( 'Form published successfully.', 'jetpack-forms' ), {
Copy link
Member

@simison simison Feb 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
createSuccessNotice( __( 'Form published successfully.', 'jetpack-forms' ), {
createSuccessNotice( __( 'Form published.', 'jetpack-forms' ), {

"Successfully" feels a bit formal but shorter feels blunt; I wonder if this would be a good place to spice up the copy a bit? "Great!" in the front for example. @ilonagl

It's a copy likely seen rarely and recovers from a kind of "alert/error" state, so little congrats seems in place. :-)

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't fully understand the full context of this state, but maybe something like "Your form is live and ready to collect responses." would be more helpful? Even "Congrats! Your form is live." could work.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both are great 👍

> = {
trash: {
status: 'error',
message: __( 'Trashed — not visible to visitors.', 'jetpack-forms' ),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wondering if there's a way to smooth these copies to more natural language without

? sprintf(
/* translators: %s: scheduled publish date */
__( 'Hidden until publication on %s.', 'jetpack-forms' ),
dateI18n( 'F j, Y g:i a', syncedForm.date )
Copy link
Member

@simison simison Feb 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To fully localize the datetime you can pull the setting like so — it differs between locales:

import { dateI18n, getSettings as getDateSettings } from '@wordpress/date';

const dateSettings = getDateSettings();

dateI18n( dateSettings.formats.datetime, syncedForm.date );

.jetpack-contact-form__status-notice {
margin-bottom: 16px;

.components-button {
Copy link
Member

@simison simison Feb 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's give the button a class and target that so that we avoid using internal classes, which aren't considered stable API and can change; imagine, e.g. swapping the button to @wordpress/ui without noticing this CSS, someone adding extra buttons to the notice, etc.

Although using the component API for actions is much better: https://github.com/Automattic/jetpack/pull/46914/changes#r2757755847

formStatus
) }
{ formStatus !== 'trash' && (
<Button
Copy link
Member

@simison simison Feb 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's pass actions to Notice instead. It'll style and place the CTA consistently and doesn't require extra CSS to make it look good.

https://wordpress.github.io/gutenberg/?path=/story/components-notice--with-actions

Image

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this the component we want to use instead of the ones in the PR screenshots?

Copy link
Member

@simison simison Feb 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're already using it in this PR but not sure why it looks different in the editor than Gutenberg storybook :-)

@ilonagl
Copy link

ilonagl commented Feb 3, 2026

Great work in showing these info notices! Here are the copy suggestions:

Draft

Current

This form is a draft and will not be displayed on the frontend until published.

Proposed

This form is a draft. It isn’t visible to visitors yet.

Primary action

  • Publish (instead of “Publish now”)

Why

  • Draft is a normal working state, so no urgency needed
  • “Visitors” is clearer and more human than “frontend”

Pending review

Current

This form is pending review and will not be displayed on the frontend.

Proposed

This form is under review. It will go live once the review is approved.

Primary action

  • View review status (if allowed) idk how can users approve it or see the status?

Why

  • Explains why publishing is blocked
  • Avoids the misleading “Publish now” CTA

Private

Current

This form is private and only visible to site administrators.

Proposed

This form is private. Only site admins can see and use it.

Primary action

  • Change visibility. Can we lead to this specific action?

Why

  • Frames this as an intentional setting, not a limitation
  • “Change visibility” is more accurate than “Publish”

Scheduled

Current

This form is scheduled and will not be displayed until its publish date.

Proposed

This form is scheduled. It will go live on [date].

Secondary actions

  • Change schedule and Publish now (only if we actually can do it)

Why

  • The publish date is important context
  • “Go live” is clearer and friendlier than “displayed”
  • Keeps user expectations aligned

Trashed

Current

This form has been trashed and will not be displayed on the frontend.

Proposed

This form is in the trash. It’s no longer available to visitors.

Primary actions

  • Restore or Delete permanently (if we can do any of them)

enejb and others added 10 commits February 3, 2026 05:18
Move the form status notice logic into a dedicated FormStatusNotice
component for better separation of concerns and reusability.

Co-Authored-By: Claude Opus 4.5 <[email protected]>
Refine the changelog wording to generalize the entry. Replaced 'Contact Form: Add status notice for non-published synced forms in block editor.' with 'Show status notice for non-published synced forms in block editor.' to clarify the scope and phrasing of the added notice.
Allow users to undo the publish action via a snackbar action button,
reverting the form to its previous status.

Co-Authored-By: Claude Opus 4.5 <[email protected]>
- Allow draft, pending, and scheduled forms to preview on frontend for editors
- Display status notice above form explaining visibility
- Trashed forms remain hidden for everyone
- Private forms visible only to editors with notice

Co-Authored-By: Claude Opus 4.5 <[email protected]>
Add an "Edit form" link to the frontend status notice that takes
editors directly to the form editor.

Co-Authored-By: Claude Opus 4.5 <[email protected]>
@CGastrell
Copy link
Contributor

CGastrell commented Feb 3, 2026

I can't speak from designs, but I love that we have this. Information to the user, specially on new things, is always a must.

In terms of code, it looks good to me. As always, Mikael has good points, specially with the locale trick.

The only thing I'd say, looking at @ilonagl careful review, is on the scheduled status.

This form is scheduled. It will go live on [date].

Since I read around "spice things up", could this also be "It will go live in [live countdown timer here]"?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

[Block] Contact Form Form block (also see Contact Form label) [Feature] Contact Form [Package] Forms [Status] Needs Review This PR is ready for review. [Type] Enhancement Changes to an existing feature — removing, adding, or changing parts of it

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants