Skip to content

refactor: system table cell uses new jobs#533

Merged
adityachoudhari26 merged 2 commits intomainfrom
refactor-system-cell
May 1, 2025
Merged

refactor: system table cell uses new jobs#533
adityachoudhari26 merged 2 commits intomainfrom
refactor-system-cell

Conversation

@adityachoudhari26
Copy link
Copy Markdown
Member

@adityachoudhari26 adityachoudhari26 commented May 1, 2025

Summary by CodeRabbit

  • Refactor

    • Simplified the deployment environment cell in the deployments table for a cleaner and more streamlined display.
    • Improved loading and empty states with clearer indicators and messaging.
    • Reduced complexity by consolidating data fetching and removing unnecessary UI elements such as dropdowns and approval dialogs.
  • New Features

    • Enhanced backend support for deployment environment cells with a new unified API endpoint, improving performance and reliability.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented May 1, 2025

Walkthrough

This change refactors the deployment environment cell rendering in the web application's deployment tables. The DeploymentEnvironmentCell component is simplified to accept only environmentId and a minimal deployment object, instead of full environment and workspace objects. Data fetching is consolidated into a single API query, and the UI is streamlined by removing complex conditional rendering and approval dialogs. Corresponding updates are made to the LazyDeploymentEnvironmentCell and its usage in deployment tables. On the backend, a new systemTableRouter with a cell procedure is introduced to serve the required data, and it is integrated into the main systemRouter.

Changes

File(s) Change Summary
apps/webservice/src/app/[workspaceSlug]/(app)/(deploy)/(raw)/systems/[systemSlug]/(sidebar)/deployments/TableDeployments.tsx
apps/webservice/src/app/[workspaceSlug]/(app)/(deploy)/(sidebar)/systems/_components/system-deployment-table/TableDeployments.tsx
Updated usage of LazyDeploymentEnvironmentCell to pass only environmentId (not the full environment object) and removed the workspace prop. Removed a wrapping <div> container with flex styling in the sidebar table version.
apps/webservice/src/app/[workspaceSlug]/(app)/(deploy)/_components/deployments/environment-cell/DeploymentEnvironmentCell.tsx Refactored DeploymentEnvironmentCell to use a single consolidated API query for deployment version and job status data. Simplified props to accept only environmentId and minimal deployment info (id and slug), removing full environment and workspace objects. Streamlined UI by removing approval dialogs, dropdowns, and complex conditional rendering. Added a reusable CellSkeleton component for loading states. Updated LazyDeploymentEnvironmentCell to use the new skeleton and adjusted container styling.
packages/api/src/router/system-table.ts Added new systemTableRouter with a protected procedure cell that accepts environmentId and deploymentId, performs authorization, and queries the database to return the latest deployment version info and aggregated job statuses for the specified environment and deployment.
packages/api/src/router/system.ts Integrated systemTableRouter as a new table route in the main systemRouter.

Sequence Diagram(s)

sequenceDiagram
    participant UI as DeploymentEnvironmentCell
    participant API as system.table.cell (tRPC)
    participant DB as Database

    UI->>API: Request cell data (environmentId, deploymentId)
    API->>DB: Query for deployment version and job statuses
    DB-->>API: Return deployment version and statuses
    API-->>UI: Respond with deployment version info and statuses
    UI->>UI: Render cell UI based on data
Loading

Suggested reviewers

  • jsbroks

Poem

In the garden of code, a cell is reborn,
With lighter props and queries shorn.
No more the weight of workspace lore,
Just IDs and slugs, and clutter no more.
The backend now answers in one swift hop,
As rabbits rejoice—less code, more hop! 🐇✨

✨ Finishing Touches
  • 📝 Generate Docstrings

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.
    • 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.

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

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 Markdown
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: 1

🧹 Nitpick comments (4)
apps/webservice/src/app/[workspaceSlug]/(app)/(deploy)/_components/deployments/environment-cell/DeploymentEnvironmentCell.tsx (4)

35-38: Remove debug console.log before merging

console.log(environmentId, deployment, systemSlug); will leak potentially sensitive identifiers to every browser console in production. It can also have a measurable performance cost when the table renders hundreds of cells.

-  console.log(environmentId, deployment, systemSlug);

44-48: Tiny optimisation: build URLs once

urls.workspace(workspaceSlug)… is re-executed on every render, even when only isLoading toggles. Wrapping it in useMemo keeps renders cheap on large tables.

-  const deploymentUrls = urls
-    .workspace(workspaceSlug)
-    .system(systemSlug)
-    .deployment(deployment.slug);
+  const deploymentUrls = React.useMemo(
+    () =>
+      urls
+        .workspace(workspaceSlug)
+        .system(systemSlug)
+        .deployment(deployment.slug),
+    [workspaceSlug, systemSlug, deployment.slug],
+  );

51-59: Clarify “No jobs” copy

“No jobs” could be mis-read as “no background jobs” instead of “no deployment runs”.
A slightly richer message reduces ambiguity and makes the link purpose clearer.

-        No jobs
+        No deployment runs

89-95: Accessibility: ensure focus outline is visible

The wrapper div sets fixed width/height but the child link relies on browser default focus styles, which can be clipped. Adding focus-visible:outline classes (Tailwind) keeps keyboard navigation usable.

-      <Link
+      <Link
+        className="focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2"
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 66b4037 and e243292.

📒 Files selected for processing (5)
  • apps/webservice/src/app/[workspaceSlug]/(app)/(deploy)/(raw)/systems/[systemSlug]/(sidebar)/deployments/TableDeployments.tsx (1 hunks)
  • apps/webservice/src/app/[workspaceSlug]/(app)/(deploy)/(sidebar)/systems/_components/system-deployment-table/TableDeployments.tsx (1 hunks)
  • apps/webservice/src/app/[workspaceSlug]/(app)/(deploy)/_components/deployments/environment-cell/DeploymentEnvironmentCell.tsx (2 hunks)
  • packages/api/src/router/system-table.ts (1 hunks)
  • packages/api/src/router/system.ts (2 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
`**/*.{ts,tsx}`: **Note on Error Handling:** Avoid strict enforcement of try/catch blocks. Code may use early returns, Promise chains (.then().catch()), or other patterns for error...

**/*.{ts,tsx}: Note on Error Handling:
Avoid strict enforcement of try/catch blocks. Code may use early returns, Promise chains (.then().catch()), or other patterns for error handling. These are acceptable as long as they maintain clarity and predictability.

  • packages/api/src/router/system.ts
  • apps/webservice/src/app/[workspaceSlug]/(app)/(deploy)/(raw)/systems/[systemSlug]/(sidebar)/deployments/TableDeployments.tsx
  • apps/webservice/src/app/[workspaceSlug]/(app)/(deploy)/(sidebar)/systems/_components/system-deployment-table/TableDeployments.tsx
  • packages/api/src/router/system-table.ts
  • apps/webservice/src/app/[workspaceSlug]/(app)/(deploy)/_components/deployments/environment-cell/DeploymentEnvironmentCell.tsx
🧬 Code Graph Analysis (2)
packages/api/src/router/system.ts (1)
packages/api/src/router/system-table.ts (1)
  • systemTableRouter (9-68)
packages/api/src/router/system-table.ts (3)
packages/api/src/trpc.ts (2)
  • createTRPCRouter (55-55)
  • protectedProcedure (173-173)
packages/db/src/schema/job.ts (1)
  • JobStatus (141-141)
packages/db/src/common.ts (1)
  • takeFirstOrNull (15-20)
🔇 Additional comments (7)
packages/api/src/router/system.ts (2)

39-39: Logical integration of the system table router.

The import for systemTableRouter is correctly added, preparing for its usage in the main system router.


319-319: Well-placed integration of the table router.

The systemTableRouter is properly integrated into the main system router under the table property, providing a clear namespace for table-related operations.

apps/webservice/src/app/[workspaceSlug]/(app)/(deploy)/(raw)/systems/[systemSlug]/(sidebar)/deployments/TableDeployments.tsx (1)

231-231: Simplified props passing.

The component now receives only the environment ID rather than the entire environment object, which is a more efficient approach for data passing. This change aligns with the broader refactoring to simplify the deployment environment cell components.

apps/webservice/src/app/[workspaceSlug]/(app)/(deploy)/(sidebar)/systems/_components/system-deployment-table/TableDeployments.tsx (1)

211-215: Streamlined component implementation.

The LazyDeploymentEnvironmentCell implementation has been properly refactored to:

  1. Remove unnecessary wrapper div
  2. Pass only the environment ID instead of the full environment object
  3. Remove the workspace prop entirely

This change aligns with the broader refactoring effort to simplify the component API and improve maintainability.

packages/api/src/router/system-table.ts (3)

1-8: Well-structured imports for the new router.

Imports are organized logically, with standard libraries first followed by internal imports. The necessary utilities and schema definitions are properly imported.


9-22: Well-defined router with proper permission checks.

The router is implemented correctly with:

  1. Clear input validation using zod
  2. Proper permission checks to ensure the user has access to the requested deployment
  3. Well-defined types for parameters

This provides a secure foundation for the API endpoint.


23-67: Efficient database query implementation.

The query implementation:

  1. Properly joins the necessary tables to fetch deployment-related data
  2. Uses SQL aggregation to collect job statuses in a single query
  3. Applies appropriate filtering based on input parameters
  4. Adds sorting to return the most recent version first
  5. Limits results to one record for efficiency
  6. Handles the null case with takeFirstOrNull

This consolidated query is a significant improvement over potentially multiple separate queries.

Comment on lines +39 to 43
const { data, isLoading } = api.system.table.cell.useQuery({
environmentId,
deploymentId: deployment.id,
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Surface query errors to avoid silent failures

useQuery exposes error / isError; if the request fails the UI stays in a perpetual loading skeleton or falls through to the “No jobs” branch, which can mask backend/permission issues.
Consider adding an explicit error state so users have feedback and you have telemetry.

-  const { data, isLoading } = api.system.table.cell.useQuery({
+  const { data, isLoading, isError, error } = api.system.table.cell.useQuery({
     environmentId,
     deploymentId: deployment.id,
   });
+
+  if (isError) {
+    return (
+      <div className="flex h-full w-full items-center justify-center text-destructive">
+        {error.message ?? "Failed to load"}
+      </div>
+    );
+  }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const { data, isLoading } = api.system.table.cell.useQuery({
environmentId,
deploymentId: deployment.id,
});
const { data, isLoading, isError, error } = api.system.table.cell.useQuery({
environmentId,
deploymentId: deployment.id,
});
if (isError) {
return (
<div className="flex h-full w-full items-center justify-center text-destructive">
{error.message ?? "Failed to load"}
</div>
);
}

Copy link
Copy Markdown
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

♻️ Duplicate comments (1)
apps/webservice/src/app/[workspaceSlug]/(app)/(deploy)/_components/deployments/environment-cell/DeploymentEnvironmentCell.tsx (1)

37-41: ⚠️ Potential issue

Surface query errors to avoid silent failures

The query implementation still doesn't handle error states, which could lead to silent failures where users see either a perpetual loading skeleton or "No jobs" message when there are actually permission or backend issues.

-  const { data, isLoading } = api.system.table.cell.useQuery({
+  const { data, isLoading, isError, error } = api.system.table.cell.useQuery({
     environmentId,
     deploymentId: deployment.id,
   });
+
+  if (isError) {
+    return (
+      <div className="flex h-full w-full items-center justify-center text-destructive">
+        {error.message ?? "Failed to load"}
+      </div>
+    );
+  }
🧹 Nitpick comments (3)
apps/webservice/src/app/[workspaceSlug]/(app)/(deploy)/_components/deployments/environment-cell/DeploymentEnvironmentCell.tsx (3)

74-76: Consider localization for date formatting

The date formatting is currently hardcoded with a specific format. For better internationalization support, consider using a localized date format approach.

- {format(data.versionCreatedAt, "MMM d, hh:mm aa")}
+ {format(data.versionCreatedAt, 
+   new Intl.DateTimeFormat(navigator.language, {
+     month: 'short',
+     day: 'numeric',
+     hour: 'numeric',
+     minute: 'numeric',
+     hour12: true
+   }).format(data.versionCreatedAt)
+ )}

Alternatively, if you're using a localization library throughout the application, consider integrating with that for consistency.


89-91: Use CSS variables for consistent dimensions

The hardcoded dimensions (h-[70px] and w-[220px]) could be extracted to CSS variables or theme constants for better maintainability and consistency across the application.

< <div
<   className="flex h-[70px] w-[220px] items-center justify-center"
<   ref={ref}
< >

This would make it easier to adjust these values globally if needed.


30-81: Add JSDoc documentation

Consider adding JSDoc documentation to the component to explain its purpose, usage, and the structure of the data it expects. This would help other developers understand how to use this component correctly.

+ /**
+  * DeploymentEnvironmentCell displays deployment status and version information for a specific environment.
+  * 
+  * @param {string} environmentId - The ID of the environment to display
+  * @param {Object} deployment - A minimal deployment object containing id and slug
+  * @param {string} systemSlug - The slug of the system this deployment belongs to
+  */
const DeploymentEnvironmentCell: React.FC<DeploymentEnvironmentCellProps> = ({
  environmentId,
  deployment,
  systemSlug,
}) => {
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e243292 and 674336c.

📒 Files selected for processing (1)
  • apps/webservice/src/app/[workspaceSlug]/(app)/(deploy)/_components/deployments/environment-cell/DeploymentEnvironmentCell.tsx (2 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
`**/*.{ts,tsx}`: **Note on Error Handling:** Avoid strict enforcement of try/catch blocks. Code may use early returns, Promise chains (.then().catch()), or other patterns for error...

**/*.{ts,tsx}: Note on Error Handling:
Avoid strict enforcement of try/catch blocks. Code may use early returns, Promise chains (.then().catch()), or other patterns for error handling. These are acceptable as long as they maintain clarity and predictability.

  • apps/webservice/src/app/[workspaceSlug]/(app)/(deploy)/_components/deployments/environment-cell/DeploymentEnvironmentCell.tsx
⏰ Context from checks skipped due to timeout of 90000ms (3)
  • GitHub Check: Typecheck
  • GitHub Check: Lint
  • GitHub Check: build (linux/amd64)
🔇 Additional comments (5)
apps/webservice/src/app/[workspaceSlug]/(app)/(deploy)/_components/deployments/environment-cell/DeploymentEnvironmentCell.tsx (5)

14-22: Well-structured skeleton component

The new CellSkeleton component is well-structured and provides appropriate visual feedback during loading. The component's extraction improves code reusability and maintains consistency.


24-34: Props simplification is a good improvement

The simplification of props to only require environmentId and a minimal deployment object is a good architecture decision that reduces unnecessary prop drilling and makes the component more focused and reusable.


35-36: Good use of route params instead of props

Using useParams to extract the workspaceSlug directly from the route is a better approach than passing it through props, reducing prop drilling and making the component less dependent on its parent.


61-80: Improved UI with clear visual hierarchy

The redesigned UI has a clearer visual hierarchy with the status icon, version tag, and formatted date. The component is now more focused on its primary responsibility of displaying deployment environment information.


47-59: Clean empty state handling

The empty state handling with a direct link to the releases page is clean and provides users with a clear path to find more information, which is a good UX improvement.

@adityachoudhari26 adityachoudhari26 merged commit f4b107c into main May 1, 2025
3 of 6 checks passed
@adityachoudhari26 adityachoudhari26 deleted the refactor-system-cell branch May 1, 2025 05:00
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.

1 participant