Skip to content

Refactor connections list with hosted PostgreSQL banner#1685

Merged
lyubov-voloshko merged 8 commits intorocket-admin:mainfrom
karinakharchenko:connection-list-hosted-postgresql
Mar 26, 2026
Merged

Refactor connections list with hosted PostgreSQL banner#1685
lyubov-voloshko merged 8 commits intorocket-admin:mainfrom
karinakharchenko:connection-list-hosted-postgresql

Conversation

@karinakharchenko
Copy link
Copy Markdown
Contributor

@karinakharchenko karinakharchenko commented Mar 24, 2026

Summary

  • Separate hosted PostgreSQL into a standalone full-width banner with indigo gradient, icon and "Recommended" badge
  • Move DB type cards into a responsive grid with section label "CONNECT YOUR OWN"
  • Update demo panels to 3-column grid with section label "EXPLORE DEMO PANELS"
  • Add light/dark theme variants for the hosted banner gradient
  • Improve mobile layout for the banner

Test plan

  • Verify hosted banner displays correctly in light and dark themes
  • Check DB grid is responsive and cards are equal height
  • Verify demo cards show 3 per row
  • Test mobile layout for all sections
  • Verify hosted PostgreSQL creation flow still works

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Style
    • Refreshed layout and styling across connections pages: new card/grid presentation, updated label styling, rounded cards, tighter gaps, hover/active/arrow transitions, and improved dark-mode visuals.
    • Improved responsive behavior: desktop three-column grid and single-column mobile layout; refined empty-state and banner typography and spacing.
  • Refactor
    • Simplified and standardized templates for connection lists, banners, FABs and action buttons with clearer iteration, explicit tracking and conditional rendering.
  • Tests
    • Updated specs to assert the presence of the renamed hosted-CTA using the new test selector.

karinakharchenko and others added 2 commits March 24, 2026 12:07
… and demo sections

Split the connections page into three visually distinct sections:
- Hosted PostgreSQL as a standalone banner with gradient card
- Connect your own as a responsive DB grid
- Demo panels as a 3-column grid with section labels

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add separate dark mode gradient to keep the deep tones, while using
a brighter indigo palette for light theme.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings March 24, 2026 10:17
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 24, 2026

Caution

Review failed

Pull request was closed or merged during review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 6ba46e58-e888-4416-8cfa-c405e84e96ca

📥 Commits

Reviewing files that changed from the base of the PR and between 3c15bdc and 8408fa5.

📒 Files selected for processing (1)
  • frontend/src/app/components/connections-list/own-connections/own-connections.component.spec.ts
✅ Files skipped from review due to trivial changes (1)
  • frontend/src/app/components/connections-list/own-connections/own-connections.component.spec.ts

📝 Walkthrough

Walkthrough

Replaces many CSS classes and restructures demo/own connections templates from Angular structural directives (*ngIf/*ngFor) to control-flow (@if/@for) with explicit tracking; introduces new layout primitives (.demoGrid/.demoCard, .dbGrid/.dbCard, .section__label, .hosted-banner) and adjusts responsive/dark-mode styling.

Changes

Cohort / File(s) Summary
Demo Connections (template + styles)
frontend/src/app/components/connections-list/demo-connections/demo-connections.component.html, frontend/src/app/components/connections-list/demo-connections/demo-connections.component.css
Template: *ngIf/*ngFor@if/@for with explicit track. Markup class names updated. Styles: removed .testConnections/.testConnectionLink* → added .section__label, .demoGrid, .demoCard and sub-elements; grid changed 4→3 cols (1 col ≤600px), smaller gaps, new padding/border-radius, centralized hover/active, arrow opacity transition and dark-mode retargeting.
Own Connections (template + styles)
frontend/src/app/components/connections-list/own-connections/own-connections.component.html, frontend/src/app/components/connections-list/own-connections/own-connections.component.css
Templates: structural directives → control-flow (@if/@for), conditional headers for roles, moved FAB rendering into connections block, updated data-testid in tests. Styles: replaced empty-state and .addConnectionLink* patterns with .section/.section__label, .hosted-banner, .dbGrid/.dbCard; added banner/hosted card styles, responsive FAB rules, dark-mode backgrounds/borders, spacing adjustments and normalized transitions.
Specs
frontend/src/app/components/connections-list/own-connections/own-connections.component.spec.ts
Updated test selectors for hosted-button from [data-testid="create-hosted-database-empty-button"][data-testid="create-hosted-database-button"] only (DOM query target change).

Sequence Diagram(s)

(omitted)

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • Fix internal hosting #1682: Touches own-connections.component.css and .fabActions styling—likely overlaps with FAB/layout changes in this PR.

Poem

🐰 I hopped through classes, nibbling old and new,

Swapped tiles to three and tuned the midnight hue,
Templates now whisper @if and hum @for,
Cards glow on hover, arrows peek and soar,
A tiny rabbit hops—build fresh, swift, and true 🥕✨

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main refactoring focus: extracting hosted PostgreSQL into a banner and refactoring the connections list layout. It covers the primary changes evident across all modified files.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Security Check ✅ Passed This PR is a UI/UX refactoring that does not introduce new security vulnerabilities. Angular's built-in URL sanitization protects against XSS attacks.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@CLAassistant
Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR refactors the Connections List UI to promote the hosted PostgreSQL option as a standalone banner and reorganizes “connect your own” + demo connections into grid-based sections for improved responsiveness and theming.

Changes:

  • Introduces a full-width “Hosted PostgreSQL” banner section (light/dark gradient + “Recommended” badge).
  • Moves supported DB types into a responsive “CONNECT YOUR OWN” grid.
  • Updates demo connections into a 3-column grid with a section label.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.

File Description
frontend/src/app/components/connections-list/own-connections/own-connections.component.html Reorders layout into sections, adds hosted banner + DB grid, updates connection list rendering to new control-flow syntax.
frontend/src/app/components/connections-list/own-connections/own-connections.component.css Adds styling for section labels, hosted banner, DB grid/cards; reorganizes existing styles to match new layout.
frontend/src/app/components/connections-list/demo-connections/demo-connections.component.html Converts demo connections list into a grid layout and changes heading/label rendering.
frontend/src/app/components/connections-list/demo-connections/demo-connections.component.css Adds grid/card styles for the new demo layout and introduces a local section__label style.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

alt="Rocketadmin connection">
}
<div class="connectionInfo">
<h2 class="connectionInfo__connectionTitle">{{ $any(connectionItem).displayTitle }}</h2>
Copy link

Copilot AI Mar 24, 2026

Choose a reason for hiding this comment

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

Using $any(connectionItem).displayTitle bypasses template type-checking. Since displayTitle is a known UI field added in the connections flow, consider updating the connections input type to a view-model interface that includes displayTitle (or extend ConnectionItem) so the template can stay type-safe without $any.

Suggested change
<h2 class="connectionInfo__connectionTitle">{{ $any(connectionItem).displayTitle }}</h2>
<h2 class="connectionInfo__connectionTitle">{{ connectionItem.displayTitle }}</h2>

Copilot uses AI. Check for mistakes.
Comment on lines +19 to +21
<div class="demoCard__info">
<strong>{{ $any(testConnectionItem).displayTitle }}</strong>
<span class="demoCard__type">{{ testDatabasesNames[testConnectionItem.connection.type] }}</span>
Copy link

Copilot AI Mar 24, 2026

Choose a reason for hiding this comment

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

$any(testConnectionItem).displayTitle disables template type-checking. Consider changing testConnections to a typed view-model that includes displayTitle (or extend ConnectionItem) so this stays type-safe.

Copilot uses AI. Check for mistakes.
color="primary"
class="fabHostedButton"
class="hosted-banner"
data-testid="create-hosted-database-button"
Copy link

Copilot AI Mar 24, 2026

Choose a reason for hiding this comment

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

The hosted DB CTA test selector changed: unit tests still query for data-testid="create-hosted-database-empty-button" (see own-connections.component.spec.ts). Either keep the previous data-testid as an alias on this button, or update the tests to the new selector to avoid CI failures.

Suggested change
data-testid="create-hosted-database-button"
data-testid="create-hosted-database-empty-button"
data-testid-new="create-hosted-database-button"

Copilot uses AI. Check for mistakes.
Comment on lines +99 to +110
@if (showHostedDatabaseEntry) {
<button
mat-stroked-button
type="button"
color="primary"
class="fabHostedButton"
data-testid="create-hosted-database-fab-button"
[disabled]="creatingHostedDatabase()"
(click)="createHostedDatabase()">
<mat-icon>cloud_queue</mat-icon>
{{ creatingHostedDatabase() ? 'Creating...' : 'Create hosted PostgreSQL' }}
</button>
Copy link

Copilot AI Mar 24, 2026

Choose a reason for hiding this comment

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

When showHostedDatabaseEntry is true and there are existing connections, the UI will render two CTAs that both call createHostedDatabase() (the full-width hosted banner and this FAB button). This duplication can confuse users and makes analytics/QA harder; consider showing only one (e.g., hide the FAB hosted button when the banner is present, or restrict the FAB to mobile-only via an explicit condition).

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown

@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

🧹 Nitpick comments (5)
frontend/src/app/components/connections-list/own-connections/own-connections.component.html (2)

75-75: Consider using index for tracking if database order may change.

The track supportedDatabase expression works by tracking the string value directly. This is fine if supportedOrderedDatabases is a static list, but if items could be reordered dynamically, consider using track $index or a stable identifier property for optimal change detection.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@frontend/src/app/components/connections-list/own-connections/own-connections.component.html`
at line 75, The current ngFor uses "track supportedDatabase" which tracks by the
string value and may mis-handle reorderings; update the ngFor in
own-connections.component.html to track by a stable identifier or index
instead—e.g. use "track $index" if order changes frequently or use a unique
property on each item (e.g. supportedDatabase.id or supportedDatabase.key) so
change detection in the loop over supportedOrderedDatabases correctly preserves
item identity; locate the template line containing "for (supportedDatabase of
supportedOrderedDatabases; track supportedDatabase)" and replace the track
expression accordingly.

20-21: Update type interfaces to include connection_properties and displayTitle properties for compile-time type checking.

The $any() casts for connection_properties?.logo_url (lines 20-21) and displayTitle (line 30) indicate these properties aren't defined in the type interfaces. The connection_properties object is returned by the backend API but not typed in the Connection interface, and displayTitle is dynamically added by the service layer but not declared in the ConnectionItem interface. Consider updating these interfaces to include these properties and remove the $any() casts.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@frontend/src/app/components/connections-list/own-connections/own-connections.component.html`
around lines 20 - 21, Update the TypeScript interfaces to declare the missing
properties so you can remove the $any() casts: add a connection_properties field
(e.g. connection_properties?: { logo_url?: string; /* add other backend fields
*/ }) to the Connection interface and add displayTitle?: string to the
ConnectionItem interface (or the exact type that stores items returned to the
component); also update the service method that assigns displayTitle to return
the properly typed ConnectionItem so the template can reference displayTitle and
connection_properties.logo_url without using $any().
frontend/src/app/components/connections-list/own-connections/own-connections.component.css (1)

356-356: Avoid using !important for height.

Using !important on line 356 (and line 362) can make future maintenance difficult. If this is needed to override Material button styles, consider using a more specific selector instead.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@frontend/src/app/components/connections-list/own-connections/own-connections.component.css`
at line 356, The CSS rule in own-connections component uses height: 48px
!important which should be replaced by a more specific selector instead of using
!important; locate the selector applied (the rule currently forcing height: 48px
on the button within OwnConnectionsComponent) and remove the !important, then
increase selector specificity (for example target the component host and the
exact Material button classes such as .own-connections-component
.mat-button.mat-flat-button or a custom wrapper class) so the height: 48px
applies without !important and keeps Material styles overridden only for this
component.
frontend/src/app/components/connections-list/demo-connections/demo-connections.component.css (1)

7-15: Consider extracting shared .section__label styles.

The .section__label styling is duplicated between this file and own-connections.component.css. If these components share a parent module or can access shared styles, consider extracting this to a common stylesheet to maintain DRY principles.

Also applies to: 20-28

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@frontend/src/app/components/connections-list/demo-connections/demo-connections.component.css`
around lines 7 - 15, The .section__label rule is duplicated between
demo-connections and own-connections; extract this selector into a shared
stylesheet (e.g., a module-level or global shared CSS/SCSS file) and import that
shared file into both components so they reuse the single definition; remove the
duplicate .section__label blocks from demo-connections.component.css and
own-connections.component.css and verify the selector and properties (font-size,
font-weight, letter-spacing, text-transform, opacity, margin-bottom) are
preserved and still apply without changing specificity.
frontend/src/app/components/connections-list/demo-connections/demo-connections.component.html (1)

20-20: Add displayTitle property to the ConnectionItem interface for proper type safety.

The displayTitle property is added at runtime in connections.service.ts but is not defined in the ConnectionItem interface, which is why $any() is required here. Update the interface to include displayTitle: string to enable proper type checking in the template.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@frontend/src/app/components/connections-list/demo-connections/demo-connections.component.html`
at line 20, The template uses testConnectionItem.displayTitle but the
ConnectionItem interface lacks that property, forcing the template to use
$any(); add displayTitle: string to the ConnectionItem interface declaration so
the runtime-added property from connections.service.ts is reflected in types,
then remove the need for $any() in demo-connections.component.html; update the
interface (symbol: ConnectionItem) and ensure any factory/mapper in
connections.service.ts that sets displayTitle still produces a string.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@frontend/src/app/components/connections-list/own-connections/own-connections.component.css`:
- Line 160: Replace the deprecated CSS property grid-gap with the standard gap
in the same rule: locate the declaration "grid-gap: 20px;" and change it to
"gap: 20px;" (remove any duplicate/older grid-gap entries) so the layout uses
the modern gap property.
- Around line 42-46: The background shorthand is currently declared after
background-clip in own-connections.component.css which resets background-clip;
move the background-clip: padding-box declaration to come after the background:
... declaration (i.e., ensure background-clip appears below the background
shorthand) so the padding-box value isn't overridden.

---

Nitpick comments:
In
`@frontend/src/app/components/connections-list/demo-connections/demo-connections.component.css`:
- Around line 7-15: The .section__label rule is duplicated between
demo-connections and own-connections; extract this selector into a shared
stylesheet (e.g., a module-level or global shared CSS/SCSS file) and import that
shared file into both components so they reuse the single definition; remove the
duplicate .section__label blocks from demo-connections.component.css and
own-connections.component.css and verify the selector and properties (font-size,
font-weight, letter-spacing, text-transform, opacity, margin-bottom) are
preserved and still apply without changing specificity.

In
`@frontend/src/app/components/connections-list/demo-connections/demo-connections.component.html`:
- Line 20: The template uses testConnectionItem.displayTitle but the
ConnectionItem interface lacks that property, forcing the template to use
$any(); add displayTitle: string to the ConnectionItem interface declaration so
the runtime-added property from connections.service.ts is reflected in types,
then remove the need for $any() in demo-connections.component.html; update the
interface (symbol: ConnectionItem) and ensure any factory/mapper in
connections.service.ts that sets displayTitle still produces a string.

In
`@frontend/src/app/components/connections-list/own-connections/own-connections.component.css`:
- Line 356: The CSS rule in own-connections component uses height: 48px
!important which should be replaced by a more specific selector instead of using
!important; locate the selector applied (the rule currently forcing height: 48px
on the button within OwnConnectionsComponent) and remove the !important, then
increase selector specificity (for example target the component host and the
exact Material button classes such as .own-connections-component
.mat-button.mat-flat-button or a custom wrapper class) so the height: 48px
applies without !important and keeps Material styles overridden only for this
component.

In
`@frontend/src/app/components/connections-list/own-connections/own-connections.component.html`:
- Line 75: The current ngFor uses "track supportedDatabase" which tracks by the
string value and may mis-handle reorderings; update the ngFor in
own-connections.component.html to track by a stable identifier or index
instead—e.g. use "track $index" if order changes frequently or use a unique
property on each item (e.g. supportedDatabase.id or supportedDatabase.key) so
change detection in the loop over supportedOrderedDatabases correctly preserves
item identity; locate the template line containing "for (supportedDatabase of
supportedOrderedDatabases; track supportedDatabase)" and replace the track
expression accordingly.
- Around line 20-21: Update the TypeScript interfaces to declare the missing
properties so you can remove the $any() casts: add a connection_properties field
(e.g. connection_properties?: { logo_url?: string; /* add other backend fields
*/ }) to the Connection interface and add displayTitle?: string to the
ConnectionItem interface (or the exact type that stores items returned to the
component); also update the service method that assigns displayTitle to return
the properly typed ConnectionItem so the template can reference displayTitle and
connection_properties.logo_url without using $any().

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 5820d8f6-48f4-4fe7-a9dd-2a5428af412b

📥 Commits

Reviewing files that changed from the base of the PR and between c021a6e and d4f316a.

📒 Files selected for processing (4)
  • frontend/src/app/components/connections-list/demo-connections/demo-connections.component.css
  • frontend/src/app/components/connections-list/demo-connections/demo-connections.component.html
  • frontend/src/app/components/connections-list/own-connections/own-connections.component.css
  • frontend/src/app/components/connections-list/own-connections/own-connections.component.html

display: grid;
grid-template-columns: repeat(auto-fit, minmax(142px, 1fr));
align-items: stretch;
grid-gap: 20px;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Replace deprecated grid-gap with gap.

The grid-gap property is deprecated. Use the standard gap property instead for better forward compatibility.

🔧 Proposed fix
 .dbGrid {
 	list-style: none;
 	display: grid;
 	grid-template-columns: repeat(auto-fit, minmax(142px, 1fr));
 	align-items: stretch;
-	grid-gap: 20px;
+	gap: 20px;
 	width: 100%;
🧰 Tools
🪛 Stylelint (17.4.0)

[error] 160-160: Expected "grid-gap" to be "gap" (property-no-deprecated)

(property-no-deprecated)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@frontend/src/app/components/connections-list/own-connections/own-connections.component.css`
at line 160, Replace the deprecated CSS property grid-gap with the standard gap
in the same rule: locate the declaration "grid-gap: 20px;" and change it to
"gap: 20px;" (remove any duplicate/older grid-gap entries) so the layout uses
the modern gap property.

Copy link
Copy Markdown

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

🧹 Nitpick comments (5)
frontend/src/app/components/connections-list/demo-connections/demo-connections.component.html (1)

20-20: Consider adding displayTitle to the ConnectionItem type definition.

Using $any() to access displayTitle bypasses TypeScript's type checking. If displayTitle is a computed or enriched property, consider extending the ConnectionItem interface or creating a view model type that includes it. This would improve type safety and IDE support.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@frontend/src/app/components/connections-list/demo-connections/demo-connections.component.html`
at line 20, The template uses $any(testConnectionItem).displayTitle which
bypasses TypeScript; add displayTitle to the ConnectionItem type (or create a
ConnectionViewModel type) and update the component to expose items typed as
ConnectionItem | ConnectionViewModel so the template can bind to
testConnectionItem.displayTitle without $any; specifically modify the
ConnectionItem interface (or add a new interface) to include displayTitle
(string) and adjust any mapping logic in the component class that produces
testConnectionItem to populate this field.
frontend/src/app/components/connections-list/own-connections/own-connections.component.css (2)

350-363: Verify !important necessity for Material button height overrides.

The height: 48px !important declarations on .fabAddButton and .fabHostedButton are likely needed to override Angular Material's default button heights. This is acceptable, but consider documenting why !important is required here (e.g., via a CSS comment) for future maintainability.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@frontend/src/app/components/connections-list/own-connections/own-connections.component.css`
around lines 350 - 363, Add a brief CSS comment above the .fabAddButton and
.fabHostedButton rules explaining why height: 48px !important is required (e.g.,
to override Angular Material button min-height/line-height defaults for this
FAB-style button) so future maintainers understand the override; keep the
!important in .fabAddButton and .fabHostedButton and ensure the comment
references the selectors .fabAddButton and .fabHostedButton and mentions Angular
Material as the source of the competing styles.

400-406: Consider reducing !important usage if possible.

Multiple !important declarations on .empty-state__text suggest conflicts with Material typography classes. If these overrides are necessary due to Material's specificity, this is acceptable. Otherwise, consider increasing selector specificity instead.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@frontend/src/app/components/connections-list/own-connections/own-connections.component.css`
around lines 400 - 406, The CSS rule for .empty-state__text uses multiple
!important flags which likely mask Material typography and create maintenance
issues; remove unnecessary !important declarations and instead increase selector
specificity (e.g., scope it under the component root class or use the
component's host selector such as .own-connections .empty-state__text) or move
the declaration to a stylesheet loaded after Material so it naturally overrides
the library styles; keep !important only if after testing you confirm
specificity cannot be resolved without it.
frontend/src/app/components/connections-list/own-connections/own-connections.component.html (2)

5-5: Consider extracting the admin role check to a component property.

The role check currentUser?.role === 'ADMIN' || currentUser?.role === 'DB_ADMIN' appears at lines 5 and 112. Consider extracting this to a getter or computed property (e.g., isAdminUser) for better maintainability and to ensure consistency if the role logic changes.

get isAdminUser(): boolean {
  return this.currentUser?.role === 'ADMIN' || this.currentUser?.role === 'DB_ADMIN';
}

Also applies to: 112-112

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@frontend/src/app/components/connections-list/own-connections/own-connections.component.html`
at line 5, Extract the repeated role check into a boolean getter (e.g.,
isAdminUser) on the OwnConnectionsComponent class that returns
this.currentUser?.role === 'ADMIN' || this.currentUser?.role === 'DB_ADMIN',
then update both template expressions that currently use currentUser?.role ===
'ADMIN' || currentUser?.role === 'DB_ADMIN' to use isAdminUser instead;
implement the getter in the component class (OwnConnectionsComponent) so all
role logic is centralized and the template references become simpler and
consistent.

133-133: Consider moving inline style to CSS class.

The inline style="text-align: center;" could be consolidated into the existing .empty-state__text class or a sibling class for consistency with the component's styling approach.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@frontend/src/app/components/connections-list/own-connections/own-connections.component.html`
at line 133, The paragraph element in own-connections.component.html uses an
inline style (style="text-align: center;"); remove that inline style and instead
add the centering rule to the component stylesheet by either adding text-align:
center to the existing .empty-state__text selector or creating a new modifier
class (e.g., .empty-state__text--center) and applying that class alongside
mat-body-1 in the template so styles remain consistent and component-scoped.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In
`@frontend/src/app/components/connections-list/demo-connections/demo-connections.component.html`:
- Line 20: The template uses $any(testConnectionItem).displayTitle which
bypasses TypeScript; add displayTitle to the ConnectionItem type (or create a
ConnectionViewModel type) and update the component to expose items typed as
ConnectionItem | ConnectionViewModel so the template can bind to
testConnectionItem.displayTitle without $any; specifically modify the
ConnectionItem interface (or add a new interface) to include displayTitle
(string) and adjust any mapping logic in the component class that produces
testConnectionItem to populate this field.

In
`@frontend/src/app/components/connections-list/own-connections/own-connections.component.css`:
- Around line 350-363: Add a brief CSS comment above the .fabAddButton and
.fabHostedButton rules explaining why height: 48px !important is required (e.g.,
to override Angular Material button min-height/line-height defaults for this
FAB-style button) so future maintainers understand the override; keep the
!important in .fabAddButton and .fabHostedButton and ensure the comment
references the selectors .fabAddButton and .fabHostedButton and mentions Angular
Material as the source of the competing styles.
- Around line 400-406: The CSS rule for .empty-state__text uses multiple
!important flags which likely mask Material typography and create maintenance
issues; remove unnecessary !important declarations and instead increase selector
specificity (e.g., scope it under the component root class or use the
component's host selector such as .own-connections .empty-state__text) or move
the declaration to a stylesheet loaded after Material so it naturally overrides
the library styles; keep !important only if after testing you confirm
specificity cannot be resolved without it.

In
`@frontend/src/app/components/connections-list/own-connections/own-connections.component.html`:
- Line 5: Extract the repeated role check into a boolean getter (e.g.,
isAdminUser) on the OwnConnectionsComponent class that returns
this.currentUser?.role === 'ADMIN' || this.currentUser?.role === 'DB_ADMIN',
then update both template expressions that currently use currentUser?.role ===
'ADMIN' || currentUser?.role === 'DB_ADMIN' to use isAdminUser instead;
implement the getter in the component class (OwnConnectionsComponent) so all
role logic is centralized and the template references become simpler and
consistent.
- Line 133: The paragraph element in own-connections.component.html uses an
inline style (style="text-align: center;"); remove that inline style and instead
add the centering rule to the component stylesheet by either adding text-align:
center to the existing .empty-state__text selector or creating a new modifier
class (e.g., .empty-state__text--center) and applying that class alongside
mat-body-1 in the template so styles remain consistent and component-scoped.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 25f8aeec-d819-4ccd-a92b-2587086fb847

📥 Commits

Reviewing files that changed from the base of the PR and between d4f316a and ea1722b.

📒 Files selected for processing (3)
  • frontend/src/app/components/connections-list/demo-connections/demo-connections.component.html
  • frontend/src/app/components/connections-list/own-connections/own-connections.component.css
  • frontend/src/app/components/connections-list/own-connections/own-connections.component.html

Copy link
Copy Markdown

@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: 4

🧹 Nitpick comments (1)
frontend/src/app/components/connections-list/own-connections/own-connections.component.css (1)

49-54: Give the new interactive cards a visible :focus-visible state.

hosted-banner and dbCard only define custom hover affordances right now. Mirroring those styles on :focus-visible keeps the new button/cards discoverable for keyboard users.

♿ Suggested follow-up
-.hosted-banner:hover {
+.hosted-banner:hover,
+.hosted-banner:focus-visible {
 	border-color: var(--color-accentedPalette-300);
 	box-shadow:
 		0px 8px 24px var(--color-accentedPalette-100),
 		0px 1px 5px var(--color-accentedPalette-50);
 }
@@
-	.hosted-banner:hover {
+	.hosted-banner:hover,
+	.hosted-banner:focus-visible {
 		border-color: var(--color-accentedPalette-500);
 		box-shadow:
 			0px 8px 24px var(--color-accentedPalette-800),
 			0px 1px 5px var(--color-accentedPalette-600);
 	}
@@
-.dbCard:hover {
+.dbCard:hover,
+.dbCard:focus-visible {
 	box-shadow:
 		0px 1px 5px 0px rgba(0, 0, 0, 0.2),
 		0px 3px 4px 0px rgba(0, 0, 0, 0.12),
 		0px 2px 4px 0px rgba(0, 0, 0, 0.14);
 }
@@
-	.dbCard:hover {
+	.dbCard:hover,
+	.dbCard:focus-visible {
 		background: var(--surface-dark-color);
 		border: 1px solid rgba(255, 255, 255, 0.25);
 		box-shadow:
 			0px 1px 3px 0px rgba(255, 255, 255, 0.1),
 			0px 2px 2px 0px rgba(255, 255, 255, 0.08),
 			0px 0px 2px 0px rgba(255, 255, 255, 0.12);
 	}

Also applies to: 63-68, 194-199, 207-214

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@frontend/src/app/components/connections-list/own-connections/own-connections.component.css`
around lines 49 - 54, Add matching :focus-visible rules so interactive cards
have the same visible focus affordances as hover; for .hosted-banner and the db
card selectors referenced (e.g., .dbCard or similar classes in the file),
duplicate the border-color and box-shadow styles used in the :hover state into a
:focus-visible block, ensure any existing outline is handled (keep or replace
with the same visual ring) and include keyboard-focus-friendly styling so
keyboard users see the same highlight as mouse hover.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@frontend/src/app/components/connections-list/own-connections/own-connections.component.css`:
- Around line 43-44: The hosted banner rules currently set flat background-color
values; update the hosted banner CSS in own-connections.component.css to use
linear-gradient instead of background-color and provide both light and dark
indigo gradient variants (use a default/light gradient and a dark variant under
a .dark selector or `@media` (prefers-color-scheme: dark)); replace the flat color
declarations (var(--color-accentedPalette-50) and
var(--color-accentedPalette-900)) with appropriate background:
linear-gradient(...) values and keep the text color rule intact, and make the
same change for the other occurrence around lines 58-60 so both banner variants
render the requested gradient treatment.
- Around line 24-27: Remove the duplicate text-transform declaration in
own-connections.component.css: keep a single text-transform: uppercase; (remove
the repeated line), leaving opacity: 0.45; and margin-bottom: 12px; unchanged so
Stylelint no longer flags duplicate properties.

In
`@frontend/src/app/components/connections-list/own-connections/own-connections.component.html`:
- Line 65: The badge text in the OwnConnections component template is incorrect:
in own-connections.component.html the span with class "hosted-banner__badge"
currently contains "Quickstart" but should read "Recommended" per the PR
requirement; update the inner text of that span (hosted-banner__badge) to
"Recommended" so the badge copy matches the spec.
- Line 45: The template currently renders the empty-state CTA in the `@else`
branch even when the component's connections model is null (loading); update the
conditional so the hosted/connect-your-own CTA only renders when connections is
not null and empty (e.g., replace the bare `@else` with an explicit check like
connections !== null && connections.length === 0 or wrap the CTA block with
*ngIf="connections !== null && connections.length === 0"); refer to the
connections variable and the `@else` branch in own-connections.component.html to
locate and update the condition.

---

Nitpick comments:
In
`@frontend/src/app/components/connections-list/own-connections/own-connections.component.css`:
- Around line 49-54: Add matching :focus-visible rules so interactive cards have
the same visible focus affordances as hover; for .hosted-banner and the db card
selectors referenced (e.g., .dbCard or similar classes in the file), duplicate
the border-color and box-shadow styles used in the :hover state into a
:focus-visible block, ensure any existing outline is handled (keep or replace
with the same visual ring) and include keyboard-focus-friendly styling so
keyboard users see the same highlight as mouse hover.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: b8fe33e9-1a97-4e6f-bfcd-f7886d8b5d29

📥 Commits

Reviewing files that changed from the base of the PR and between ea1722b and 3c15bdc.

📒 Files selected for processing (2)
  • frontend/src/app/components/connections-list/own-connections/own-connections.component.css
  • frontend/src/app/components/connections-list/own-connections/own-connections.component.html

Comment on lines +24 to +27
text-transform: uppercase;
opacity: 0.45;
margin-bottom: 12px;
text-transform: uppercase;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Remove the duplicate text-transform declaration.

Stylelint will keep flagging this rule until one of the duplicate declarations is removed.

🔧 Minimal fix
 .section__label {
 	display: block;
 	font-size: 11px;
 	font-weight: 700;
 	letter-spacing: 0.08em;
 	text-transform: uppercase;
 	opacity: 0.45;
 	margin-bottom: 12px;
-	text-transform: uppercase;
 }
📝 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
text-transform: uppercase;
opacity: 0.45;
margin-bottom: 12px;
text-transform: uppercase;
.section__label {
display: block;
font-size: 11px;
font-weight: 700;
letter-spacing: 0.08em;
text-transform: uppercase;
opacity: 0.45;
margin-bottom: 12px;
}
🧰 Tools
🪛 Stylelint (17.4.0)

[error] 24-24: Unexpected duplicate "text-transform" (declaration-block-no-duplicate-properties)

(declaration-block-no-duplicate-properties)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@frontend/src/app/components/connections-list/own-connections/own-connections.component.css`
around lines 24 - 27, Remove the duplicate text-transform declaration in
own-connections.component.css: keep a single text-transform: uppercase; (remove
the repeated line), leaving opacity: 0.45; and margin-bottom: 12px; unchanged so
Stylelint no longer flags duplicate properties.

Comment on lines +43 to +44
background-color: var(--color-accentedPalette-50);
color: var(--color-accentedPalette-900);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

The hosted banner lost its promised gradient treatment.

The PR scope calls for light and dark indigo gradient variants, but these rules only set flat background-color values. That ships a different banner treatment than requested.

Also applies to: 58-60

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@frontend/src/app/components/connections-list/own-connections/own-connections.component.css`
around lines 43 - 44, The hosted banner rules currently set flat
background-color values; update the hosted banner CSS in
own-connections.component.css to use linear-gradient instead of background-color
and provide both light and dark indigo gradient variants (use a default/light
gradient and a dark variant under a .dark selector or `@media`
(prefers-color-scheme: dark)); replace the flat color declarations
(var(--color-accentedPalette-50) and var(--color-accentedPalette-900)) with
appropriate background: linear-gradient(...) values and keep the text color rule
intact, and make the same change for the other occurrence around lines 58-60 so
both banner variants render the requested gradient treatment.

@if (displayedCardCount > 3) {
<button type="button" mat-button color="accent" class="showAllButton" (click)="showLess()">Show less</button>
}
} @else {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Don't render the empty state while connections is still loading.

Line 2 and Line 128 already treat connections === null as a loading state, but this @else branch still renders the hosted/connect-your-own CTA when the input is null. That will flash the wrong state before the real list arrives.

🔧 Minimal fix
-} `@else` {
+} `@else` if (connections !== null) {
📝 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
} @else {
} `@else` if (connections !== null) {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@frontend/src/app/components/connections-list/own-connections/own-connections.component.html`
at line 45, The template currently renders the empty-state CTA in the `@else`
branch even when the component's connections model is null (loading); update the
conditional so the hosted/connect-your-own CTA only renders when connections is
not null and empty (e.g., replace the bare `@else` with an explicit check like
connections !== null && connections.length === 0 or wrap the CTA block with
*ngIf="connections !== null && connections.length === 0"); refer to the
connections variable and the `@else` branch in own-connections.component.html to
locate and update the condition.

</span>
<span class="hosted-banner__subtitle">Provision a managed database in one click</span>
</div>
<span class="hosted-banner__badge">&#10022; Quickstart</span>
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

The badge copy doesn't match the PR requirement.

The scope calls for a "Recommended" badge, but Line 65 renders "Quickstart".

🔧 Copy fix
-                <span class="hosted-banner__badge">&#10022; Quickstart</span>
+                <span class="hosted-banner__badge">&#10022; Recommended</span>
📝 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
<span class="hosted-banner__badge">&#10022; Quickstart</span>
<span class="hosted-banner__badge">&#10022; Recommended</span>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@frontend/src/app/components/connections-list/own-connections/own-connections.component.html`
at line 65, The badge text in the OwnConnections component template is
incorrect: in own-connections.component.html the span with class
"hosted-banner__badge" currently contains "Quickstart" but should read
"Recommended" per the PR requirement; update the inner text of that span
(hosted-banner__badge) to "Recommended" so the badge copy matches the spec.

@lyubov-voloshko lyubov-voloshko merged commit b0d7ff0 into rocket-admin:main Mar 26, 2026
6 of 9 checks passed
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.

4 participants