Skip to content

Conversation

dlhck
Copy link
Collaborator

@dlhck dlhck commented Jul 31, 2025

Description

This PR introduces a new extension API for customizing the Vendure dashboard login page. It allows developers to extend and customize various parts of the login interface through a declarative API.

The new API provides extension points for:

  • Custom logo component to replace the default Vendure logo
  • Content injection before the login form
  • Content injection after the login form
  • Custom login image panel to replace the default image

This feature enables better branding and customization options for Vendure implementations that need to tailor the admin UI to their specific needs.

Breaking changes

No breaking changes. This is a new feature that maintains backward compatibility.

Screenshots

The test plugin demonstrates the new extension points in action, showing custom logo, after-form content, and a custom login image panel.

image

Checklist

📌 Always:

  • I have set a clear title
  • My PR is small and contains a single feature
  • I have checked my own PR

👍 Most of the time:

  • I have added or updated test cases
  • I have updated the README if needed

Implementation Details

  • Added new login extension types in packages/dashboard/src/lib/framework/extension-api/types/login.ts
  • Implemented useLoginExtensions hook for consuming login extensions
  • Updated the login form component to support the new extension points
  • Added login extension support to the dashboard extension API
  • Included example usage in the reviews test plugin

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added support for customizing the login page with extension points for logo, content before/after the form, and the login image panel.
    • Introduced a new hook to enable dynamic rendering of custom login components.
    • Example extensions demonstrate custom branding and additional login options.
  • Documentation

    • Added developer-preview documentation for new login extension interfaces.
  • Refactor

    • Refactored login form rendering to support conditional extension components while preserving existing UI as fallback.
  • Chores

    • Updated internal registries and APIs to support and expose login extension functionality.

Copy link

vercel bot commented Jul 31, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Updated (UTC)
docs ✅ Ready (Inspect) Visit Preview Jul 31, 2025 7:27am

Copy link
Contributor

coderabbitai bot commented Jul 31, 2025

Walkthrough

This change introduces a new extensibility mechanism for customizing the login page in the dashboard. It adds extension points for the logo, content before and after the login form, and the login image. Supporting types, hooks, and registration logic are implemented, and the global registry is updated to manage these extensions. Example usage is added in a test plugin.

Changes

Cohort / File(s) Change Summary
Login Form Extensibility & UI
packages/dashboard/src/lib/components/login/login-form.tsx
Refactored LoginForm to support extensibility via a new useLoginExtensions hook. Added conditional rendering for custom logo, beforeForm, afterForm, and loginImage components. Exported RemoteLoginImage type. Minor formatting cleanup.
Extension Registration Logic
packages/dashboard/src/lib/framework/extension-api/define-dashboard-extension.ts, packages/dashboard/src/lib/framework/extension-api/logic/login.ts
Added support for registering login extensions in defineDashboardExtension. Introduced registerLoginExtensions function to handle merging and storing login extensions in the global registry.
Extension API Types
packages/dashboard/src/lib/framework/extension-api/types/login.ts, packages/dashboard/src/lib/framework/extension-api/types/index.ts, packages/dashboard/src/lib/framework/extension-api/extension-api-types.ts
Added new interfaces for login page extension points and aggregated type. Updated DashboardExtension interface to include optional login property. Re-exported login types.
Login Extension Hook
packages/dashboard/src/lib/framework/extension-api/use-login-extensions.ts
Added useLoginExtensions React hook to provide reactive access to login extensions from the registry.
Global Registry Enhancements
packages/dashboard/src/lib/framework/registry/global-registry.ts, packages/dashboard/src/lib/framework/registry/registry-types.ts
Added has method to GlobalRegistry. Extended GlobalRegistryContents to include loginExtensions.
Public API Exports
packages/dashboard/src/lib/index.ts
Exported login extension types and hook from the main index.
Example Plugin Usage
packages/dev-server/test-plugins/reviews/dashboard/index.tsx
Demonstrated use of login extension points by providing custom logo, afterForm, and loginImage components in a test plugin.

Sequence Diagram(s)

sequenceDiagram
    participant Plugin as Dashboard Extension Plugin
    participant Registry as GlobalRegistry
    participant Dashboard as Dashboard UI
    participant LoginForm as LoginForm Component

    Plugin->>Registry: defineDashboardExtension({ login: { ... } })
    Registry->>Registry: registerLoginExtensions(loginExtensions)
    Registry->>Registry: Merge and store login extensions

    Dashboard->>Registry: useLoginExtensions()
    Registry-->>Dashboard: Provide current login extensions

    Dashboard->>LoginForm: Render LoginForm with extensions
    LoginForm->>LoginForm: Conditionally render custom logo, beforeForm, afterForm, loginImage
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~18 minutes

Note

⚡️ Unit Test Generation is now available in beta!

Learn more here, or try it out under "Finishing Touches" below.


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
🪧 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.
    • Explain this complex logic.
    • 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 explain this code block.
    • @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 explain its main purpose.
    • @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.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

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 sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests 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.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

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.

Copy link

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (4)
packages/dashboard/src/lib/framework/registry/global-registry.ts (1)

40-42: Consider using generic type constraint for consistency.

The has method uses string while other registry methods use the generic GlobalRegistryKey constraint. This breaks the established type safety pattern.

Apply this diff to maintain consistency with other registry methods:

-    public has(key: string): boolean {
+    public has<T extends GlobalRegistryKey>(key: T): boolean {
         return this.registry.has(key);
     }
packages/dev-server/test-plugins/reviews/dashboard/index.tsx (1)

24-48: Good demonstration of login extensions with minor suggestions.

The login extension implementation provides a clear example of all available extension points. However, consider these improvements:

  1. Localization: The "Login with Vendure ID" text should use localization via the Trans component or useLingui() hook as per coding guidelines.

  2. Component props typing: Consider typing the component props as Readonly<{}> to align with coding guidelines.

For the afterForm component, consider adding localization:

-                        Login with Vendure ID
+                        <Trans>Login with Vendure ID</Trans>

And for the loginImage component:

-                    Custom Login Image
+                    <Trans>Custom Login Image</Trans>

Don't forget to import Trans from the appropriate localization package.

packages/dashboard/src/lib/framework/extension-api/types/login.ts (1)

12-18: Consider adding prop constraints for better type safety.

The interface looks good, but React.ComponentType allows components with any props. Consider whether extension components should have specific prop requirements or constraints.

If no props are expected, you could use:

-    component: React.ComponentType;
+    component: React.ComponentType<Record<string, never>>;

Or if specific props are needed:

-    component: React.ComponentType;
+    component: React.ComponentType<YourPropsType>;
packages/dashboard/src/lib/components/login/login-form.tsx (1)

72-104: Consider refactoring to reduce code duplication.

The logo extension implementation works correctly, but the beforeForm extension logic is duplicated in both branches of the conditional.

Consider extracting the beforeForm logic to reduce duplication:

+                                const BeforeFormExtension = () => (
+                                    loginExtensions.beforeForm ? (
+                                        <>
+                                            <Separator className="w-full" />
+                                            <div className="w-full">
+                                                <loginExtensions.beforeForm.component />
+                                            </div>
+                                        </>
+                                    ) : null
+                                );
+
                                 {loginExtensions.logo ? (
                                     <>
                                         <loginExtensions.logo.component />
-                                        {loginExtensions.beforeForm && (
-                                            <>
-                                                <loginExtensions.beforeForm.component />
-                                                <Separator className="w-full" />
-                                            </>
-                                        )}
+                                        <BeforeFormExtension />
                                     </>
                                 ) : (
                                     <>
                                         {/* existing default content */}
-                                        {loginExtensions.beforeForm && (
-                                            <>
-                                                <Separator className="w-full" />
-                                                <div className="w-full">
-                                                    <loginExtensions.beforeForm.component />
-                                                </div>
-                                            </>
-                                        )}
+                                        <BeforeFormExtension />
                                     </>
                                 )}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8e7574b and dd39a72.

📒 Files selected for processing (12)
  • packages/dashboard/src/lib/components/login/login-form.tsx (4 hunks)
  • packages/dashboard/src/lib/framework/extension-api/define-dashboard-extension.ts (2 hunks)
  • packages/dashboard/src/lib/framework/extension-api/extension-api-types.ts (2 hunks)
  • packages/dashboard/src/lib/framework/extension-api/logic/index.ts (1 hunks)
  • packages/dashboard/src/lib/framework/extension-api/logic/login.ts (1 hunks)
  • packages/dashboard/src/lib/framework/extension-api/types/index.ts (1 hunks)
  • packages/dashboard/src/lib/framework/extension-api/types/login.ts (1 hunks)
  • packages/dashboard/src/lib/framework/extension-api/use-login-extensions.ts (1 hunks)
  • packages/dashboard/src/lib/framework/registry/global-registry.ts (1 hunks)
  • packages/dashboard/src/lib/framework/registry/registry-types.ts (2 hunks)
  • packages/dashboard/src/lib/index.ts (1 hunks)
  • packages/dev-server/test-plugins/reviews/dashboard/index.tsx (2 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
packages/dashboard/src/**/*.{ts,tsx}

📄 CodeRabbit Inference Engine (.cursor/rules/dashboard.mdc)

packages/dashboard/src/**/*.{ts,tsx}: Use TanStack Query (useQuery or useMutation) for data fetching; do not use Apollo Client.
When creating useQuery calls, follow the provided pattern: import { api } from '@/graphql/api.js'; import { graphql } from '@/graphql/graphql.js'; use useQuery with queryKey, staleTime, and queryFn using api.query.
When performing mutations, follow the provided useMutation pattern: use graphql() for the mutation document, api.mutate for mutationFn, and do not pass variables at declaration.

Files:

  • packages/dashboard/src/lib/framework/extension-api/extension-api-types.ts
  • packages/dashboard/src/lib/framework/registry/global-registry.ts
  • packages/dashboard/src/lib/framework/extension-api/logic/index.ts
  • packages/dashboard/src/lib/framework/registry/registry-types.ts
  • packages/dashboard/src/lib/framework/extension-api/define-dashboard-extension.ts
  • packages/dashboard/src/lib/index.ts
  • packages/dashboard/src/lib/framework/extension-api/types/index.ts
  • packages/dashboard/src/lib/framework/extension-api/types/login.ts
  • packages/dashboard/src/lib/framework/extension-api/logic/login.ts
  • packages/dashboard/src/lib/components/login/login-form.tsx
  • packages/dashboard/src/lib/framework/extension-api/use-login-extensions.ts
packages/dashboard/src/**/*.{tsx,ts}

📄 CodeRabbit Inference Engine (.cursor/rules/dashboard.mdc)

React component props objects should be typed as Readonly<...>.

Files:

  • packages/dashboard/src/lib/framework/extension-api/extension-api-types.ts
  • packages/dashboard/src/lib/framework/registry/global-registry.ts
  • packages/dashboard/src/lib/framework/extension-api/logic/index.ts
  • packages/dashboard/src/lib/framework/registry/registry-types.ts
  • packages/dashboard/src/lib/framework/extension-api/define-dashboard-extension.ts
  • packages/dashboard/src/lib/index.ts
  • packages/dashboard/src/lib/framework/extension-api/types/index.ts
  • packages/dashboard/src/lib/framework/extension-api/types/login.ts
  • packages/dashboard/src/lib/framework/extension-api/logic/login.ts
  • packages/dashboard/src/lib/components/login/login-form.tsx
  • packages/dashboard/src/lib/framework/extension-api/use-login-extensions.ts
packages/dashboard/src/**/*.{tsx,jsx}

📄 CodeRabbit Inference Engine (.cursor/rules/dashboard.mdc)

packages/dashboard/src/**/*.{tsx,jsx}: Use React for all UI components in the dashboard package.
Prefer re-using components from /src/lib/components, especially Shadcn components from /src/lib/components/ui.
Prefer using the FormFieldWrapper component for forms over raw Shadcn components.
All labels or user-facing messages should use localization via the Trans component or useLingui().

Files:

  • packages/dashboard/src/lib/components/login/login-form.tsx
packages/dashboard/src/lib/components/**/*.{tsx,jsx}

📄 CodeRabbit Inference Engine (.cursor/rules/dashboard.mdc)

Use Shadcn UI and Tailwind CSS for UI components.

Files:

  • packages/dashboard/src/lib/components/login/login-form.tsx
🧠 Learnings (9)
packages/dashboard/src/lib/framework/extension-api/extension-api-types.ts (3)

Learnt from: CR
PR: vendure-ecommerce/vendure#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-23T07:05:04.344Z
Learning: Applies to packages/dashboard/src/lib/components/**/*.{tsx,jsx} : Use Shadcn UI and Tailwind CSS for UI components.

Learnt from: CR
PR: vendure-ecommerce/vendure#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-23T07:05:04.344Z
Learning: Applies to packages/dashboard/src/**/*.{tsx,jsx} : Use React for all UI components in the dashboard package.

Learnt from: CR
PR: vendure-ecommerce/vendure#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-23T07:05:04.344Z
Learning: Applies to packages/dashboard/src/**/*.{tsx,jsx} : Prefer re-using components from /src/lib/components, especially Shadcn components from /src/lib/components/ui.

packages/dashboard/src/lib/framework/extension-api/logic/index.ts (7)

Learnt from: CR
PR: vendure-ecommerce/vendure#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-23T07:05:04.344Z
Learning: Applies to packages/dashboard/src/**/*.{tsx,jsx} : Prefer re-using components from /src/lib/components, especially Shadcn components from /src/lib/components/ui.

Learnt from: CR
PR: vendure-ecommerce/vendure#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-23T07:05:04.344Z
Learning: Applies to packages/dashboard/src/**/*.{tsx,jsx} : Use React for all UI components in the dashboard package.

Learnt from: CR
PR: vendure-ecommerce/vendure#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-23T07:05:04.344Z
Learning: Applies to packages/dashboard/src/lib/components/**/*.{tsx,jsx} : Use Shadcn UI and Tailwind CSS for UI components.

Learnt from: CR
PR: vendure-ecommerce/vendure#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-23T07:05:04.344Z
Learning: Applies to packages/dashboard/src/app/routes/**/*.tsx : Use TanStack Router for all routing and navigation in the dashboard app.

Learnt from: CR
PR: vendure-ecommerce/vendure#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-23T07:05:04.344Z
Learning: Applies to packages/dashboard/src/**/*.{tsx,jsx} : All labels or user-facing messages should use localization via the Trans component or useLingui().

Learnt from: CR
PR: vendure-ecommerce/vendure#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-23T07:05:04.344Z
Learning: Applies to packages/dashboard/src/**/*.{ts,tsx} : When creating useQuery calls, follow the provided pattern: import { api } from '@/graphql/api.js'; import { graphql } from '@/graphql/graphql.js'; use useQuery with queryKey, staleTime, and queryFn using api.query.

Learnt from: CR
PR: vendure-ecommerce/vendure#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-23T07:05:04.344Z
Learning: Applies to packages/dashboard/src/**/*.{tsx,jsx} : Prefer using the FormFieldWrapper component for forms over raw Shadcn components.

packages/dashboard/src/lib/framework/registry/registry-types.ts (3)

Learnt from: CR
PR: vendure-ecommerce/vendure#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-23T07:05:04.344Z
Learning: Applies to packages/dashboard/src/**/*.{tsx,jsx} : Prefer re-using components from /src/lib/components, especially Shadcn components from /src/lib/components/ui.

Learnt from: CR
PR: vendure-ecommerce/vendure#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-23T07:05:04.344Z
Learning: Applies to packages/dashboard/src/**/*.{tsx,jsx} : Use React for all UI components in the dashboard package.

Learnt from: CR
PR: vendure-ecommerce/vendure#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-23T07:05:04.344Z
Learning: Applies to packages/dashboard/src/lib/components/**/*.{tsx,jsx} : Use Shadcn UI and Tailwind CSS for UI components.

packages/dashboard/src/lib/index.ts (10)

Learnt from: CR
PR: vendure-ecommerce/vendure#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-23T07:05:04.344Z
Learning: Applies to packages/dashboard/src/**/*.{tsx,jsx} : Prefer re-using components from /src/lib/components, especially Shadcn components from /src/lib/components/ui.

Learnt from: CR
PR: vendure-ecommerce/vendure#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-23T07:05:04.344Z
Learning: Applies to packages/dashboard/src/**/*.{tsx,jsx} : Use React for all UI components in the dashboard package.

Learnt from: CR
PR: vendure-ecommerce/vendure#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-23T07:05:04.344Z
Learning: Applies to packages/dashboard/src/lib/components/**/*.{tsx,jsx} : Use Shadcn UI and Tailwind CSS for UI components.

Learnt from: CR
PR: vendure-ecommerce/vendure#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-23T07:05:04.344Z
Learning: Applies to packages/dashboard/src/**/*.{ts,tsx} : When creating useQuery calls, follow the provided pattern: import { api } from '@/graphql/api.js'; import { graphql } from '@/graphql/graphql.js'; use useQuery with queryKey, staleTime, and queryFn using api.query.

Learnt from: CR
PR: vendure-ecommerce/vendure#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-23T07:05:04.344Z
Learning: Applies to packages/dashboard/src/app/routes/**/*.tsx : Use TanStack Router for all routing and navigation in the dashboard app.

Learnt from: CR
PR: vendure-ecommerce/vendure#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-23T07:05:04.344Z
Learning: Applies to packages/dashboard/src/**/*.{tsx,jsx} : All labels or user-facing messages should use localization via the Trans component or useLingui().

Learnt from: CR
PR: vendure-ecommerce/vendure#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-23T07:05:04.344Z
Learning: Applies to packages/dashboard/src/**/*.{ts,tsx} : When performing mutations, follow the provided useMutation pattern: use graphql() for the mutation document, api.mutate for mutationFn, and do not pass variables at declaration.

Learnt from: CR
PR: vendure-ecommerce/vendure#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-23T07:05:04.344Z
Learning: Applies to packages/dashboard/src/app/routes/** : Do not create new directories or files in /src/app/routes/ that do not fit the pattern: route files (except those in /components, /hooks, or ending with .graphql.ts).

Learnt from: CR
PR: vendure-ecommerce/vendure#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-23T07:05:04.344Z
Learning: Applies to packages/dashboard/src/**/*.{ts,tsx} : Use TanStack Query (useQuery or useMutation) for data fetching; do not use Apollo Client.

Learnt from: CR
PR: vendure-ecommerce/vendure#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-23T07:05:04.344Z
Learning: Applies to packages/dashboard/src/**/*.{tsx,jsx} : Prefer using the FormFieldWrapper component for forms over raw Shadcn components.

packages/dashboard/src/lib/framework/extension-api/types/index.ts (6)

Learnt from: CR
PR: vendure-ecommerce/vendure#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-23T07:05:04.344Z
Learning: Applies to packages/dashboard/src/**/*.{tsx,jsx} : Use React for all UI components in the dashboard package.

Learnt from: CR
PR: vendure-ecommerce/vendure#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-23T07:05:04.344Z
Learning: Applies to packages/dashboard/src/**/*.{tsx,jsx} : Prefer re-using components from /src/lib/components, especially Shadcn components from /src/lib/components/ui.

Learnt from: CR
PR: vendure-ecommerce/vendure#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-23T07:05:04.344Z
Learning: Applies to packages/dashboard/src/lib/components/**/*.{tsx,jsx} : Use Shadcn UI and Tailwind CSS for UI components.

Learnt from: CR
PR: vendure-ecommerce/vendure#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-23T07:05:04.344Z
Learning: Applies to packages/dashboard/src/**/*.{ts,tsx} : When creating useQuery calls, follow the provided pattern: import { api } from '@/graphql/api.js'; import { graphql } from '@/graphql/graphql.js'; use useQuery with queryKey, staleTime, and queryFn using api.query.

Learnt from: CR
PR: vendure-ecommerce/vendure#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-23T07:05:04.344Z
Learning: Applies to packages/dashboard/src/app/routes/**/*.tsx : Use TanStack Router for all routing and navigation in the dashboard app.

Learnt from: CR
PR: vendure-ecommerce/vendure#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-23T07:05:04.344Z
Learning: Applies to packages/dashboard/src/**/*.{tsx,jsx} : Prefer using the FormFieldWrapper component for forms over raw Shadcn components.

packages/dev-server/test-plugins/reviews/dashboard/index.tsx (9)

Learnt from: CR
PR: vendure-ecommerce/vendure#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-23T07:05:04.344Z
Learning: Applies to packages/dashboard/src/lib/components/**/*.{tsx,jsx} : Use Shadcn UI and Tailwind CSS for UI components.

Learnt from: CR
PR: vendure-ecommerce/vendure#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-23T07:05:04.344Z
Learning: Applies to packages/dashboard/src/**/*.{tsx,jsx} : Use React for all UI components in the dashboard package.

Learnt from: CR
PR: vendure-ecommerce/vendure#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-23T07:05:04.344Z
Learning: Applies to packages/dashboard/src/**/*.{tsx,jsx} : Prefer re-using components from /src/lib/components, especially Shadcn components from /src/lib/components/ui.

Learnt from: CR
PR: vendure-ecommerce/vendure#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-23T07:05:04.344Z
Learning: Applies to packages/dashboard/src/**/*.{tsx,jsx} : All labels or user-facing messages should use localization via the Trans component or useLingui().

Learnt from: CR
PR: vendure-ecommerce/vendure#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-23T07:05:04.344Z
Learning: Applies to packages/dashboard/src/**/*.{tsx,ts} : React component props objects should be typed as Readonly<...>.

Learnt from: CR
PR: vendure-ecommerce/vendure#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-23T07:05:04.344Z
Learning: Applies to packages/dashboard/src/**/*.{tsx,jsx} : Prefer using the FormFieldWrapper component for forms over raw Shadcn components.

Learnt from: CR
PR: vendure-ecommerce/vendure#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-23T07:05:04.344Z
Learning: Applies to packages/dashboard/src/app/routes/**/*.tsx : Use TanStack Router for all routing and navigation in the dashboard app.

Learnt from: CR
PR: vendure-ecommerce/vendure#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-23T07:05:04.344Z
Learning: Applies to packages/dashboard/src/**/*.{ts,tsx} : When creating useQuery calls, follow the provided pattern: import { api } from '@/graphql/api.js'; import { graphql } from '@/graphql/graphql.js'; use useQuery with queryKey, staleTime, and queryFn using api.query.

Learnt from: CR
PR: vendure-ecommerce/vendure#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-23T07:05:04.344Z
Learning: Applies to packages/dashboard/src/**/*.{ts,tsx} : Use TanStack Query (useQuery or useMutation) for data fetching; do not use Apollo Client.

packages/dashboard/src/lib/framework/extension-api/types/login.ts (6)

Learnt from: CR
PR: vendure-ecommerce/vendure#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-23T07:05:04.344Z
Learning: Applies to packages/dashboard/src/**/*.{tsx,jsx} : Use React for all UI components in the dashboard package.

Learnt from: CR
PR: vendure-ecommerce/vendure#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-23T07:05:04.344Z
Learning: Applies to packages/dashboard/src/lib/components/**/*.{tsx,jsx} : Use Shadcn UI and Tailwind CSS for UI components.

Learnt from: CR
PR: vendure-ecommerce/vendure#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-23T07:05:04.344Z
Learning: Applies to packages/dashboard/src/**/*.{tsx,jsx} : Prefer re-using components from /src/lib/components, especially Shadcn components from /src/lib/components/ui.

Learnt from: CR
PR: vendure-ecommerce/vendure#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-23T07:05:04.344Z
Learning: Applies to packages/dashboard/src/**/*.{tsx,ts} : React component props objects should be typed as Readonly<...>.

Learnt from: CR
PR: vendure-ecommerce/vendure#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-23T07:05:04.344Z
Learning: Applies to packages/dashboard/src/**/*.{tsx,jsx} : All labels or user-facing messages should use localization via the Trans component or useLingui().

Learnt from: CR
PR: vendure-ecommerce/vendure#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-23T07:05:04.344Z
Learning: Applies to packages/dashboard/src/app/routes/**/*.tsx : Use TanStack Router for all routing and navigation in the dashboard app.

packages/dashboard/src/lib/components/login/login-form.tsx (5)

Learnt from: CR
PR: vendure-ecommerce/vendure#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-23T07:05:04.344Z
Learning: Applies to packages/dashboard/src/**/*.{tsx,jsx} : Prefer using the FormFieldWrapper component for forms over raw Shadcn components.

Learnt from: CR
PR: vendure-ecommerce/vendure#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-23T07:05:04.344Z
Learning: Applies to packages/dashboard/src/lib/components/**/*.{tsx,jsx} : Use Shadcn UI and Tailwind CSS for UI components.

Learnt from: CR
PR: vendure-ecommerce/vendure#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-23T07:05:04.344Z
Learning: Applies to packages/dashboard/src/**/*.{tsx,jsx} : Prefer re-using components from /src/lib/components, especially Shadcn components from /src/lib/components/ui.

Learnt from: CR
PR: vendure-ecommerce/vendure#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-23T07:05:04.344Z
Learning: Applies to packages/dashboard/src/**/*.{tsx,jsx} : All labels or user-facing messages should use localization via the Trans component or useLingui().

Learnt from: CR
PR: vendure-ecommerce/vendure#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-23T07:05:04.344Z
Learning: Applies to packages/dashboard/src/**/*.{tsx,jsx} : Use React for all UI components in the dashboard package.

packages/dashboard/src/lib/framework/extension-api/use-login-extensions.ts (8)

Learnt from: CR
PR: vendure-ecommerce/vendure#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-23T07:05:04.344Z
Learning: Applies to packages/dashboard/src/**/*.{tsx,jsx} : Use React for all UI components in the dashboard package.

Learnt from: CR
PR: vendure-ecommerce/vendure#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-23T07:05:04.344Z
Learning: Applies to packages/dashboard/src/**/*.{ts,tsx} : When creating useQuery calls, follow the provided pattern: import { api } from '@/graphql/api.js'; import { graphql } from '@/graphql/graphql.js'; use useQuery with queryKey, staleTime, and queryFn using api.query.

Learnt from: CR
PR: vendure-ecommerce/vendure#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-23T07:05:04.344Z
Learning: Applies to packages/dashboard/src/lib/components/**/*.{tsx,jsx} : Use Shadcn UI and Tailwind CSS for UI components.

Learnt from: CR
PR: vendure-ecommerce/vendure#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-23T07:05:04.344Z
Learning: Applies to packages/dashboard/src/**/*.{tsx,jsx} : Prefer re-using components from /src/lib/components, especially Shadcn components from /src/lib/components/ui.

Learnt from: CR
PR: vendure-ecommerce/vendure#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-23T07:05:04.344Z
Learning: Applies to packages/dashboard/src/app/routes/**/*.tsx : Use TanStack Router for all routing and navigation in the dashboard app.

Learnt from: CR
PR: vendure-ecommerce/vendure#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-23T07:05:04.344Z
Learning: Applies to packages/dashboard/src/**/*.{ts,tsx} : When performing mutations, follow the provided useMutation pattern: use graphql() for the mutation document, api.mutate for mutationFn, and do not pass variables at declaration.

Learnt from: CR
PR: vendure-ecommerce/vendure#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-23T07:05:04.344Z
Learning: Applies to packages/dashboard/src/**/*.{ts,tsx} : Use TanStack Query (useQuery or useMutation) for data fetching; do not use Apollo Client.

Learnt from: CR
PR: vendure-ecommerce/vendure#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-23T07:05:04.344Z
Learning: Applies to packages/dashboard/src/**/*.{tsx,jsx} : All labels or user-facing messages should use localization via the Trans component or useLingui().

🧬 Code Graph Analysis (7)
packages/dashboard/src/lib/framework/extension-api/extension-api-types.ts (1)
packages/dashboard/src/lib/framework/extension-api/types/login.ts (1)
  • DashboardLoginExtensions (80-101)
packages/dashboard/src/lib/framework/registry/registry-types.ts (1)
packages/dashboard/src/lib/framework/extension-api/types/login.ts (1)
  • DashboardLoginExtensions (80-101)
packages/dashboard/src/lib/framework/extension-api/define-dashboard-extension.ts (1)
packages/dashboard/src/lib/framework/extension-api/logic/login.ts (1)
  • registerLoginExtensions (4-17)
packages/dev-server/test-plugins/reviews/dashboard/index.tsx (1)
packages/dashboard/src/lib/components/shared/logo-mark.tsx (1)
  • LogoMark (1-24)
packages/dashboard/src/lib/framework/extension-api/logic/login.ts (2)
packages/dashboard/src/lib/framework/extension-api/types/login.ts (1)
  • DashboardLoginExtensions (80-101)
packages/dashboard/src/lib/framework/registry/global-registry.ts (1)
  • globalRegistry (50-50)
packages/dashboard/src/lib/components/login/login-form.tsx (6)
packages/dashboard/src/lib/framework/extension-api/use-login-extensions.ts (1)
  • useLoginExtensions (8-26)
packages/dashboard/src/lib/components/ui/separator.tsx (1)
  • Separator (26-26)
packages/dashboard/src/lib/virtual.d.ts (1)
  • uiConfig (11-11)
packages/dashboard/src/lib/components/shared/logo-mark.tsx (1)
  • LogoMark (1-24)
packages/dashboard/src/lib/lib/trans.tsx (1)
  • Trans (6-8)
packages/dashboard/src/lib/components/ui/form.tsx (1)
  • Form (141-141)
packages/dashboard/src/lib/framework/extension-api/use-login-extensions.ts (3)
packages/dashboard/src/lib/framework/extension-api/types/login.ts (1)
  • DashboardLoginExtensions (80-101)
packages/dashboard/src/lib/framework/registry/global-registry.ts (1)
  • globalRegistry (50-50)
packages/dashboard/src/lib/framework/extension-api/define-dashboard-extension.ts (1)
  • onExtensionSourceChange (18-20)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (11)
  • GitHub Check: unit tests (22.x)
  • GitHub Check: build (22.x)
  • GitHub Check: publish_install (macos-latest, 22.x)
  • GitHub Check: publish_install (windows-latest, 20.x)
  • GitHub Check: publish_install (macos-latest, 20.x)
  • GitHub Check: publish_install (macos-latest, 24.x)
  • GitHub Check: publish_install (windows-latest, 24.x)
  • GitHub Check: publish_install (windows-latest, 22.x)
  • GitHub Check: publish_install (ubuntu-latest, 24.x)
  • GitHub Check: publish_install (ubuntu-latest, 22.x)
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (20)
packages/dashboard/src/lib/framework/extension-api/types/index.ts (1)

7-7: LGTM!

The export follows the established pattern and maintains alphabetical ordering.

packages/dashboard/src/lib/framework/registry/registry-types.ts (2)

4-4: LGTM!

The import follows the established pattern and integrates properly with the existing imports.


30-30: LGTM!

The property addition correctly integrates the login extensions into the global registry type system.

packages/dashboard/src/lib/framework/extension-api/logic/index.ts (1)

7-7: LGTM!

The export follows the established pattern and maintains alphabetical ordering.

packages/dashboard/src/lib/framework/extension-api/extension-api-types.ts (2)

8-8: LGTM!

The import is correctly added to the existing import block and follows the established pattern.


68-72: LGTM!

The property addition is well-documented and properly typed. The optional nature maintains backward compatibility while enabling the new login extension functionality.

packages/dashboard/src/lib/index.ts (2)

1-1: Verify that manual changes to auto-generated file are appropriate.

The file header indicates this is auto-generated, but the PR includes manual additions of login extension exports. Please confirm that manual edits to this file are intended and won't be overwritten by the generation process.


183-183: LGTM! Proper placement of login extension exports.

The new login extension exports are correctly positioned alphabetically within the framework extension API types and follow the established export pattern.

Also applies to: 187-187

packages/dashboard/src/lib/framework/extension-api/define-dashboard-extension.ts (2)

10-10: LGTM! Correct import addition.

The import of registerLoginExtensions follows the established pattern and is properly imported from the logic module.


61-62: LGTM! Proper integration of login extension registration.

The login extension registration follows the same pattern as other extension types and is correctly integrated into the extension registration workflow.

packages/dashboard/src/lib/framework/extension-api/use-login-extensions.ts (1)

8-26: LGTM! Well-implemented React hook following established patterns.

The useLoginExtensions hook properly implements the reactive pattern for consuming login extensions:

  • Correct lazy initialization with current registry state
  • Proper subscription to extension source changes
  • Immediate update to capture pre-registered extensions
  • Appropriate TypeScript typing

The implementation is consistent with other extension hooks in the framework.

packages/dashboard/src/lib/framework/extension-api/logic/login.ts (1)

4-17: LGTM! Correct implementation following established registration pattern.

The registerLoginExtensions function properly implements the extension registration pattern:

  • Appropriate null/undefined guard with early return
  • Consistent use of globalRegistry with merge logic
  • Proper TypeScript typing and parameter handling

The implementation aligns with other extension registration functions in the framework.

packages/dev-server/test-plugins/reviews/dashboard/index.tsx (1)

1-7: LGTM! Proper imports for login extension components.

The imports correctly include the necessary components (LogoMark, Button) and the defineDashboardExtension function from the dashboard package.

packages/dashboard/src/lib/framework/extension-api/types/login.ts (3)

1-1: LGTM!

Proper type-only import for React types.


29-69: LGTM! Consistent interface design.

All interfaces follow the same well-documented pattern. The same consideration about prop constraints mentioned for LoginLogoExtension applies here as well.


80-101: LGTM! Well-designed composite interface.

The interface effectively aggregates all login extension types with intuitive property names and appropriate optional typing for flexible customization.

packages/dashboard/src/lib/components/login/login-form.tsx (4)

13-13: LGTM!

New imports follow the established patterns and are correctly referenced.

Also applies to: 16-16


37-37: LGTM!

Proper hook usage following React best practices.


155-161: LGTM!

Clean implementation of the afterForm extension with proper conditional rendering and visual separation.


164-203: LGTM!

Excellent implementation of the loginImage extension that preserves all existing functionality while enabling complete customization of the image panel.

@michaelbromley michaelbromley changed the base branch from master to minor July 31, 2025 10:06
@michaelbromley michaelbromley merged commit 866afcb into minor Jul 31, 2025
40 checks passed
@michaelbromley michaelbromley deleted the dashboard-login-extension-api branch July 31, 2025 10:06
@github-actions github-actions bot locked and limited conversation to collaborators Jul 31, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants