Feat/performance recommended plugins - #4577
Conversation
There was a problem hiding this comment.
Pull request overview
Adds promoted performance-plugin recommendations to the Dashboard Settings Performance tab.
Changes:
- Adds Optimole and Super Page Cache cards with install/activation actions.
- Adds loading, success, error, and telemetry handling.
- Updates the settings layout to display recommendations below performance settings.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
assets/apps/dashboard/src/Components/Content/Settings/PerformancePlugins.js |
Implements promoted plugin cards and action states. |
assets/apps/dashboard/src/Components/Content/Settings.js |
Integrates the recommendations into the Performance tab. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| if (isPluginActive && !success) { | ||
| return null; | ||
| } |
Co-authored-by: harshitarora-in <56164789+harshitarora-in@users.noreply.github.com>
Move PerformancePlugins into PerformanceTabContent so it reuses the tab's existing conditional and TransitionWrapper, instead of duplicating both in Settings.js. Nested inside the settings card, the component's own Card rendered a white box inside a white box, so add a `flat` variant to Card that keeps the header but drops the box styling. It defaults to false, leaving the other 20 usages unchanged. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
| <div className="grow flex flex-col gap-6"> | ||
| <Card> | ||
| {tab === 'general' && ( | ||
| <TransitionWrapper> | ||
| <GeneralTabContent /> | ||
| </TransitionWrapper> | ||
| )} | ||
| {tab === 'performance' && ( | ||
| <TransitionWrapper> | ||
| <PerformanceTabContent /> | ||
| </TransitionWrapper> | ||
| )} | ||
| {tab === 'white-label' && ( | ||
| <TransitionWrapper> | ||
| <WhiteLabelTabContent /> | ||
| </TransitionWrapper> | ||
| )} | ||
| {tab === 'manage-modules' && ( | ||
| <TransitionWrapper> | ||
| <ManageModulesTabContent /> | ||
| </TransitionWrapper> | ||
| )} | ||
| </Card> | ||
| </div> |
There was a problem hiding this comment.
We're adding some classes here that would manage the layout inside the Performance tab content. If it's only related to that, the layout should live there. Otherwise it can have side-effects or impact on the other tabs content. We should wrap the Content inside the PerformanceTabContent component in a div or add the needed classes on its main wrapper. Otherwise I don't see why we can't simply add a mt-6 class on the PerformancePlugins component.
Later Edit: It looks like we already have a mt-6 class there, so why do we still need changes here?
Render the promoted plugins block with the existing ControlWrap section primitive instead of a nested Card. Settings.js and Layout/Card.js return to their original state; the section spacing and divider now come from the same rhythm the other settings sections use. PerformancePlugins owns the visible list and shrinks it when a card is dismissed, so the section unmounts once the last card is gone. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
| const [visibleSlugs, setVisibleSlugs] = useState(() => | ||
| PROMOTED_SLUGS.filter((slug) => { | ||
| // Super Page Cache is dropped server side when SPC Pro is | ||
| // installed, so a promoted slug can be missing entirely. | ||
| const plugin = neveDash.plugins[slug]; | ||
|
|
||
| return plugin && plugin.cta !== 'deactivate'; | ||
| }) | ||
| ); |
| {visibleSlugs.map((slug) => ( | ||
| <PluginCard | ||
| key={slug} | ||
| slug={slug} | ||
| data={neveDash.plugins[slug]} | ||
| onDismiss={handleDismiss} | ||
| /> | ||
| ))} |
| {!success && ( | ||
| <button | ||
| onClick={handleClick} | ||
| disabled={loading} | ||
| className={cn( | ||
| 'mt-3 self-start text-blue-600 hover:text-blue-700 text-sm font-medium flex items-center', | ||
| { 'opacity-75 cursor-not-allowed': loading } | ||
| )} | ||
| > |
| useEffect(() => { | ||
| if (!success) { | ||
| return; | ||
| } | ||
|
|
||
| // Only `success` belongs in the deps: onDismiss is recreated on every | ||
| // parent render and would restart a countdown already in progress. | ||
| const timeoutId = window.setTimeout(() => { | ||
| onDismiss(slug); | ||
| }, ACTIVE_PILL_TIMEOUT); | ||
|
|
||
| return () => window.clearTimeout(timeoutId); | ||
| }, [success]); |
| const handleClick = async () => { | ||
| setError(null); | ||
|
|
||
| window.tiTrk?.with('neve').set(slug, { |
Summary
This PR adds a new Recommended Plugins section in the Dashboard Settings Performance tab.
It introduces plugin cards for:
Behavior included:
Will affect visual aspect of the product
YES
Screenshots
Test instructions
Check before Pull Request is ready:
Closes https://github.com/Codeinwp/neve-pro-addon/issues/3027