Skip to content

UN-3308 [MISC] Add plugin-gated banner mount in PageLayout#2029

Open
athul-rs wants to merge 6 commits into
mainfrom
UN-3308-marketplace-banner-mount
Open

UN-3308 [MISC] Add plugin-gated banner mount in PageLayout#2029
athul-rs wants to merge 6 commits into
mainfrom
UN-3308-marketplace-banner-mount

Conversation

@athul-rs

@athul-rs athul-rs commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

What

  • Adds a plugin-gated mount point in PageLayout for an optional status banner contributed by the marketplace plugin, when present.
  • Extracts isModuleMissing into a zero-dependency helpers/pluginLoader.js (it previously lived in useMainAppRoutes.js, which would have created an import cycle with PageLayout); Router.jsx and useMainAppRoutes.js now import it from there.

Why

How

  • Same plugin-gated dynamic import used elsewhere (Router.jsx, TopNavBar): await import("../../plugins/marketplace") inside try/catch with isModuleMissing — missing plugin is the expected quiet case, any other failure is logged.
  • Rendered above <Outlet />; the component self-manages visibility and renders nothing when it has nothing to show.

Can this PR break any existing features? If yes, please list possible items. If no, please explain why. (PS: Admins do not merge the PR without this section filled)

  • No. In builds without the plugin the import fails, the binding stays undefined, and nothing renders — verified with vite build both without the plugin and with it present. The isModuleMissing move is a pure relocation (same implementation, all consumers updated).

Relevant Docs

  • N/A (follows the existing plugin-gating convention in Router.jsx)

Related Issues or PRs

Dependencies Versions / Env Variables

  • None

Notes on Testing

  • vite build green with and without the plugin directory present; biome clean.

Screenshots

  • N/A (no rendering change in OSS builds)

Checklist

I have read and understood the Contribution Guidelines.

🤖 Generated with Claude Code

The MarketplacePendingBanner component (cloud plugin, #1532 in
unstract-cloud) was exported but mounted nowhere, so the 'your
marketplace purchase is being confirmed' state never showed. Mount it
at the top of PageLayout using the established plugin-gated dynamic
import — OSS builds without the plugin leave it unmounted.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 4d4aa372-98ac-4516-86ad-8cde3d59a837

📥 Commits

Reviewing files that changed from the base of the PR and between 808b3e3 and 506acd3.

📒 Files selected for processing (1)
  • frontend/src/helpers/pluginLoader.js
🚧 Files skipped from review as they are similar to previous changes (1)
  • frontend/src/helpers/pluginLoader.js

Summary by CodeRabbit

  • New Features
    • Added a marketplace pending-purchase confirmation banner that shows when the marketplace integration is available, providing clear purchase-status feedback.
  • Bug Fixes
    • Improved resilience when the marketplace integration isn’t present, so page rendering continues without unexpected errors.
  • Chores
    • Centralized marketplace module-missing detection to keep route and plugin loading behavior consistent.

Walkthrough

Adds a shared isModuleMissing helper and uses a top-level dynamic import to optionally load the marketplace plugin; when available PageLayout renders MarketplacePendingBanner, and route modules import the shared helper instead of a local copy.

Changes

Marketplace Plugin Integration with Dynamic Import

Layer / File(s) Summary
Shared module-missing error classification helper
frontend/src/helpers/pluginLoader.js
Adds isModuleMissing(err) exported helper that classifies dynamic-import failures by err.code and message patterns.
PageLayout marketplace banner with dynamic import
frontend/src/layouts/page-layout/PageLayout.jsx
Module-level dynamic import of ../../plugins/marketplace using top-level await captures MarketplacePendingBanner when present; adds conditional render of <MarketplacePendingBanner /> inside inner Layout above the Outlet.
Route modules refactored to use shared helper
frontend/src/routes/Router.jsx, frontend/src/routes/useMainAppRoutes.js
Moves isModuleMissing import to ../helpers/pluginLoader.js and removes the file-local exported helper from useMainAppRoutes.js.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: adding a plugin-gated banner mount in PageLayout, which is the core feature of this PR.
Description check ✅ Passed The PR description is comprehensive and follows the template with all major sections filled: What, Why, How, breaking changes assessment, related issues, testing notes, and checklist completion.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch UN-3308-marketplace-banner-mount

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@greptile-apps

greptile-apps Bot commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds a plugin-gated banner slot in PageLayout for an optional MarketplacePendingBanner component and extracts isModuleMissing into a new zero-dependency helpers/pluginLoader.js to avoid an import cycle between PageLayout and useMainAppRoutes.

  • PageLayout.jsx gains a TLA await import(…) block that mirrors the pattern in Router.jsx — missing plugin stays quiet, genuine load failures are logged — and conditionally renders the banner above <Outlet />.
  • helpers/pluginLoader.js centralises isModuleMissing and quietly fixes a pre-existing gap: the old function in useMainAppRoutes.js did not match the \"Optional plugin not available\" error that Vite's optionalPluginImports stub actually throws in production, meaning OSS builds were logging spurious console errors for every optional plugin import. All callers silently benefit from the corrected function.

Confidence Score: 5/5

Safe to merge — the change is additive, OSS builds fall through the same silent path they did before, and the plugin-gating logic is consistent with the established pattern elsewhere in the codebase.

The logic is straightforward: a module-level TLA import that resolves to undefined on failure, guarded before render. The isModuleMissing extraction is clean and cycle-free. No existing behaviour is broken; the only functional delta is the corrected Vite-stub error match that suppresses previously spurious OSS console errors.

No files require special attention.

Important Files Changed

Filename Overview
frontend/src/helpers/pluginLoader.js New zero-dependency helper that centralises isModuleMissing; adds the 'Optional plugin not available' Vite stub match missing from the old useMainAppRoutes.js version, fixing spurious console errors in OSS production builds.
frontend/src/layouts/page-layout/PageLayout.jsx Adds a TLA-gated marketplace banner slot above Outlet; follows the established plugin-gating pattern with correct isModuleMissing error classification and a safe undefined-guard before rendering.
frontend/src/routes/Router.jsx Swaps the isModuleMissing import from useMainAppRoutes.js to the new helpers/pluginLoader.js; no logic changes.
frontend/src/routes/useMainAppRoutes.js Removes the local isModuleMissing definition and imports it from helpers/pluginLoader.js; all catch blocks now also benefit from the added 'Optional plugin not available' match.

Sequence Diagram

sequenceDiagram
    participant Vite as Vite bundler
    participant PL as PageLayout.jsx (TLA)
    participant PLdr as helpers/pluginLoader.js
    participant Mkt as plugins/marketplace (or stub)

    Vite->>PL: initialise module (TLA)
    PL->>PLdr: "import { isModuleMissing }"
    PLdr-->>PL: function returned
    PL->>Mkt: await import()
    alt Plugin present
        Mkt-->>PL: MarketplacePendingBanner exported
        PL->>PL: MarketplacePendingBanner assigned
    else Plugin absent
        Mkt-->>PL: throws Error optional plugin not available
        PL->>PLdr: isModuleMissing(err) true
        PL->>PL: MarketplacePendingBanner stays undefined
    else Plugin broken
        Mkt-->>PL: throws unexpected error
        PL->>PLdr: isModuleMissing(err) false
        PL->>PL: console.error import failed
    end
    PL-->>Vite: module ready
Loading

Reviews (6): Last reviewed commit: "UN-3308 Recognize Vite optional-plugin s..." | Re-trigger Greptile

Comment thread frontend/src/layouts/page-layout/PageLayout.jsx

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@frontend/src/layouts/page-layout/PageLayout.jsx`:
- Around line 21-25: The current empty catch in PageLayout.jsx swallows all
import errors for the marketplace plugin; change it to catch the error (e.g.,
catch (err)) and only suppress it when the error indicates the module is missing
(same contract used in Router.jsx and useMainAppRoutes.js — check err.code ===
'MODULE_NOT_FOUND' or err.message for "Cannot find module"); for any other error
log the full error (or rethrow) so runtime/syntax failures in the plugin aren’t
silently ignored, and only set MarketplacePendingBanner when the import
succeeds.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 533c278f-52bf-4a0e-a39a-839a8142acca

📥 Commits

Reviewing files that changed from the base of the PR and between c14a3b3 and e0223a3.

📒 Files selected for processing (1)
  • frontend/src/layouts/page-layout/PageLayout.jsx

Comment thread frontend/src/layouts/page-layout/PageLayout.jsx Outdated
Mirror Router.jsx: stay quiet for the expected plugin-absent OSS case,
log unexpected plugin failures so a broken plugin can't silently remove
the pending-purchase UX in cloud builds.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Comment thread frontend/src/layouts/page-layout/PageLayout.jsx Outdated
athul-rs and others added 2 commits June 11, 2026 12:55
PageLayout importing it from useMainAppRoutes created an import cycle
(useMainAppRoutes -> PageLayout -> useMainAppRoutes). Move the helper to
helpers/pluginLoader.js so Router, useMainAppRoutes, and PageLayout all
import it cycle-free.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The layout-side change is a generic plugin-gated mount slot; keep the
cloud feature's product narrative out of the OSS code comments.
@athul-rs athul-rs changed the title UN-3308 [FEAT] Show marketplace purchase-pending banner while provisioning completes UN-3308 [MISC] Add plugin-gated banner mount in PageLayout Jun 11, 2026
@athul-rs athul-rs requested a review from jaseemjaskp June 11, 2026 10:39

@jaseemjaskp jaseemjaskp left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Automated PR Review Toolkit pass (code-review / silent-failure / type-design / test-coverage / comment / simplify), scoped to the 4 changed files. The extraction is clean and consistent with the existing top-level-await import plugin pattern, and the previously-raised "catch swallows unexpected failures" concern is resolved. Two new, higher-value findings are posted inline on pluginLoader.js; lower-priority/design notes are summarized in the PR thread rather than posted inline to avoid clutter.

Comment thread frontend/src/helpers/pluginLoader.js
Comment thread frontend/src/helpers/pluginLoader.js Outdated
The shipped bundle resolves an absent optional plugin to a stub that
throws 'Optional plugin not available' (vite.config.js optionalPluginImports),
not a fetch/MODULE_NOT_FOUND error — so the OSS 'missing plugin' case was
misclassified and every OSS load logged the console.error the helper was
meant to suppress. Match that message; also generalize the stale
de-register-the-route comment to cover the PageLayout banner mount.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

Frontend Lint Report (Biome)

All checks passed! No linting or formatting issues found.

@sonarqubecloud

Copy link
Copy Markdown

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants