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
Product Collection: Implement Preview Mode #46369
Product Collection: Implement Preview Mode #46369
Conversation
POC: Implement preview mode for Product Collection block in editor - Added extensive commentary to clarify the mechanism and usage of the `handlePreviewState` function - Implemented an internal state within `ProductCollectionContent` to manage preview status and messages, serving as a foundational example of how preview mode can enrich block functionality. - Showcased the application of `handlePreviewState` by incorporating it as a prop in `BlockEdit`, illustrating the potential for extending the block's capabilities for dynamic and interactive previews. This POC demonstrates a flexible approach to managing preview states within the editor, paving the way for further development and integration based on feedback and use-case analysis.
This commit introduces a centralized approach for registering product collection variations and managing their preview states. It abstracts the registration logic into a dedicated function and enhances the flexibility of preview state handling across different collection types.
I don't see any good use of it in handlePreviewState. Also, We will be going to call handlePreviewState only once therefore, it will always have the same value as the initial value of the previewState. If in future, we decide to run it multiple times then we can pass the previewState as an argument to handlePreviewState.
This commit introduces a refined approach for injecting the `handlePreviewState` function into product collection blocks, utilizing JavaScript closures to streamline the process. This method replaces the previous global registry mechanism, offering a more direct and efficient way to manage preview states. Advantages of This Approach: - Utilizing JavaScript closures for injecting `handlePreviewState` simplifies the overall architecture by directly modifying block edit components without relying on an external registry. This method enhances code clarity and reduces the cognitive load for developers. - The conditional application of `withHandlePreviewState` ensures that the preview state handling logic is only added to blocks that require it, optimizing performance and maintainability.
This commit enhances the organization and readability of the product collection content component by abstracting the preview state management into a custom hook named `usePreviewState`. This change streamlines the component's structure and aligns with React best practices for managing state and side effects. Key Changes: - Introduced `usePreviewState`, a custom hook responsible for initializing and managing the preview state (`isPreview` and `previewMessage`) of the product collection block. This hook encapsulates the state logic and its side effects, including the conditional invocation of `handlePreviewState`. - Modified `ProductCollectionContent` to utilize `usePreviewState` for handling its preview state. This adjustment makes the component cleaner and focuses it more on presentation and behavior rather than state management details.
Based on [this discussion](#45703 (comment)), I added a cleanup function support for handlePreviewState. `handlePreviewState` can return a function which will be called on cleanup in `useLayoutEffect` hook.
- Consolidated `handlePreviewState` and `initialPreviewState` into a single `preview` prop in `register-product-collection.tsx` and `product-collection-content.tsx` to streamline prop passing and improve the component interface. - Updated the `queryContextIncludes` in `constants.ts` to include 'previewState' - Enhanced the `ProductCollection` PHP class to handle preview-specific queries more effectively, introducing a new method `get_preview_query_args` that adjusts query parameters based on the collection being previewed, thereby improving the relevance and accuracy of products displayed in preview mode.
- Renamed `HandlePreviewStateArgs` to `SetPreviewStateArgs` in `featured.tsx` to better reflect its purpose, which is now more focused on setting rather than handling states. The implementation details within `featured.tsx` have also been refined to include async operations and cleanup functions, demonstrating a more sophisticated approach to managing state. Overall, these updates make the preview state logic more understandable and maintainable.
This commit addresses an issue in the product-collection-content.tsx where the newPreviewState was not properly merged into the existing previewState attribute. Previously, the spread operator was incorrectly applied, leading to potential loss of existing state attributes. By changing the order of operations and correctly spreading the existing attributes before merging the newPreviewState, we ensure that all state attributes are preserved and updated correctly.
…b.com/woocommerce/woocommerce into add/46368-product-collection-productionize-the-preview-mode-poc
…to add/46368-product-collection-productionize-the-preview-mode-poc
Implemented a new useLayoutEffect in `utils.tsx` to dynamically set a preview message in the editor for product collection blocks located in generic archive templates (like Products by Category, Products by Tag, or Products by Attribute).
1. **Template-Specific Tests:** Each template (tag, category, attribute) undergoes a test to ensure the preview button behaves as expected when replacing products with product collections in these contexts. 2. **Visibility Checks:** The tests verify that the preview button is visible when the block or its inner blocks are selected and hidden when the block is not selected. This helps confirm the correct implementation of the preview button visibility logic across different use cases. 3. **Interaction with Inner Blocks:** Additional checks are included to ensure the preview button's visibility toggles appropriately when interacting with inner blocks, reinforcing the dynamic nature of block selection and its effect on UI elements within the editor.
Hi @samueljseay @xristos3490 👋 I have made following requested changes:
PR is now ready for review again. Can you please review it again? Please let me know in case I missed something. Thank you for the helpful feedback so far 🙂 |
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 don't have much else to add, it's looking great. A few suggestions but they're mostly minor and won't block approval from me.
plugins/woocommerce-blocks/assets/js/blocks/product-collection/utils.tsx
Outdated
Show resolved
Hide resolved
...locks/tests/e2e/tests/product-collection/product-collection.block_theme.side_effects.spec.ts
Outdated
Show resolved
Hide resolved
*/ | ||
if ( setPreviewState || initialPreviewState ) { | ||
const withSetPreviewState = | ||
< T extends EditorBlock< T > >( BlockEdit: ElementType ) => |
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.
If it helps, I tried to use ComponentType from `'@wordpress/element' as we aren't supposed to import directly from "react", right?
as i mentioned in another comment, you absolutely can import types from react. types are erased at compilation. For some reason wp element is erasing the generics of the ComponentType so the fix here would indeed be to import from react (I tested and it works well).
Modifications: - Added `data-test-id="product-collection-preview-button"` to the Preview button in `product-collection-content.tsx`. - Updated the corresponding e2e test locator in `product-collection.block_theme.side_effects.spec.ts` to use the new `data-test-id` instead of the class name. By using `data-test-id`, we ensure that the e2e tests are not affected by changes in the styling or restructuring of the DOM that might alter CSS classes but do not affect functionality.
…to add/46368-product-collection-productionize-the-preview-mode-poc
Test using WordPress PlaygroundThe changes in this pull request can be previewed and tested using a WordPress Playground instance. Test this pull request with WordPress Playground. Note that this URL is valid for 30 days from when this comment was last updated. You can update it by closing/reopening the PR or pushing a new commit. |
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.
Overall looking good, @imanish003! I couldn't test this in a 3PD environment of course but it seems to be checking all the boxes! Fingers crossed, things should work as expected!
Left some comments before approving!
plugins/woocommerce-blocks/assets/js/blocks/product-collection/utils.tsx
Show resolved
Hide resolved
plugins/woocommerce-blocks/assets/js/blocks/product-collection/utils.tsx
Show resolved
Hide resolved
...merce-blocks/assets/js/blocks/product-collection/collections/register-product-collection.tsx
Show resolved
Hide resolved
...s/woocommerce-blocks/assets/js/blocks/product-collection/edit/product-collection-content.tsx
Show resolved
Hide resolved
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.
Left some comments before giving the final approval.
plugins/woocommerce-blocks/assets/js/blocks/product-collection/utils.tsx
Show resolved
Hide resolved
plugins/woocommerce-blocks/assets/js/blocks/product-collection/utils.tsx
Show resolved
Hide resolved
...s/woocommerce-blocks/assets/js/blocks/product-collection/edit/product-collection-content.tsx
Show resolved
Hide resolved
…to add/46368-product-collection-productionize-the-preview-mode-poc
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.
Works as expected! Nice work, @imanish003!
…to add/46368-product-collection-productionize-the-preview-mode-poc
Changes proposed in this Pull Request:
Introduction
We are working on Preview mode for Product Collection block. Here's the scoop: some collections might look a bit different in the Editor than they do on the Frontend. Take the Recently Viewed collection as an example; its appearance in the Editor might not exactly mirror its Frontend display. To bridge this gap, we're introducing a label, which you can peek at in the screenshot below.
Tooltip
A message will be shown when the merchant hovers over the "preview" label in Editor as shown in screenshot below:
What is implemented in this PR?
For all Product Collection blocks that inherit query from the template, we are showing a preview message in the editor if the block is in a generic archive template, i.e.
Here is what it should look like:
Technical details
I have abstracted logic to register a new collection into
registerProductCollection
. This function will allow us to register a new collection. For now, it's not public, but in follow-up PR, we plan to make it public (i.e., usable by 3PDs). For now, this function accepts all the arguments which are accepted by Block Variation. Also,registerProductCollection
accepts anpreview
argument. Here are some examples of howpreview
can be used:Example 1:
As you can see in the example below, you can pass
preview
object toregisterProductCollection
to set the initial state of the preview mode.isPreview
is a boolean that will determine if the collection is in preview mode.previewMessage
is a string that will be shown as a tooltip when the merchant hovers over the preview label in the Editor.Example 2:
In the example below, you can see how you can use
setPreviewState
to set the preview state. InsetPreviewState
, you can access attributes and location in the preview state, utilize async operations, and implement a cleanup function as a return value.When
setPreviewState
will be triggered?What isn't part of this PR?
Preview argument validation
In followup PR, we will add validation for preview argument passed in
registerProductCollection
function. For now, this is still a private API, but before making it public, we will need to add some validation, as incorrect data is possible.Required context
As mentioned by Karol in #45703 (review), collection should be able to specify
requiredContext
orrequiredLocation
. In case it's not satisfied we should not even callsetPreviewState
and set the preview ourselves.For now, there is no way for collection to specify require context but when it will be implemented, we will need to handle this case, i.e. we will need to show preview label when required context isn't satisfied.
Expose
registerProductCollection
for 3PDsThis will require a bit more discussion about what is the best way to expose it. Therefore, I will be implementing it in a follow-up PR.
Closes #46368
How to test the changes in this Pull Request:
Using the WooCommerce Testing Instructions Guide, include your detailed testing instructions:
Also, verify that hovering over "preview" label shows following tooltip: "Actual products will vary depending on the page being viewed."
Save and go to frontend. Verify that "preview" label isn't visible on frontend. It should be only visible on Editor side. Also, verify that everything is working as expected in Product Collection block and there are no errors.
Now, Toggle "Sync with current query" to off using inspector control. Verify that:
Changelog entry
Significance
Type
Message
Product Collection: Add preview mode on Editor side
Comment