wp-parsely icon indicating copy to clipboard operation
wp-parsely copied to clipboard

Fix "Related Posts" persistence when sidebar is closed

Open alecgeatches opened this issue 9 months ago • 2 comments

Description

In develop, when the "Related Posts" sidebar tab is closed and re-opened, the set of related posts reloads each time. Additionally, some of the fields (section, tags) are not persisted between reopens:

https://github.com/user-attachments/assets/924f74a2-b1dc-412f-a3ca-415a2cdf8a13

This component has been modified to use a store for persistence:

https://github.com/user-attachments/assets/068169cd-7c06-4455-835c-64a00b111635

How has this been tested?

This has been tested manually in the editor. To test:

  1. Log into a site with the wp-parsely plugin activated and connected to Parse.ly credentials.
  2. Open a post with content.
  3. Click the upper-right hand Parse.ly logo, and unfurl the "Related Posts" section.
  4. Select values for the metric, period, section, and tags options if desired.
  5. Close the pane by clicking the Parse.ly logo and reopen it.
  6. Verify that the posts are not reloaded, and settings remain the same.

Summary by CodeRabbit

  • New Features

    • Introduced centralized state management for related posts, ensuring posts load efficiently with enhanced filter and time period options.
    • Improved error handling during content fetching to update the display accurately when no posts are available.
  • Refactor

    • Updated the component to use store-driven state management instead of local state, streamlining post updates and initial content loading.
    • Added a new Redux store to manage related posts state, including actions and selectors for better state handling.

alecgeatches avatar Apr 10 '25 18:04 alecgeatches

📝 Walkthrough

Walkthrough

The changes modify the related posts component by shifting from local state management to using the WordPress data hooks useSelect and useDispatch with the new RelatedPostsStore. The fetchPosts function now accepts additional parameters and executes conditionally on the firstRun flag during component initialization. Additionally, error handling is updated to clear posts on failure. A new Redux store is introduced to manage the related posts state, complete with actions, reducers, and selectors, and it is registered with the WordPress data system. The test suite is updated to reset the store state before each test.

Changes

File(s) Change Summary
src/content-helper/editor-sidebar/related-posts/component.tsx Updated the component to use useSelect and useDispatch for state management; refactored fetchPosts to accept parameters for period, metric, filters, and retries; implemented retry logic and error handling; added firstRun flag to control initial fetch and conditional rendering; updated event handlers to dispatch actions and trigger fetches accordingly.
src/content-helper/editor-sidebar/related-posts/store.ts Introduced a new Redux store (RelatedPostsStore) with state interface, actions, reducers, selectors, and action creators; manages first run status, loading state, filters, and posts; registered the store with the WordPress data system.
tests/js/content-helper/structure.test.tsx Added imports for dispatch and RelatedPostsStore; introduced a beforeEach hook to reset the related posts store state before each test to ensure test isolation.

Suggested labels

Changelog: Changed

Suggested reviewers

  • acicovic

Possibly related PRs

  • Parsely/wp-parsely#3117: Refactors the Related Posts component and store to manage multiple filters (author, section, tags) via a Redux store and updates fetching logic accordingly, closely related to this PR's changes in filter management and store usage.

[!TIP]

⚡💬 Agentic Chat (Pro Plan, General Availability)
  • We're introducing multi-step agentic chat in review comments and issue comments, within and outside of PR's. This feature enhances review and issue discussions with the CodeRabbit agentic chat by enabling advanced interactions, including the ability to create pull requests directly from comments and add commits to existing pull requests.

📜 Recent review details

Configuration used: .coderabbit.yaml Review profile: CHILL Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 913965ab1efadebf1f7a1c1b424a145194d78fa9 and cee02eb30fb757eb8ca3929e7353fb549cac8f99.

⛔ Files ignored due to path filters (2)
  • build/content-helper/editor-sidebar.asset.php is excluded by !build/**
  • build/content-helper/editor-sidebar.js is excluded by !build/**
📒 Files selected for processing (3)
  • src/content-helper/editor-sidebar/related-posts/component.tsx (7 hunks)
  • src/content-helper/editor-sidebar/related-posts/store.ts (1 hunks)
  • tests/js/content-helper/structure.test.tsx (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • tests/js/content-helper/structure.test.tsx
  • src/content-helper/editor-sidebar/related-posts/store.ts
🧰 Additional context used
📓 Path-based instructions (1)
`**/*.{js,ts,tsx,jsx}`: "Perform a detailed review of the provided code with following key aspects in mind: - Review the code to ensure it is well-structured and adheres to best ...

**/*.{js,ts,tsx,jsx}: "Perform a detailed review of the provided code with following key aspects in mind:

  • Review the code to ensure it is well-structured and adheres to best practices.
  • Verify compliance with WordPress coding standards.
  • Ensure the code is well-documented.
  • Check for security vulnerabilities and confirm the code is secure.
  • Optimize the code for performance, removing any unnecessary elements.
  • Validate JSDoc comments for accuracy, currency, and adherence to WordPress coding standards.
  • Ensure each line comment concludes with a period.
  • Confirm every JSDoc comment includes a @since tag indicating the next version of the plugin to include the code.
  • Guarantee compatibility with the latest version of WordPress, avoiding deprecated functions or features."
  • src/content-helper/editor-sidebar/related-posts/component.tsx
🔇 Additional comments (9)
src/content-helper/editor-sidebar/related-posts/component.tsx (9)

9-9: Import updated to support the store-based approach.

The addition of useDispatch alongside useSelect enables the component to both retrieve and update state from a central store, essential for the persistence functionality required by this PR.


36-36: Importing the newly created Redux store for related posts.

This import connects the component to the centralized state store, enabling state persistence when the sidebar is closed and reopened.


143-156: Well-implemented store selectors replacing local state.

The component now uses WordPress data architecture to maintain state across component lifecycles. This is the key improvement that enables persistence when the sidebar is closed and reopened.


158-163: Action dispatchers properly set up for state management.

Good implementation of the WordPress data pattern for dispatching actions to update store state.


189-199: Metric change handler updated to work with store-based approach.

The handler now correctly:

  1. Updates settings
  2. Tracks telemetry
  3. Fetches posts with the new parameters

This implementation maintains the same functionality while integrating with the store-based state management.


212-222: Period change handler updated to work with store-based approach.

The implementation follows the same pattern as the metric change handler, maintaining consistency across the codebase.


226-257: Improved post fetching with explicit parameters and error handling.

The fetchPosts function has been significantly improved:

  1. It now accepts explicit parameters for better function signature clarity
  2. Properly updates store state through action dispatchers
  3. Includes retry logic with timeout
  4. Clears posts on failure for proper UI feedback

The JSDoc comment is well-updated with the new parameters and versioning information.


281-296: Filter handling updated to work with store-based approach.

The implementation now correctly:

  1. Creates a local variable to prepare the updated filters
  2. Updates the store state through the setFilters action
  3. Fetches posts with the current parameters and updated filters

The approach is consistent with other handlers in the component.


372-372: Improved empty state UX by considering first run status.

The addition of the ! firstRun condition prevents showing the "No related posts found" message during initial loading, which provides a better user experience.

✨ Finishing Touches
  • [ ] 📝 Generate Docstrings

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

coderabbitai[bot] avatar Apr 10 '25 18:04 coderabbitai[bot]

@acicovic This is ready for review! Note that I ran into some test failures after implementing the store:

 FAIL tests/js/content-helper/structure.test.tsx (6.282 s)
  PCH Editor Sidebar Related Post panel
    ✓ should display spinner when starting (140 ms)
    ✕ should show contact us message when Parse.ly Site ID is not set (29 ms)
    ✕ should show contact us message when Parse.ly API Secret is not set (26 ms)
    ✕ should show error message when API returns the error (27 ms)
    ✕ should show error message and hint when API fetch is failed (25 ms)
    ✕ should show a single post with description and proper attributes (1085 ms)
    ✕ should show 5 posts by default (1066 ms)

These have been addressed, but essentially every test was waiting for the "Loading..." message to appear, but with the store in place this only happens on the first render. There were some other inconsistencies that relied on the previous non-stateful behavior. I tried a few different approaches but what ended up working was adding a reset() action into the store and calling it directly in https://github.com/Parsely/wp-parsely/pull/3249/commits/913965ab1efadebf1f7a1c1b424a145194d78fa9.

Let me know if you have any questions or thoughts!

alecgeatches avatar Apr 10 '25 21:04 alecgeatches

Noting that I've pushed https://github.com/Parsely/wp-parsely/commit/6cc87b30b90f15d78c88d73b001b228dc85dd884, a nitpick commit which doesn't change any functionality.

Thank you @acicovic! I've noted those changes.

alecgeatches avatar Apr 15 '25 16:04 alecgeatches