Skip to content

feat: add empty state #4026

Merged
Flo4604 merged 4 commits intomainfrom
project-details-empty-state
Sep 25, 2025
Merged

feat: add empty state #4026
Flo4604 merged 4 commits intomainfrom
project-details-empty-state

Conversation

@ogzhanolguncu
Copy link
Contributor

What does this PR do?

This PR adds proper empty state for project details. Project Details UI now properly transition between states.

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?

  • Create a project
  • Make a deploy
  • See project details render everything successfully
  • Make sure we first show empty state before the deployment, then refresh the UI make sure you first see skeletons then the data.
  • Stare into abyss

Checklist

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

@changeset-bot
Copy link

changeset-bot bot commented Sep 25, 2025

⚠️ No Changeset found

Latest commit: cdfd14e

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

@vercel
Copy link

vercel bot commented Sep 25, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
dashboard Ready Ready Preview Comment Sep 25, 2025 2:00pm
1 Skipped Deployment
Project Deployment Preview Comments Updated (UTC)
engineering Ignored Ignored Preview Sep 25, 2025 2:00pm

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 25, 2025

📝 Walkthrough

Walkthrough

Adds empty and skeleton UI states for active deployments and domains, makes deploymentId nullable across hooks and components, introduces loading control via useLiveQuery, tweaks layout/navigation behavior, adds a subtle-bounce keyframe, and adds an optional style prop to IconProps.

Changes

Cohort / File(s) Summary
Active Deployment Card
apps/dashboard/app/(app)/projects/[projectId]/details/active-deployment-card/active-deployment-card-empty.tsx, apps/dashboard/app/(app)/projects/[projectId]/details/active-deployment-card/hooks/use-deployment-logs.tsx, apps/dashboard/app/(app)/projects/[projectId]/details/active-deployment-card/index.tsx
Added ActiveDeploymentCardEmpty component; made `deploymentId: string
Project Page & Layout
apps/dashboard/app/(app)/projects/[projectId]/page.tsx, apps/dashboard/app/(app)/projects/[projectId]/layout.tsx, apps/dashboard/app/(app)/projects/[projectId]/navigations/project-navigation.tsx
Always-render sections (no early "No Project" return); domains use skeleton/empty states; active deployment passed as project?.liveDeploymentId ?? null; layout derives liveDeploymentId via useLiveQuery, adjusts tooltip/disabled/open logic; navigation adds a Separator after repo display.
Domain Rows
apps/dashboard/app/(app)/projects/[projectId]/details/domain-row.tsx
Added DomainRowSkeleton and DomainRowEmpty exports (additive); DomainRow unchanged.
Styling
apps/dashboard/styles/tailwind/tailwind.css
Added @keyframes subtle-bounce.
Icons
internal/icons/src/props.ts
Added optional style?: React.CSSProperties to IconProps.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant Page
  participant LiveQuery as useLiveQuery(projects)
  participant ActiveCard as ActiveDeploymentCard
  participant LogsHook as useDeploymentLogs

  Page->>LiveQuery: subscribe(projects)
  LiveQuery-->>Page: { project, isLoading }
  Page->>ActiveCard: deploymentId = project?.liveDeploymentId ?? null, isLoading

  alt isLoading
    ActiveCard->>ActiveCard: render Skeleton
  else if !deploymentId
    ActiveCard->>ActiveCard: render ActiveDeploymentCardEmpty
  else
    ActiveCard->>LogsHook: useDeploymentLogs(deploymentId)
    LogsHook-->>ActiveCard: logs stream
    ActiveCard->>ActiveCard: render active deployment UI
  end
Loading
sequenceDiagram
  autonumber
  participant Page
  participant DomainsQuery as useDomainsQuery
  participant DomainsUI as DomainsSection

  Page->>DomainsQuery: fetch domains
  DomainsQuery-->>Page: { domains, isLoading }

  alt isLoading
    Page->>DomainsUI: render DomainRowSkeleton (n rows)
  else if domains.length > 0
    Page->>DomainsUI: render DomainRow list
  else
    Page->>DomainsUI: render DomainRowEmpty
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • mcstepp
  • chronark
  • perkinsjr
  • Flo4604
  • MichaelUnkey

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings, 1 inconclusive)
Check name Status Explanation Resolution
Description Check ⚠️ Warning The pull request description follows the template structure with summary, type of change, testing instructions, and checklist sections but omits the required Fixes # line under the “What does this PR do?” heading. The placeholder for the issue reference remains, so it is unclear which issue this fixes. Additionally the type of change section marks all options, which is misleading. To comply with the template the issue number should be added and only relevant change types selected. Add the Fixes # line under the summary section, fill in or remove the issue placeholder, and update the type of change section to only check the applicable option(s) so the description fully adheres to the repository template.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Title Check ❓ Inconclusive The title uses a conventional commit prefix but is too generic because it does not specify what empty state is being added. Reviewers cannot immediately tell that the changes relate to project details and associated UI components. The title would be clearer with additional context. Consider updating the title to specify the scope of the change, for example: “feat: add empty state for project details” so reviewers can understand at a glance which UI component this applies to.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch project-details-empty-state

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.

@github-actions
Copy link
Contributor

github-actions bot commented Sep 25, 2025

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

@ogzhanolguncu ogzhanolguncu changed the title feat: add empty state feat: add empty state - Merge this after #4014 Sep 25, 2025
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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
apps/dashboard/app/(app)/projects/[projectId]/layout.tsx (1)

61-77: Tooltip won’t show on a disabled button. Wrap with a non-disabled element.

Disabled elements don’t receive pointer events; the tooltip won’t trigger. Wrap the Button to preserve the tooltip while keeping the button disabled.

Apply this diff:

-              <InfoTooltip
-                asChild
-                content={getTooltipContent()}
-                position={{
-                  side: "bottom",
-                  align: "end",
-                }}
-              >
-                <Button
-                  variant="ghost"
-                  className="size-7"
-                  disabled={!liveDeploymentId}
-                  onClick={() => setIsDetailsOpen(!isDetailsOpen)}
-                >
-                  <DoubleChevronLeft size="lg-medium" className="text-gray-13" />
-                </Button>
-              </InfoTooltip>
+              <InfoTooltip
+                asChild
+                content={getTooltipContent()}
+                position={{ side: "bottom", align: "end" }}
+              >
+                <span className="inline-flex" aria-disabled={!liveDeploymentId}>
+                  <Button
+                    variant="ghost"
+                    className="size-7"
+                    disabled={!liveDeploymentId}
+                    onClick={() => setIsDetailsOpen(!isDetailsOpen)}
+                  >
+                    <DoubleChevronLeft size="lg-medium" className="text-gray-13" />
+                  </Button>
+                </span>
+              </InfoTooltip>
apps/dashboard/app/(app)/projects/[projectId]/details/active-deployment-card/hooks/use-deployment-logs.tsx (1)

103-109: Fix runtime error: optional level can cause .includes on undefined.

log.level?.toLowerCase().includes(...) will call .includes on undefined. Coalesce or chain to avoid exceptions.

Apply this diff:

-      filtered = filtered.filter(
-        (log) =>
-          log.message.toLowerCase().includes(searchTerm.toLowerCase()) ||
-          log.timestamp.includes(searchTerm) ||
-          log.level?.toLowerCase().includes(searchTerm.toLowerCase()),
-      );
+      const term = searchTerm.toLowerCase();
+      filtered = filtered.filter(
+        (log) =>
+          log.message.toLowerCase().includes(term) ||
+          log.timestamp.includes(searchTerm) ||
+          (log.level ?? "").toLowerCase().includes(term),
+      );
🧹 Nitpick comments (8)
apps/dashboard/styles/tailwind/tailwind.css (1)

116-124: Expose the keyframes via a utility class (currently unused).

Define a utility so components can use animate-subtle-bounce without inline styles or Tailwind config changes.

Apply this diff to add a utility:

 @keyframes subtle-bounce {
   0%,
   100% {
     transform: translateY(0px);
   }
   50% {
     transform: translateY(-8px);
   }
 }
 
+@layer utilities {
+  .animate-subtle-bounce {
+    animation: subtle-bounce 2s ease-in-out infinite;
+  }
+}
apps/dashboard/app/(app)/projects/[projectId]/details/domain-row.tsx (1)

52-55: Prefer using the new subtle-bounce animation utility over inline style.

Switch to a class for consistency and to avoid inline styles.

Apply this diff:

-          <Link4
-            className="text-gray-9 size-6 group-hover:text-gray-11 transition-all duration-200 animate-pulse"
-            style={{ animationDuration: "2s" }}
-          />
+          <Link4
+            className="text-gray-9 size-6 group-hover:text-gray-11 transition-all duration-200 animate-subtle-bounce"
+          />
apps/dashboard/app/(app)/projects/[projectId]/details/active-deployment-card/index.tsx (2)

75-80: Guard the equality when deploymentId is null to avoid invalid comparisons.

Coalesce to a non-matching string to keep the query valid until an ID exists.

Apply this diff:

-  const { data, isLoading } = useLiveQuery(
-    (q) =>
-      q
-        .from({ deployment: collections.deployments })
-        .where(({ deployment }) => eq(deployment.id, deploymentId)),
-    [deploymentId],
-  );
+  const { data, isLoading } = useLiveQuery(
+    (q) =>
+      q
+        .from({ deployment: collections.deployments })
+        .where(({ deployment }) => eq(deployment.id, deploymentId ?? "")),
+    [deploymentId],
+  );

If eq supports null safely, feel free to keep it as-is; otherwise, this avoids throwing and yields an empty result.


118-123: Avoid forcing success text color on all statuses.

className="text-successA-11" conflicts with error/warning variants.

Apply this diff:

-          <Badge variant={statusConfig.variant} className="text-successA-11 font-medium">
+          <Badge variant={statusConfig.variant} className="font-medium">
apps/dashboard/app/(app)/projects/[projectId]/page.tsx (3)

2-3: Use collections.projects from context for consistency.

Avoid mixing collection and collections; keeps a single query client/source of truth.

Apply this diff:

-import { collection } from "@/lib/collections";
 import { eq, useLiveQuery } from "@tanstack/react-db";

15-17: Align projects query with context collections.

Use the same collections source you already consume below.

Apply this diff:

-  const projects = useLiveQuery((q) =>
-    q.from({ project: collection.projects }).where(({ project }) => eq(project.id, projectId)),
-  );
+  const projects = useLiveQuery((q) =>
+    q.from({ project: collections.projects }).where(({ project }) => eq(project.id, projectId)),
+  );

21-26: Coalesce nullable liveDeploymentId in the domains filter to avoid invalid comparisons.

Prevents passing undefined to eq, which may be unsupported.

Apply this diff:

   const { data: domains, isLoading: isDomainsLoading } = useLiveQuery(
     (q) =>
       q
         .from({ domain: collections.domains })
-        .where(({ domain }) => eq(domain.deploymentId, project?.liveDeploymentId)),
+        .where(({ domain }) => eq(domain.deploymentId, project?.liveDeploymentId ?? "")),
     [project?.liveDeploymentId],
   );

If eq gracefully handles undefined/null, this is optional; otherwise, this yields a safe empty result until an ID exists.

apps/dashboard/app/(app)/projects/[projectId]/details/active-deployment-card/active-deployment-card-empty.tsx (1)

23-55: Hide decorative icons from assistive tech.

All three icons here (Cloud, Plus, CodeBranch) are purely ornamental; right now they’ll surface to screen readers as nameless graphics, which adds noise to the empty state. Mark them as hidden so the meaningful copy is what gets announced.

Apply:

-          <Cloud
+          <Cloud
+            aria-hidden="true"
             className="text-gray-9 size-6 group-hover:text-gray-11 transition-all duration-200 animate-pulse"
             style={{ animationDuration: "2s" }}
           />
...
-        <Button onClick={onCreateDeployment} size="sm" className="mt-2 group/button">
-          <Plus className="size-4 mr-2 group-hover/button:rotate-90 transition-transform duration-200" />
+        <Button onClick={onCreateDeployment} size="sm" className="mt-2 group/button">
+          <Plus
+            aria-hidden="true"
+            className="size-4 mr-2 group-hover/button:rotate-90 transition-transform duration-200"
+          />
           Create deployment
         </Button>
...
-        <CodeBranch className="text-gray-7 size-3" />
+        <CodeBranch aria-hidden="true" className="text-gray-7 size-3" />
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7df1c17 and db64b60.

📒 Files selected for processing (9)
  • apps/dashboard/app/(app)/projects/[projectId]/details/active-deployment-card/active-deployment-card-empty.tsx (1 hunks)
  • apps/dashboard/app/(app)/projects/[projectId]/details/active-deployment-card/hooks/use-deployment-logs.tsx (2 hunks)
  • apps/dashboard/app/(app)/projects/[projectId]/details/active-deployment-card/index.tsx (3 hunks)
  • apps/dashboard/app/(app)/projects/[projectId]/details/domain-row.tsx (2 hunks)
  • apps/dashboard/app/(app)/projects/[projectId]/layout.tsx (5 hunks)
  • apps/dashboard/app/(app)/projects/[projectId]/navigations/project-navigation.tsx (1 hunks)
  • apps/dashboard/app/(app)/projects/[projectId]/page.tsx (3 hunks)
  • apps/dashboard/styles/tailwind/tailwind.css (1 hunks)
  • internal/icons/src/props.ts (1 hunks)
🧰 Additional context used
🧠 Learnings (3)
📚 Learning: 2025-07-28T19:42:37.047Z
Learnt from: mcstepp
PR: unkeyed/unkey#3662
File: apps/dashboard/app/(app)/projects/page.tsx:74-81
Timestamp: 2025-07-28T19:42:37.047Z
Learning: In apps/dashboard/app/(app)/projects/page.tsx, the user mcstepp prefers to keep placeholder functions like generateSlug inline during POC/demonstration phases rather than extracting them to utility modules, with plans to refactor later when the feature matures beyond the proof-of-concept stage.

Applied to files:

  • apps/dashboard/app/(app)/projects/[projectId]/page.tsx
📚 Learning: 2025-07-28T20:38:53.244Z
Learnt from: mcstepp
PR: unkeyed/unkey#3662
File: apps/dashboard/app/(app)/projects/[projectId]/diff/[...compare]/components/client.tsx:322-341
Timestamp: 2025-07-28T20:38:53.244Z
Learning: In apps/dashboard/app/(app)/projects/[projectId]/diff/[...compare]/components/client.tsx, mcstepp prefers to keep hardcoded endpoint logic in the getDiffType function during POC phases for demonstrating diff functionality, rather than implementing a generic diff algorithm. This follows the pattern of keeping simplified implementations for demonstration purposes.

Applied to files:

  • apps/dashboard/app/(app)/projects/[projectId]/layout.tsx
📚 Learning: 2025-09-19T12:43:46.746Z
Learnt from: ogzhanolguncu
PR: unkeyed/unkey#4000
File: apps/dashboard/lib/collections/index.ts:92-99
Timestamp: 2025-09-19T12:43:46.746Z
Learning: In the dashboard codebase, useLiveQuery hooks have mixed invalidation behavior - some automatically invalidate when collections change, while others are memoized and require explicit collection properties in their deps arrays. Not all useLiveQuery calls need collection dependencies added.

Applied to files:

  • apps/dashboard/app/(app)/projects/[projectId]/layout.tsx
🧬 Code graph analysis (7)
apps/dashboard/app/(app)/projects/[projectId]/details/active-deployment-card/active-deployment-card-empty.tsx (3)
internal/icons/src/icons/cloud.tsx (1)
  • Cloud (15-38)
internal/icons/src/icons/plus.tsx (1)
  • Plus (16-52)
internal/icons/src/icons/code-branch.tsx (1)
  • CodeBranch (15-41)
apps/dashboard/app/(app)/projects/[projectId]/details/active-deployment-card/hooks/use-deployment-logs.tsx (1)
apps/dashboard/lib/trpc/server.ts (1)
  • trpc (7-14)
apps/dashboard/app/(app)/projects/[projectId]/navigations/project-navigation.tsx (2)
internal/icons/src/icons/refresh-3.tsx (1)
  • Refresh3 (15-46)
apps/dashboard/app/(app)/projects/_components/list/repo-display.tsx (1)
  • RepoDisplay (12-34)
apps/dashboard/app/(app)/projects/[projectId]/details/active-deployment-card/index.tsx (3)
apps/dashboard/app/(app)/projects/[projectId]/layout-provider.tsx (1)
  • useProjectLayout (13-19)
apps/dashboard/app/(app)/projects/[projectId]/details/active-deployment-card/skeleton.tsx (1)
  • ActiveDeploymentCardSkeleton (6-66)
apps/dashboard/app/(app)/projects/[projectId]/details/active-deployment-card/active-deployment-card-empty.tsx (1)
  • ActiveDeploymentCardEmpty (10-60)
apps/dashboard/app/(app)/projects/[projectId]/details/domain-row.tsx (2)
internal/icons/src/icons/link-4.tsx (1)
  • Link4 (16-45)
internal/icons/src/icons/share-up-right.tsx (1)
  • ShareUpRight (15-56)
apps/dashboard/app/(app)/projects/[projectId]/page.tsx (3)
internal/db/src/schema/domains.ts (1)
  • domains (4-36)
apps/dashboard/app/(app)/projects/[projectId]/details/active-deployment-card/index.tsx (1)
  • ActiveDeploymentCard (72-278)
apps/dashboard/app/(app)/projects/[projectId]/details/domain-row.tsx (3)
  • DomainRowSkeleton (25-39)
  • DomainRow (9-23)
  • DomainRowEmpty (41-67)
apps/dashboard/app/(app)/projects/[projectId]/layout.tsx (2)
apps/dashboard/lib/collections/deploy/projects.ts (1)
  • projects (42-108)
internal/db/src/schema/projects.ts (1)
  • projects (8-31)
⏰ 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). (6)
  • GitHub Check: Test Packages / Test
  • GitHub Check: Test Go API Local / Test
  • GitHub Check: Build / Build
  • GitHub Check: Test API / API Test Local
  • GitHub Check: Vercel Agent Review
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (4)
apps/dashboard/app/(app)/projects/[projectId]/navigations/project-navigation.tsx (1)

78-87: Nice fragment swap to accommodate the separator.

Returning a fragment keeps the flex layout clean while letting the repo pill and separator sit side‑by‑side without an extra wrapper. The updated styling on RepoDisplay reads well too.

internal/icons/src/props.ts (1)

36-37: LGTM: Adding style to IconProps is appropriate.

Enables inline styles to flow to the SVG via props spreading. No concerns.

apps/dashboard/app/(app)/projects/[projectId]/page.tsx (2)

36-42: Nice: active deployment always rendered with empty/loading states.

Clear UX progression: skeleton → empty → data.


49-58: Good domain list state handling.

Skeletons while loading, rows when present, and an empty state fallback are well-structured.

@ogzhanolguncu ogzhanolguncu changed the title feat: add empty state - Merge this after #4014 feat: add empty state Sep 25, 2025
@coderabbitai coderabbitai bot added the UI label Sep 25, 2025
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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/dashboard/app/(app)/projects/[projectId]/details/active-deployment-card/index.tsx (1)

127-133: Badge text color is hard-coded to success

The text color remains success for warning/error variants.

-          <Badge variant={statusConfig.variant} className="text-successA-11 font-medium">
+          <Badge
+            variant={statusConfig.variant}
+            className={cn(
+              "font-medium",
+              statusConfig.variant === "success"
+                ? "text-successA-11"
+                : statusConfig.variant === "warning"
+                  ? "text-warningA-11"
+                  : "text-errorA-11",
+            )}
+          >
🧹 Nitpick comments (3)
apps/dashboard/app/(app)/projects/[projectId]/details/active-deployment-card/hooks/use-deployment-logs.tsx (1)

65-71: Avoid passing a sentinel "" to the TRPC query input

Rely on enabled + a type assertion instead of sending an empty string; also disable refetch-on-focus for parity with gateway logs.

-      // without this check TS yells at us
-      deploymentId: deploymentId ?? "",
+      // safe: guarded by `enabled`
+      deploymentId: deploymentId as string,
     },
     {
-      enabled: showBuildSteps && isExpanded && Boolean(deploymentId),
+      enabled: showBuildSteps && isExpanded && Boolean(deploymentId),
       refetchInterval: BUILD_STEPS_REFETCH_INTERVAL,
+      refetchOnWindowFocus: false,
     },
apps/dashboard/app/(app)/projects/[projectId]/details/active-deployment-card/index.tsx (2)

77-83: Null passed to eq(): verify library semantics

Passing a possible null into eq(...) can be unsafe depending on @tanstack/react-db’s typing/behavior (it may generate = null or error). If eq doesn’t accept null, coerce to a sentinel or gate the comparison.

If eq rejects null, minimally:

-        .where(({ deployment }) => eq(deployment.id, deploymentId)),
+        .where(({ deployment }) => eq(deployment.id, deploymentId ?? "__none__")),

Or, if the API supports it, prefer an “always false” predicate when deploymentId is null.


255-258: Use a stable key for log rows

Index-based keys cause unnecessary re-renders on filter/sort. Use log.id.

-                  {filteredLogs.map((log, index) => (
+                  {filteredLogs.map((log) => (
                     <div
-                      key={`${log.message}-${index}`}
+                      key={log.id}
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7fa3855 and cdfd14e.

📒 Files selected for processing (3)
  • apps/dashboard/app/(app)/projects/[projectId]/details/active-deployment-card/hooks/use-deployment-logs.tsx (2 hunks)
  • apps/dashboard/app/(app)/projects/[projectId]/details/active-deployment-card/index.tsx (3 hunks)
  • apps/dashboard/app/(app)/projects/[projectId]/details/domain-row.tsx (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/dashboard/app/(app)/projects/[projectId]/details/domain-row.tsx
🧰 Additional context used
🧬 Code graph analysis (1)
apps/dashboard/app/(app)/projects/[projectId]/details/active-deployment-card/index.tsx (3)
apps/dashboard/app/(app)/projects/[projectId]/layout-provider.tsx (1)
  • useProjectLayout (13-19)
apps/dashboard/app/(app)/projects/[projectId]/details/active-deployment-card/skeleton.tsx (1)
  • ActiveDeploymentCardSkeleton (6-66)
apps/dashboard/app/(app)/projects/[projectId]/details/active-deployment-card/active-deployment-card-empty.tsx (1)
  • ActiveDeploymentCardEmpty (10-48)
🔇 Additional comments (4)
apps/dashboard/app/(app)/projects/[projectId]/details/active-deployment-card/hooks/use-deployment-logs.tsx (1)

25-28: Prop now allows null deploymentId — good change

This aligns the hook with the new empty-state flow.

apps/dashboard/app/(app)/projects/[projectId]/details/active-deployment-card/index.tsx (3)

21-21: Empty-state import looks good

Import location and usage are consistent.


72-73: Prop accepts null deploymentId — good

Matches upstream nullable flow.


107-113: Loading → Empty fallback flow is correct

Skeleton while live query loads, then empty UI when no deployment.

@chronark
Copy link
Collaborator

@Flo4604 @perkinsjr @mcstepp we need one more please

@chronark chronark enabled auto-merge September 25, 2025 14:39
@chronark chronark added this pull request to the merge queue Sep 25, 2025
@graphite-app
Copy link

graphite-app bot commented Sep 25, 2025

Video gif. A toddler sits at a table with a cracker in her hands. She looks at us with a big excited smile and then grins while giving a big thumbs up. Text, “Thank you!” (Added via Giphy)

@graphite-app
Copy link

graphite-app bot commented Sep 25, 2025

Graphite Automations

"Post a GIF when PR approved" took an action on this PR • (09/25/25)

1 gif was posted to this PR based on Andreas Thomas's automation.

@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Sep 25, 2025
@Flo4604 Flo4604 added this pull request to the merge queue Sep 25, 2025
Merged via the queue into main with commit c0242db Sep 25, 2025
17 checks passed
@Flo4604 Flo4604 deleted the project-details-empty-state branch September 25, 2025 15:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants