Skip to content
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

feat: new empty placeholder component #2792

Open
wants to merge 15 commits into
base: main
Choose a base branch
from

Conversation

MichaelUnkey
Copy link
Collaborator

@MichaelUnkey MichaelUnkey commented Jan 7, 2025

What does this PR do?

Added an new component to use when no data is available. Includes Top icon, title, description, and action element.
Added the component to the @unkey/ui package and Engineering docs.
added the component to all places previous was. Everything worked well with no issues noticed.
Fixes # (issue)

eng-1606

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • Chore (refactoring code, technical debt, workflow improvements)
  • Enhancement (small improvements)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update

How should this be tested?

  • Component conforms to style standards and can be used as expected with no issues on different sized devices.

Required

  • Filled out the "How to test" section in this PR
  • Read Contributing Guide
  • Self-reviewed my own code
  • Commented on my code in hard-to-understand areas
  • Ran pnpm build
  • Ran pnpm fmt
  • Checked for warnings, there are none
  • Removed all console.logs
  • Merged the latest changes from main onto my branch with git pull origin main
  • My changes don't cause any responsiveness issues

Appreciated

Light Mode
image
Dark Mode
image

  • If a UI change was made: Added a screen recording or screenshots to this PR
  • Updated the Unkey Docs if changes were necessary

Summary by CodeRabbit

Release Notes: UI Component Refactoring

  • New Features

    • Introduced a new Empty component from @unkey/ui library to replace EmptyPlaceholder
    • Enhanced empty state representations across multiple dashboard pages
  • UI Improvements

    • Standardized empty state rendering with a more flexible and consistent component structure
    • Added support for icon, title, description, and action sections in empty states
    • Improved visual consistency across different sections of the application
  • Technical Updates

    • Removed custom EmptyPlaceholder component
    • Migrated existing empty state implementations to use the new Empty component
    • Updated import statements across multiple files
  • Styling Changes

    • Minor color adjustments to alert foreground color
    • Refined empty state component styling

This release focuses on improving the user interface's empty state representations with a more modular and consistent approach.

Copy link

linear bot commented Jan 7, 2025

Copy link

changeset-bot bot commented Jan 7, 2025

⚠️ No Changeset found

Latest commit: 5abbdf6

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

Copy link

vercel bot commented Jan 7, 2025

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

Name Status Preview Comments Updated (UTC)
engineering ✅ Ready (Inspect) Visit Preview 💬 Add feedback Jan 8, 2025 4:20pm
play ✅ Ready (Inspect) Visit Preview 💬 Add feedback Jan 8, 2025 4:20pm
www ✅ Ready (Inspect) Visit Preview 💬 Add feedback Jan 8, 2025 4:20pm
1 Skipped Deployment
Name Status Preview Comments Updated (UTC)
dashboard ⬜️ Ignored (Inspect) Visit Preview Jan 8, 2025 4:20pm

Copy link
Contributor

coderabbitai bot commented Jan 7, 2025

📝 Walkthrough

Walkthrough

This pull request introduces a comprehensive replacement of the custom EmptyPlaceholder component with the new Empty component from the @unkey/ui library across multiple files in the dashboard application. The changes involve updating import statements, modifying component structures, and transitioning to a more standardized empty state representation. The EmptyPlaceholder component has been completely removed, and its functionality is now handled by the new Empty component with its subcomponents like Empty.Icon, Empty.Title, Empty.Description, and Empty.Actions.

Changes

File Path Change Summary
apps/dashboard/app/(app)/* Replaced EmptyPlaceholder with Empty component across multiple pages and components
apps/dashboard/components/dashboard/empty-placeholder.tsx Completely removed the custom EmptyPlaceholder component
internal/ui/src/components/empty.tsx Added new Empty component with subcomponents
internal/ui/src/index.ts Added export for the new Empty component
apps/dashboard/styles/tailwind/tailwind.css Minor color variable adjustment

Suggested labels

Feature, Improvement, Needs Approval

Suggested reviewers

  • mcstepp
  • chronark
  • perkinsjr
  • ogzhanolguncu

Possibly related PRs


📜 Recent review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 850cb8b and 5abbdf6.

📒 Files selected for processing (1)
  • apps/engineering/content/design/components/empty.example.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/engineering/content/design/components/empty.example.tsx
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: Test Agent Local / test_agent_local

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ 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.
    • 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. (Beta)
  • @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
Contributor

github-actions bot commented Jan 7, 2025

Thank you for following the naming conventions for pull request titles! 🙏

Copy link

pullflow-com bot commented Jan 7, 2025

MichaelUnkey (GitHub user) ▸ What does this PR do?

Added an new component to use when no data is available. Includes Top icon, title, description, and action element.
Added the component to the unkey/ui package and Engineering docs.
added the component to all places previous was. Everything worked well with no issues noticed.
Fixes # (issue)

eng-1606

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • Chore (refactoring code, technical debt, workflow improvements)
  • Enhancement (small improvements)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update

How should this be tested?

  • Component conforms to style standards and can be used as expected with no issues on different sized devices.

Required

  • Filled out the "How to test" section in this PR
  • Read Contributing Guide
  • Self-reviewed my own code
  • Commented on my code in hard-to-understand areas
  • Ran pnpm build
  • Ran pnpm fmt
  • Checked for warnings, there are none
  • Removed all console.logs
  • Merged the latest changes from main onto my branch with git pull origin main
  • My changes don't cause any responsiveness issues

Appreciated

  • If a UI change was made: Added a screen recording or screenshots to this PR
  • Updated the Unkey Docs if changes were necessary

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: 2

🔭 Outside diff range comments (1)
apps/dashboard/components/opt-in.tsx (1)

Line range hint 22-35: Remove duplicate analytics event.

The same PostHogEvent is being triggered in both onMutate and onSuccess. Consider keeping only the onSuccess event to avoid duplicate tracking.

  const optIn = trpc.workspace.optIntoBeta.useMutation({
-   onMutate() {
-     PostHogEvent({
-       name: "self-serve-opt-in",
-       properties: { feature },
-     });
-   },
    onSuccess() {
      PostHogEvent({
        name: "self-serve-opt-in",
        properties: { feature },
      });
      toast.success("Successfully opted in");
      router.refresh();
    },
    onError(err) {
      toast.error(err.message);
    },
  });
🧹 Nitpick comments (19)
apps/engineering/content/design/components/empty.example.tsx (2)

18-20: Consider using variant prop instead of direct background class.

The Button component likely supports variants through props rather than requiring direct background color classes.

-          <Button className="bg-gray-2">
+          <Button variant="secondary">
            <BookOpen /> Example action button with icon
           </Button>

15-16: Consider using more meaningful example text.

The current example text is generic. Consider using text that better represents real-world usage scenarios.

-        <Empty.Title>Example Title Text</Empty.Title>
-        <Empty.Description>Example of Description Text.</Empty.Description>
+        <Empty.Title>No Results Found</Empty.Title>
+        <Empty.Description>Try adjusting your search filters to find what you're looking for.</Empty.Description>
internal/ui/src/components/empty.tsx (2)

5-7: Add type for children prop in EmptyRootProps interface

The interface should explicitly define the children prop type for better type safety.

 interface EmptyRootProps extends React.HTMLAttributes<HTMLDivElement> {
   fill: boolean | undefined;
+  children: React.ReactNode;
 }

40-61: Use consistent type definitions

For consistency, consider using interfaces instead of type aliases for EmptyTitleProps, EmptyDescriptionProps, and EmptyActionProps as they represent object types.

-type EmptyTitleProps = React.HTMLAttributes<HTMLHeadingElement>;
+interface EmptyTitleProps extends React.HTMLAttributes<HTMLHeadingElement> {}

-type EmptyDescriptionProps = React.HTMLAttributes<HTMLParagraphElement>;
+interface EmptyDescriptionProps extends React.HTMLAttributes<HTMLParagraphElement> {}

-type EmptyActionProps = React.HTMLAttributes<HTMLDivElement>;
+interface EmptyActionProps extends React.HTMLAttributes<HTMLDivElement> {}
apps/dashboard/app/(app)/settings/billing/stripe/page.tsx (1)

34-39: Consider adding an icon for consistency

Other instances of the Empty component across the application include an icon. Consider adding an appropriate icon (e.g., AlertTriangle or Settings) to maintain consistency.

 <Empty fill={true}>
+  <Empty.Icon>
+    <AlertTriangle className="w-8 h-8" />
+  </Empty.Icon>
   <Empty.Title>Stripe is not configured</Empty.Title>
   <Empty.Description>
     If you are selfhosting Unkey, you need to configure Stripe in your environment variables.
   </Empty.Description>
 </Empty>
apps/dashboard/app/integrations/vercel/callback/page.tsx (1)

Line range hint 69-84: Consider improving error message readability

While the error handling is comprehensive, consider making the error message more user-friendly by formatting the technical details in a collapsible section.

 <Empty className="m-8" fill={true}>
   <Empty.Title>Error</Empty.Title>
   <Empty.Description>
     We couldn't load your projects from Vercel. Please try again or contact [email protected]
   </Empty.Description>
+  <details className="mt-4">
+    <summary className="cursor-pointer">Technical Details</summary>
     <Code className="text-left">
       {JSON.stringify(
         {
           message: projects.err.message,
           context: projects.err.context,
         },
         null,
         2,
       )}
     </Code>
+  </details>
 </Empty>
apps/dashboard/app/(app)/apis/client.tsx (1)

79-96: Add consistent button styling

The implementation looks good, but the documentation button is missing className for consistent styling with other buttons.

 <Empty.Action>
   <CreateApiButton key="createApi" />
   <Link href="/docs" target="_blank">
-    <Button>
+    <Button className="items-center w-full gap-2">
       <BookOpen />
       Read the docs
     </Button>
   </Link>
 </Empty.Action>
apps/dashboard/app/(app)/settings/billing/stripe/success/page.tsx (1)

39-44: Standardize error message structure across empty states.

While the empty states are well-implemented, consider standardizing the error message structure for consistency:

  1. Title: Clear error message
  2. Description: Technical details (IDs)
  3. Action: Support contact information

Example structure for the session not found case:

 <Empty fill={true}>
   <Empty.Title>Stripe session not found</Empty.Title>
-  <Empty.Description>The Stripe session</Empty.Description>
-  <Code>{session_id}</Code>
-  <Empty.Description>
-    you are trying to access does not exist. Please contact [email protected].
-  </Empty.Description>
+  <Empty.Description>
+    The Stripe session {session_id} does not exist.
+  </Empty.Description>
+  <Empty.Action>
+    <Button onClick={() => window.location.href = 'mailto:[email protected]'}>
+      Contact Support
+    </Button>
+  </Empty.Action>
 </Empty>

Also applies to: 56-63, 69-76

apps/dashboard/app/(app)/apis/[apiId]/keys/[keyAuthId]/keys.tsx (1)

73-73: Remove commented-out code.

The commented-out code for CreateNewRole should be removed as it appears to be unused.

-          {/* <CreateNewRole trigger={<Button variant="primary">Create New Role</Button>} /> */}
apps/dashboard/app/(app)/settings/vercel/page.tsx (1)

86-94: Consider consolidating error descriptions

Instead of using two separate Empty.Description components, consider consolidating them into a single description with better formatting:

 <Empty fill={true}>
   <Empty.Title>Error</Empty.Title>
   <Empty.Description>
     We couldn't load your projects from Vercel. Please try again or contact support.
-  </Empty.Description>
-  <Empty.Description>
     <Code className="text-left mt-4">{JSON.stringify(err, null, 2)}</Code>
   </Empty.Description>
 </Empty>
apps/dashboard/app/(app)/ratelimits/[namespaceId]/logs/page.tsx (1)

159-175: Fix inconsistent JSX spacing

While the Empty component implementation is correct, there's inconsistent spacing in the JSX structure. Consider fixing the indentation:

       <Empty fill={true}>
         <Empty.Icon>
           <Box />
         </Empty.Icon>
         <Empty.Title>No logs found</Empty.Title>
         {isFiltered ? (
           <div className="flex flex-col items-center gap-2">
             <Empty.Description>
               No events matched these filters, try changing them.{" "}
             </Empty.Description>
           </div>
         ) : (
           <Empty.Description>
             Create, update or delete something and come back again.
           </Empty.Description>
         )}
       </Empty>
apps/dashboard/app/(app)/settings/team/page.tsx (1)

217-221: Wrap the InviteButton in Empty.Action.

For consistency with other empty states and to follow the component's API, consider wrapping the InviteButton in Empty.Action.

 <Empty fill={true}>
   <Empty.Title>No pending invitations</Empty.Title>
   <Empty.Description>Invite members to your team</Empty.Description>
-  <InviteButton />
+  <Empty.Action>
+    <InviteButton />
+  </Empty.Action>
 </Empty>
apps/dashboard/app/(app)/ratelimits/[namespaceId]/page.tsx (1)

227-237: Wrap the code snippet in Empty.Action.

For consistency with other empty states and to follow the component's API, consider wrapping the code snippet in Empty.Action.

 <Empty fill={true}>
   <Empty.Icon>
     <BarChart />
   </Empty.Icon>
   <Empty.Title>No usage</Empty.Title>
   <Empty.Description>Ratelimit something or change the range</Empty.Description>
-  <Code className="flex items-start  gap-0 sm:gap-8 p-4 my-8  text-xs  sm:text-xxs text-start overflow-x-auto max-w-full">
-    {snippet}
-    <CopyButton value={snippet} />
-  </Code>
+  <Empty.Action>
+    <Code className="flex items-start  gap-0 sm:gap-8 p-4 my-8  text-xs  sm:text-xxs text-start overflow-x-auto max-w-full">
+      {snippet}
+      <CopyButton value={snippet} />
+    </Code>
+  </Empty.Action>
 </Empty>
apps/engineering/content/design/components/empty.mdx (2)

11-11: Consider expanding the overview section.

The overview could benefit from more detailed guidance on when to use this component, including specific use cases and best practices.


29-31: Add code snippet for the full example.

While the example is rendered via <EmptyExample/>, it would be helpful to include the actual code snippet in the documentation for direct reference.

Consider adding:

 ## Full Example

 <EmptyExample/>
+
+```tsx
+import { Empty } from "@unkey/ui";
+
+export function EmptyExample() {
+  return (
+    <Empty>
+      <Empty.Icon><YourIcon /></Empty.Icon>
+      <Empty.Title>No Data Available</Empty.Title>
+      <Empty.Description>Add some data to get started</Empty.Description>
+      <Empty.Action>
+        <Button>Add Data</Button>
+      </Empty.Action>
+    </Empty>
+  );
+}
+```
apps/dashboard/app/(app)/apis/[apiId]/page.tsx (2)

249-255: Consider differentiating the empty states.

While the implementation is correct, using identical empty states for both verifications and active keys might not provide the best user experience. Consider customizing the messages and actions for each case.

For verifications, you could add:

 <Empty fill={true}>
   <Empty.Icon>
     <BarChart />
   </Empty.Icon>
   <Empty.Title>No usage</Empty.Title>
   <Empty.Description>Verify a key or change the range</Empty.Description>
+  <Empty.Action>
+    <Button onClick={() => setInterval("24h")}>Try Last 24 Hours</Button>
+  </Empty.Action>
 </Empty>

291-297: Add an action to guide users.

The empty state for active keys could benefit from an action that helps users understand how to get started.

 <Empty fill={true}>
   <Empty.Icon>
     <BarChart />
   </Empty.Icon>
   <Empty.Title>No usage</Empty.Title>
   <Empty.Description>Verify a key or change the range</Empty.Description>
+  <Empty.Action>
+    <CreateKeyButton apiId={api.id} keyAuthId={key.keyAuthId} />
+  </Empty.Action>
 </Empty>
apps/dashboard/app/(app)/apis/[apiId]/keys/[keyAuthId]/[keyId]/page.tsx (1)

355-361: Add an action to help users get started.

The empty state could be more helpful by providing an action that guides users on how to start using the key.

 <Empty fill={true}>
   <Empty.Icon>
     <BarChart />
   </Empty.Icon>
   <Empty.Title>Not used</Empty.Title>
   <Empty.Description>This key was not used in the last {interval}</Empty.Description>
+  <Empty.Action>
+    <Button asChild>
+      <a href="/docs/api-reference/verify" target="_blank" rel="noopener">
+        View API Documentation
+      </a>
+    </Button>
+  </Empty.Action>
 </Empty>
apps/dashboard/app/(app)/settings/vercel/client.tsx (1)

67-86: Consider extracting the SVG icon and enhancing the action button.

The Empty component implementation is good, but there are a few suggestions for improvement:

  1. The SVG icon is duplicated (also used in the project list). Consider extracting it to a shared component.
  2. The hardcoded black color in the SVG might not work well with different themes.
  3. The ghost variant for the action button might not provide enough emphasis for the primary action.
  4. The external link should indicate that it opens in a new tab.

Here's a suggested improvement:

 <Empty fill={true}>
   <Empty.Icon>
-    <svg
-      width="76"
-      height="65"
-      viewBox="0 0 76 65"
-      fill="none"
-      xmlns="http://www.w3.org/2000/svg"
-    >
-      <path d="M37.5274 0L75.0548 65H0L37.5274 0Z" fill="#000000" />
-    </svg>
+    <VercelIcon className="w-[76px] h-[65px]" />
   </Empty.Icon>
   <Empty.Title>No connected projects found</Empty.Title>
   <Empty.Description>Connect a Vercel project now</Empty.Description>
   <Empty.Action>
     <Link href="https://vercel.com/integrations/unkey" target="_blank">
-      <Button variant="ghost">Vercel Integration</Button>
+      <Button>
+        Vercel Integration
+        <ExternalLink className="w-4 h-4 ml-2" />
+      </Button>
     </Link>
   </Empty.Action>
 </Empty>

Create a new shared component for the Vercel icon:

// components/icons/vercel-icon.tsx
export const VercelIcon: React.FC<{ className?: string }> = ({ className }) => (
  <svg
    className={className}
    viewBox="0 0 76 65"
    fill="none"
    xmlns="http://www.w3.org/2000/svg"
  >
    <path d="M37.5274 0L75.0548 65H0L37.5274 0Z" fill="currentColor" />
  </svg>
);
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 8a1ccc3 and b3c14ef.

📒 Files selected for processing (31)
  • apps/dashboard/app/(app)/[...not-found]/page.tsx (1 hunks)
  • apps/dashboard/app/(app)/apis/[apiId]/keys/[keyAuthId]/[keyId]/page.tsx (2 hunks)
  • apps/dashboard/app/(app)/apis/[apiId]/keys/[keyAuthId]/keys.tsx (2 hunks)
  • apps/dashboard/app/(app)/apis/[apiId]/page.tsx (3 hunks)
  • apps/dashboard/app/(app)/apis/client.tsx (2 hunks)
  • apps/dashboard/app/(app)/audit/components/table/audit-log-table-client.tsx (2 hunks)
  • apps/dashboard/app/(app)/audit/page.tsx (2 hunks)
  • apps/dashboard/app/(app)/authorization/permissions/page.tsx (2 hunks)
  • apps/dashboard/app/(app)/authorization/roles/page.tsx (2 hunks)
  • apps/dashboard/app/(app)/identities/page.tsx (2 hunks)
  • apps/dashboard/app/(app)/layout.tsx (2 hunks)
  • apps/dashboard/app/(app)/ratelimits/[namespaceId]/logs/page.tsx (3 hunks)
  • apps/dashboard/app/(app)/ratelimits/[namespaceId]/overrides/page.tsx (2 hunks)
  • apps/dashboard/app/(app)/ratelimits/[namespaceId]/page.tsx (2 hunks)
  • apps/dashboard/app/(app)/ratelimits/page.tsx (2 hunks)
  • apps/dashboard/app/(app)/settings/billing/stripe/page.tsx (2 hunks)
  • apps/dashboard/app/(app)/settings/billing/stripe/success/page.tsx (3 hunks)
  • apps/dashboard/app/(app)/settings/team/page.tsx (3 hunks)
  • apps/dashboard/app/(app)/settings/user/update-user-email.tsx (2 hunks)
  • apps/dashboard/app/(app)/settings/user/update-user-name.tsx (2 hunks)
  • apps/dashboard/app/(app)/settings/vercel/client.tsx (2 hunks)
  • apps/dashboard/app/(app)/settings/vercel/page.tsx (3 hunks)
  • apps/dashboard/app/integrations/vercel/callback/page.tsx (3 hunks)
  • apps/dashboard/app/new/keys.tsx (2 hunks)
  • apps/dashboard/components/dashboard/empty-placeholder.tsx (0 hunks)
  • apps/dashboard/components/opt-in.tsx (3 hunks)
  • apps/dashboard/components/virtual-table.tsx (2 hunks)
  • apps/engineering/content/design/components/empty.example.tsx (1 hunks)
  • apps/engineering/content/design/components/empty.mdx (1 hunks)
  • internal/ui/src/components/empty.tsx (1 hunks)
  • internal/ui/src/index.ts (1 hunks)
💤 Files with no reviewable changes (1)
  • apps/dashboard/components/dashboard/empty-placeholder.tsx
⏰ Context from checks skipped due to timeout of 90000ms (4)
  • GitHub Check: Test Packages / Test ./internal/clickhouse
  • GitHub Check: Test API / API Test Local
  • GitHub Check: Test Agent Local / test_agent_local
  • GitHub Check: Build / Build
🔇 Additional comments (25)
internal/ui/src/index.ts (1)

4-4: LGTM! Export statement follows consistent pattern.

The export statement for the new Empty component follows the established pattern in the file.

apps/dashboard/app/(app)/[...not-found]/page.tsx (1)

6-14: LGTM! Clean implementation of the Empty component.

The Empty component is appropriately used for the 404 page, maintaining the same user experience while using the new component structure.

apps/dashboard/components/opt-in.tsx (1)

Line range hint 43-59: LGTM! Clean implementation of the Empty component.

The Empty component is appropriately used for the opt-in UI, maintaining the same user experience while using the new component structure.

apps/dashboard/app/(app)/audit/page.tsx (1)

41-50: LGTM! Clean implementation of the Empty component

The Empty component is properly implemented with all necessary subcomponents and the fill prop is correctly set.

apps/dashboard/app/(app)/layout.tsx (1)

53-67: Verify the need for border-0 className

The Empty component is used with className="border-0". Please clarify if this is intentional and why the default border needs to be removed in this specific instance.

apps/dashboard/app/(app)/settings/user/update-user-name.tsx (1)

47-49: LGTM! Good use of Empty component for loading state

The Empty component is appropriately used with correct props:

  • min-h-[200px] ensures consistent height during loading
  • fill={false} prevents unnecessary expansion
apps/dashboard/app/integrations/vercel/callback/page.tsx (1)

90-96: LGTM! Clear empty state messaging

Good implementation of the Empty component for the no-projects scenario with clear user guidance.

apps/dashboard/app/(app)/ratelimits/page.tsx (1)

73-94: LGTM! Excellent empty state implementation

Great implementation with:

  • Clear messaging
  • Helpful code snippet with copy functionality
  • Documentation link for further guidance
apps/dashboard/app/(app)/ratelimits/[namespaceId]/overrides/page.tsx (1)

100-106: LGTM! Clean implementation of the empty state.

The empty state implementation is clear, consistent, and provides good user guidance.

apps/dashboard/app/(app)/identities/page.tsx (1)

54-58: LGTM! Clean implementation of the loading state.

The loading state implementation is simple, clean, and consistent with the application's patterns.

apps/dashboard/app/(app)/apis/[apiId]/keys/[keyAuthId]/keys.tsx (1)

62-71: LGTM! Well-structured empty state with clear actions.

The empty state implementation is clear, actionable, and follows the component's best practices.

apps/dashboard/app/(app)/authorization/roles/page.tsx (1)

8-8: Implementation of Empty component looks good!

The migration from EmptyPlaceholder to Empty is well-structured with proper hierarchy of Empty.Icon, Empty.Title, Empty.Description, and Empty.Action components. The fill prop is correctly set to maintain consistent styling.

Also applies to: 86-98

apps/dashboard/app/(app)/authorization/permissions/page.tsx (1)

9-9: Implementation of Empty component looks good!

The migration from EmptyPlaceholder to Empty is well-structured. Good addition of className="w-full" to ensure proper width rendering.

Also applies to: 83-94

apps/dashboard/app/(app)/settings/vercel/page.tsx (1)

64-71: Implementation of Empty component for disconnected state looks good!

The Empty component is well-structured with proper Title and Action elements. The Button is correctly wrapped in a Link component for external navigation.

apps/dashboard/app/(app)/ratelimits/[namespaceId]/logs/page.tsx (1)

105-109: Loading state implementation looks good!

The Empty component is appropriately used as a loading state with the Loading component as the icon.

apps/dashboard/app/new/keys.tsx (2)

18-18: LGTM!

The import statement for the new Empty component is correctly placed.


124-133: LGTM!

The Empty component is correctly implemented with proper nesting of description and button elements. The migration from EmptyPlaceholder maintains the same functionality while following the new component's API.

apps/dashboard/app/(app)/settings/team/page.tsx (2)

3-3: LGTM!

The import statement for the new Empty component is correctly placed.


64-72: LGTM!

The Empty component is correctly implemented with proper nesting of title, description, and action elements. The migration maintains the same functionality while following the new component's API.

apps/dashboard/app/(app)/ratelimits/[namespaceId]/page.tsx (1)

16-16: LGTM!

The import statement for the new Empty component is correctly placed.

apps/dashboard/components/virtual-table.tsx (2)

3-6: LGTM!

The import statements for the new components and icons are correctly placed.


206-220: LGTM!

The Empty component is correctly implemented with proper nesting of all elements. The migration enhances the user experience by providing a clear action to reset filters.

apps/dashboard/app/(app)/audit/components/table/audit-log-table-client.tsx (2)

5-5: LGTM!

Clean import of the new Empty component.


81-87: LGTM! Clean implementation of the Empty component.

The error state implementation is clear, actionable, and follows the new component structure correctly.

apps/dashboard/app/(app)/settings/vercel/client.tsx (1)

27-27: LGTM!

Clean import of the new Empty component.

internal/ui/src/components/empty.tsx Outdated Show resolved Hide resolved
@chronark
Copy link
Collaborator

chronark commented Jan 7, 2025

CleanShot 2025-01-07 at 20 52 54@2x
the colors do not match
left is the implementation, right is figma

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