Skip to content
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

Extract @wordpress/reusable-blocks from @wordpress/editor #25859

Merged
merged 44 commits into from
Oct 14, 2020

Conversation

adamziel
Copy link
Contributor

@adamziel adamziel commented Oct 6, 2020

Description

This PR extracts the store part of reusable blocks logic from the editor package to a new, dedicated @wordpress/reusable-blocks package, and refactors it to use data layer instead of custom logic (props to @noisysocks).

The rationale is that the widgets editor would benefit from supporting reusable blocks as seen in #22875. Unfortunately, a large chunk of reusable blocks logic lives in the @wordpress/editor package which was designed to support editing posts and would not make a good dependency for @wordpress/edit-widgets (and wouldn't even work).

Solves #25853

How has this been tested?

Go to posts editor, and interact with reusable blocks in the following ways:

  • Create a new reusable block, confirm it's visible in the inserter
  • Split existing reusable block back into regular blocks
  • Try "Delete from reusable blocks" toolbar menu item
  • Insert reusable blocks using the inserter
  • Copy/paste reusable blocks
  • Undo/redo
  • Anything else you can think of

When you're done, save the page and refresh the editor. Confirm all the changes were stored correctly and that your new reusable blocks are visible in the inserter.

Types of changes

Breaking change, but only if messing with experimental features could be considered breaking.

Checklist:

  • My code is tested.
  • My code follows the WordPress code style.
  • My code follows the accessibility standards.
  • My code has proper inline documentation.
  • I've included developer documentation if appropriate.
  • I've updated all React Native files affected by any refactorings/renamings in this PR.

@adamziel adamziel added [Feature] Synced Patterns Related to synced patterns (formerly reusable blocks) [Package] Editor /packages/editor [Block] Block The "Reusable Block" Block labels Oct 6, 2020
@adamziel adamziel self-assigned this Oct 6, 2020
@github-actions
Copy link

github-actions bot commented Oct 6, 2020

Size Change: -2.75 kB (0%)

Total Size: 1.19 MB

Filename Size Change
build/a11y/index.js 1.14 kB +1 B
build/annotations/index.js 3.54 kB +23 B (0%)
build/autop/index.js 2.72 kB -1 B
build/blob/index.js 668 B +1 B
build/block-directory/index.js 8.6 kB +39 B (0%)
build/block-editor/index.js 130 kB -34 B (0%)
build/block-library/index.js 144 kB +148 B (0%)
build/blocks/index.js 47.6 kB -5 B (0%)
build/components/index.js 169 kB -4 B (0%)
build/compose/index.js 9.63 kB -6 B (0%)
build/core-data/index.js 12.1 kB +13 B (0%)
build/data-controls/index.js 684 B -1 B
build/data/index.js 8.63 kB -5 B (0%)
build/date/index.js 31.9 kB -3 B (0%)
build/dom-ready/index.js 569 B +1 B
build/dom/index.js 4.43 kB +2 B (0%)
build/edit-navigation/index.js 10.6 kB +1 B
build/edit-post/index.js 306 kB +15 B (0%)
build/edit-site/index.js 21.3 kB -1 B
build/edit-widgets/index.js 21.3 kB -3 B (0%)
build/editor/index.js 42.5 kB -2.95 kB (6%)
build/element/index.js 4.45 kB +1 B
build/escape-html/index.js 733 B -1 B
build/format-library/index.js 7.49 kB -1 B
build/i18n/index.js 3.54 kB +1 B
build/is-shallow-equal/index.js 709 B -1 B
build/keyboard-shortcuts/index.js 2.39 kB -1 B
build/list-reusable-blocks/index.js 3.02 kB +2 B (0%)
build/media-utils/index.js 5.12 kB -1 B
build/notices/index.js 1.69 kB +2 B (0%)
build/nux/index.js 3.27 kB +7 B (0%)
build/plugins/index.js 2.44 kB +1 B
build/primitives/index.js 1.34 kB +1 B
build/priority-queue/index.js 789 B -1 B
build/redux-routine/index.js 2.85 kB +2 B (0%)
build/rich-text/index.js 13 kB +6 B (0%)
build/shortcode/index.js 1.7 kB +1 B
build/url/index.js 4.07 kB +3 B (0%)
build/viewport/index.js 1.75 kB -1 B
ℹ️ View Unchanged
Filename Size Change
build/api-fetch/index.js 3.35 kB 0 B
build/block-directory/style-rtl.css 943 B 0 B
build/block-directory/style.css 942 B 0 B
build/block-editor/style-rtl.css 10.9 kB 0 B
build/block-editor/style.css 10.9 kB 0 B
build/block-library/editor-rtl.css 8.65 kB 0 B
build/block-library/editor.css 8.65 kB 0 B
build/block-library/style-rtl.css 7.71 kB 0 B
build/block-library/style.css 7.71 kB 0 B
build/block-library/theme-rtl.css 741 B 0 B
build/block-library/theme.css 741 B 0 B
build/block-serialization-default-parser/index.js 1.78 kB 0 B
build/block-serialization-spec-parser/index.js 3.1 kB 0 B
build/components/style-rtl.css 15.5 kB 0 B
build/components/style.css 15.5 kB 0 B
build/deprecated/index.js 772 B 0 B
build/edit-navigation/style-rtl.css 868 B 0 B
build/edit-navigation/style.css 871 B 0 B
build/edit-post/style-rtl.css 6.3 kB 0 B
build/edit-post/style.css 6.29 kB 0 B
build/edit-site/style-rtl.css 3.86 kB 0 B
build/edit-site/style.css 3.86 kB 0 B
build/edit-widgets/style-rtl.css 2.97 kB 0 B
build/edit-widgets/style.css 2.97 kB 0 B
build/editor/editor-styles-rtl.css 480 B 0 B
build/editor/editor-styles.css 482 B 0 B
build/editor/style-rtl.css 3.85 kB 0 B
build/editor/style.css 3.84 kB 0 B
build/format-library/style-rtl.css 547 B 0 B
build/format-library/style.css 548 B 0 B
build/hooks/index.js 1.74 kB 0 B
build/html-entities/index.js 622 B 0 B
build/keycodes/index.js 1.85 kB 0 B
build/list-reusable-blocks/style-rtl.css 476 B 0 B
build/list-reusable-blocks/style.css 476 B 0 B
build/nux/style-rtl.css 671 B 0 B
build/nux/style.css 668 B 0 B
build/reusable-blocks/index.js 3.04 kB 0 B
build/server-side-render/index.js 2.6 kB 0 B
build/token-list/index.js 1.24 kB 0 B
build/warning/index.js 1.13 kB 0 B
build/wordcount/index.js 1.17 kB 0 B

compressed-size-action

@adamziel
Copy link
Contributor Author

adamziel commented Oct 6, 2020

Any ideas how to address the linter warnings? It seems like all the problems stem from files untouched by this PR.

@noisysocks
Copy link
Member

If we refactor core/block to use getEntityRecord( 'wp_block' ), saveEntityRecord( 'wp_block' ), etc. then I think we wouldn't need any of this code.

@noisysocks
Copy link
Member

Here's half of what I mean: #25888

The trickier parts, which I haven't implemented, is making the Add to Reusable blocks button and inserter use @wordpress/core-data and not the custom selectors in @wordpress/editor. I think it should be possible though.

I suppose that still leaves a little bit of code related to reusable blocks in @wordpress/editor, though, so perhaps a new @wordpress/reusable-blocks package is needed regardless 🙂

@adamziel
Copy link
Contributor Author

adamziel commented Oct 8, 2020

Good idea @noisysocks ! I merged your proof of concept to this PR and moved these buttons to reusable-blocks package. From here it's just elbow grease and removing parts of the store bit by bit :-)

@adamziel
Copy link
Contributor Author

adamziel commented Oct 8, 2020

@noisysocks I think it works! Would you please give it a spin?

Also, I gave some thought to convertBlockToStatic and convertBlockToReusable actions. These could be just react hooks based on useSelect and useDispatch but that would limit their use to react components. I went for controls-based actions instead to enable more flexibility - now they can be used from components, actions, other controls etc. A side effect is that the only reducer in the store is empty - this feels wrong, but I can live with that feeling as long as it provides value.

@adamziel adamziel force-pushed the update/reusable-blocks-package branch from 647650b to 006c64c Compare October 8, 2020 17:42
@adamziel adamziel changed the title Create @wordpress/reusable-blocks package Extract @wordpress/reusable-blocks from @wordpress/editor Oct 8, 2020
@adamziel
Copy link
Contributor Author

adamziel commented Oct 8, 2020

This needs a bit more attention to fix the mobile tests.

Copy link
Member

@noisysocks noisysocks left a comment

Choose a reason for hiding this comment

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

OMG @adamziel! You did it! You legend! 😍

This looks amazing. I love all of the red. It's been a long time coming. I left a few notes.

packages/reusable-blocks/src/store/actions.js Outdated Show resolved Hide resolved
packages/reusable-blocks/src/store/index.js Outdated Show resolved Hide resolved
packages/block-library/src/block/edit.js Outdated Show resolved Hide resolved
packages/reusable-blocks/package.json Outdated Show resolved Hide resolved
packages/reusable-blocks/package.json Outdated Show resolved Hide resolved
packages/reusable-blocks/README.md Outdated Show resolved Hide resolved
packages/reusable-blocks/README.md Outdated Show resolved Hide resolved
packages/editor/src/components/provider/index.js Outdated Show resolved Hide resolved
@adamziel
Copy link
Contributor Author

adamziel commented Oct 9, 2020

@noisysocks A few considerations that are definitely out of scope for this PR:

  • Now that we have a reusable-blocks package, would it make sense to move even more parts there? As in the core/block Block for example?
  • Replacing __experimentalReusableBlocks prop with __experimentalUseReusableBlocks: true in BlockEditorProvider is worth discussing. It would require explicitly using core entities in the block-editor thus making it a little bit more WordPress-specific, but it wouldn't require any additional package dependencies and using non-WP-specific entities would not require much more effort than just passing the __experimentalReusableBlocks prop.

@adamziel
Copy link
Contributor Author

adamziel commented Oct 12, 2020

Some of the tests here are quite flaky. This one fails every time on CI:

Reusable blocks › can be inserted after refresh

And the other ones are inconsistent, one run they're all green, another run a few are red. The funny thing is that in my local dev env all the tests pass consistently. It seems like this PR requires some more polishing.

@adamziel
Copy link
Contributor Author

adamziel commented Oct 12, 2020

I think I figured this out. Now that we use core/data to manage reusable blocks, there is an additional loading indicator involved as creating a new reusable blocks invalidates the caches. It's rarely a problem in my local dev env because there is virtually no delay when requesting the API. While the ideal solution would be to prevent invalidation or do it in the background so that it's not detectable, that's outside of scope of this PR. I adjusted the e2e tests to wait until the form is ready and hopefully all the tests will pass now. 🤞

@noisysocks
Copy link
Member

  • Now that we have a reusable-blocks package, would it make sense to move even more parts there? As in the core/block Block for example?

It's an interesting thought. I guess "yes", because it makes the packages more "mix and match". That is, if you don't want reusable blocks in your @wordpress/editor, you don't import it.

But then taking this thought to its logical conclusion would mean we ought to move all blocks out into @wordpress/block-editor, @wordpress/editor, @wordpress/edit-post, etc. 😅

  • Replacing __experimentalReusableBlocks prop with __experimentalUseReusableBlocks: true in BlockEditorProvider is worth discussing. It would require explicitly using core entities in the block-editor thus making it a little bit more WordPress-specific, but it wouldn't require any additional package dependencies and using non-WP-specific entities would not require much more effort than just passing the __experimentalReusableBlocks prop.

It's odd that @wordpress/block-editor depends on @wordpress/data. I suspect it's only so that we can use select( 'core/block-editor' ) and that we, as an unwritten rule, don't select from any other stores?

Will need to think more on this. I don't hate that we pass reusableBlocks to @wordpress/block-editor. Better that it's an explicit dependency than an implicit one which is what selecting from @wordpress/data would be.

@noisysocks
Copy link
Member

While the ideal solution would be to prevent invalidation or do it in the background so that it's not detectable, that's outside of scope of this PR.

Could you please create an issue to track this?

Copy link
Member

@noisysocks noisysocks left a comment

Choose a reason for hiding this comment

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

This is looking great.

Just a few small notes, plus I'm noticing that when I update an existing reusable block and click Save, the block encounters an error.

);
const setIsEditing = useCallback(
( value ) => {
__experimentalSetEditingReusableBlock( clientId, value );
Copy link
Member

Choose a reason for hiding this comment

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

Can we not use useState()? An action/selector/reducer for this feels very heavy.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It does feel heavy! I went for this approach so that the createReusableBlock action could switch a newly created reusable block into an edit mode - we don't want that to happen automatically in any other case. I'm all ears for other ideas, but either way I don't think it should block this PR.

@@ -0,0 +1 @@
export { default as ReusableBlocksButtons } from './reusable-blocks-buttons';
Copy link
Member

Choose a reason for hiding this comment

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

Thinking the name of this component should reflect that they're menu items that belong in a block menu. ReusableBlockMenuItems is clear enough imo.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I agree! I'm hesitant of adding this change to this PR, it's already hard to reason about it as it is. Let's address it in a follow-up one.

packages/reusable-blocks/src/store/controls.js Outdated Show resolved Hide resolved
@adamziel
Copy link
Contributor Author

adamziel commented Oct 13, 2020

Just a few small notes, plus I'm noticing that when I update an existing reusable block and click Save, the block encounters an error.

I added a bandaid for now, the key to fixing it properly lies in #22127

@adamziel
Copy link
Contributor Author

adamziel commented Oct 13, 2020

But then taking this thought to its logical conclusion would mean we ought to move all blocks out into @wordpress/block-editor, @wordpress/editor, @wordpress/edit-post, etc. 😅

Not necessarily. You can't use reusable blocks without reusable-block package. I think you can use pretty much all other blocks without editor or post-editor so it makes sense to keep them in block-library.

@adamziel
Copy link
Contributor Author

adamziel commented Oct 14, 2020

I will follow up with PRs to address Rob's comments as soon as possible. Also this PR conflicted with 2293e34 to which I applied "accept mine" conflict resolution strategy as these are mostly the same changes. I will follow up with a PR to address the delta (local title state).

@draganescu draganescu dismissed noisysocks’s stale review October 14, 2020 09:37

This PR is getting very large and we can accomodate tweaks in smaller future PRs. I also believe @adamziel covered all your feedback @noisysocks (with one exception)

Copy link
Contributor

@draganescu draganescu left a comment

Choose a reason for hiding this comment

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

I am approving this based on @noisysocks 's review and @adamziel 's covering of that, and also because the size of the change set is prone to hard to solve conflicts.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Block] Block The "Reusable Block" Block [Feature] Synced Patterns Related to synced patterns (formerly reusable blocks) [Package] Editor /packages/editor
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants