Connection string improvements#1766
Conversation
|
Warning Rate limit exceeded
You’ve run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughThis PR introduces connection-string quick-connect parsing with auto-filled field tracking, a new AI-assisted database schema generation component, integrates schema editing into the dashboard, and updates the success theme color across the application. ChangesConnection Parsing and Database Schema Management
Sequence DiagramsequenceDiagram
participant User
participant ConnectDB as ConnectDB Component
participant Parser as Connection String Parser
participant CredForm as Credential Form
participant Dashboard as Dashboard
participant TablesList as Tables List
participant SchemaEditor as Schema Editor
participant TableSchemaService
User->>ConnectDB: Enter connection string
ConnectDB->>Parser: onConnectionStringChange()
Parser->>Parser: Parse and extract fields
Parser->>CredForm: Populate auto-filled fields
Parser->>Parser: Track auto-filled set
User->>CredForm: Edit a field manually
CredForm->>ConnectDB: fieldChange event
ConnectDB->>ConnectDB: clearAutoFilledField()
User->>TablesList: Click "Edit structure"
TablesList->>Dashboard: editStructure event
Dashboard->>Dashboard: onEditStructure()
Dashboard->>SchemaEditor: Show editor panel
User->>SchemaEditor: Enter schema prompt
SchemaEditor->>TableSchemaService: generateSchemaChange()
TableSchemaService->>SchemaEditor: Return batch with changes
SchemaEditor->>SchemaEditor: Display change cards
User->>SchemaEditor: Approve changes
SchemaEditor->>TableSchemaService: approveBatch()
TableSchemaService->>SchemaEditor: Confirmation
SchemaEditor->>Dashboard: schemaApplied event
Dashboard->>Dashboard: onSchemaApplied(), refresh data
Estimated code review effort🎯 4 (Complex) | ⏱️ ~50 minutes Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 6✅ Passed checks (6 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Tip 💬 Introducing Slack Agent: The best way for teams to turn conversations into code.Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.
Built for teams:
One agent for your entire SDLC. Right inside Slack. 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. Comment |
There was a problem hiding this comment.
Pull request overview
This PR updates the frontend connection “quick connect” flow by parsing a pasted connection string to auto-fill credential fields (with visual “autofilled” highlighting), and also introduces an AI-assisted schema generation/editor panel in the Dashboard UI. It additionally tweaks the success color palette and related theme backgrounds.
Changes:
- Auto-parse connection strings to populate credential fields and highlight auto-filled inputs, with “source of truth” messaging when fields are manually overridden.
- Add a new Dashboard “Edit structure” entry point and a bottom panel UI to generate/apply schema changes via a new
TableSchemaService. - Update success palette color and adjust success background tinting.
Reviewed changes
Copilot reviewed 31 out of 31 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| frontend/src/main.ts | Updates the global success palette color. |
| frontend/src/custom-theme.scss | Adjusts success background tinting via color-mix. |
| frontend/src/app/services/table-schema.service.ts | Adds API client service/types for schema change generation/approval/rejection. |
| frontend/src/app/services/connections.service.ts | Updates default success palette color in connection UI settings. |
| frontend/src/app/services/connections.service.spec.ts | Updates expected palette color in tests. |
| frontend/src/app/components/dashboard/db-tables-list/db-tables-list.component.ts | Adds editStructure output event. |
| frontend/src/app/components/dashboard/db-tables-list/db-tables-list.component.html | Adds “Edit structure” buttons in collapsed/expanded sidebar views. |
| frontend/src/app/components/dashboard/db-tables-list/db-tables-list.component.css | Adds sticky “Edit structure” button styling and adjusts bottom positioning. |
| frontend/src/app/components/dashboard/db-generate-schema/db-generate-schema.component.ts | New component implementing the schema-change chat/workflow. |
| frontend/src/app/components/dashboard/db-generate-schema/db-generate-schema.component.html | New template for schema chat UI and change review/approve/reject actions. |
| frontend/src/app/components/dashboard/db-generate-schema/db-generate-schema.component.css | New styles for schema chat and bottom panel layout. |
| frontend/src/app/components/dashboard/dashboard.component.ts | Wires in schema editor state and handlers; imports new component. |
| frontend/src/app/components/dashboard/dashboard.component.html | Replaces “no tables” banner with schema generator and adds bottom schema editor panel. |
| frontend/src/app/components/dashboard/dashboard.component.css | Adds fixed bottom panel styling and content padding adjustments. |
| frontend/src/app/components/connect-db/db-credentials-forms/redis-credentials-form/redis-credentials-form.component.html | Adds autofill highlighting hooks and clears autofill on manual edits. |
| frontend/src/app/components/connect-db/db-credentials-forms/postgres-credentials-form/postgres-credentials-form.component.html | Adds autofill highlighting hooks and clears autofill on manual edits. |
| frontend/src/app/components/connect-db/db-credentials-forms/oracledb-credentials-form/oracledb-credentials-form.component.html | Adds autofill highlighting hooks and clears autofill on manual edits. |
| frontend/src/app/components/connect-db/db-credentials-forms/mysql-credentials-form/mysql-credentials-form.component.html | Adds autofill highlighting hooks and clears autofill on manual edits. |
| frontend/src/app/components/connect-db/db-credentials-forms/mssql-credentials-form/mssql-credentials-form.component.html | Adds autofill highlighting hooks and clears autofill on manual edits. |
| frontend/src/app/components/connect-db/db-credentials-forms/mongodb-credentials-form/mongodb-credentials-form.component.html | Adds autofill highlighting hooks (including authSource) and clears autofill on edits. |
| frontend/src/app/components/connect-db/db-credentials-forms/elastic-credentials-form/elastic-credentials-form.component.html | Adds autofill highlighting hooks and clears autofill on manual edits. |
| frontend/src/app/components/connect-db/db-credentials-forms/dynamodb-credentials-form/dynamodb-credentials-form.component.html | Adds autofill highlighting hooks and clears autofill on manual edits. |
| frontend/src/app/components/connect-db/db-credentials-forms/db2-credentials-form/db2-credentials-form.component.html | Adds autofill highlighting hooks and clears autofill on manual edits. |
| frontend/src/app/components/connect-db/db-credentials-forms/clickhouse-credentials-form/clickhouse-credentials-form.component.html | Adds autofill highlighting hooks and clears autofill on manual edits. |
| frontend/src/app/components/connect-db/db-credentials-forms/cassandra-credentials-form/cassandra-credentials-form.component.html | Adds autofill highlighting hooks and clears autofill on manual edits. |
| frontend/src/app/components/connect-db/db-credentials-forms/base-credentials-form/base-credentials-form.component.ts | Adds autoFilledFields input and fieldChange output plumbing. |
| frontend/src/app/components/connect-db/db-credentials-forms/base-credentials-form/base-credentials-form.component.css | Adds shared autofill highlight styling (light/dark). |
| frontend/src/app/components/connect-db/db-connection-ip-access-dialog/db-connection-ip-access-dialog.component.html | Removes trailing whitespace line. |
| frontend/src/app/components/connect-db/connect-db.component.ts | Implements auto-parse connection string flow and autofill tracking/override behavior. |
| frontend/src/app/components/connect-db/connect-db.component.html | Replaces “Apply” with auto-parse UX; displays parsed string and override note; passes autofill set to forms. |
| frontend/src/app/components/connect-db/connect-db.component.css | Adds styling for the connection-string quick connect card and parsed/override messages. |
Comments suppressed due to low confidence (1)
frontend/src/app/components/connect-db/connect-db.component.ts:491
autoFilledFieldsis initialized withusername,password, anddatabaseeven if the parsed connection string omits them (parseConnectionString returns empty strings). This will mark empty fields as autofilled and can confuse users. Consider adding keys toautoFilledFieldsonly when the parsed value is actually present/non-empty (and similarly forportwhen it’s empty for certain schemes).
this.parsedConnectionString = this.connectionString;
this.autoFilledFields = new Set(['host', 'port', 'username', 'password', 'database']);
this.fieldsOverridden = false;
this.db.type = parsed.dbType;
this.db.host = parsed.host;
this.db.port = parsed.port;
this.db.username = parsed.username;
this.db.password = parsed.password;
this.db.database = parsed.database;
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| <mat-icon class="connectForm__connectionStringParsed-icon">check_circle</mat-icon> | ||
| <span> | ||
| <span class="connectForm__connectionStringParsed-label">Parsed:</span> | ||
| <code class="connectForm__connectionStringParsed-value">{{ parsedConnectionString }}</code> |
| [(ngModel)]="connectionString"> | ||
| <mat-hint>Paste your database connection URI to auto-fill credentials</mat-hint> | ||
| [(ngModel)]="connectionString" | ||
| (ngModelChange)="onConnectionStringChange(connectionStringInput)"> |
| if (result && result.changes.length > 0) { | ||
| const summary = result.changes.map(c => `**${c.changeType}** \`${c.targetTableName}\`${c.aiSummary ? ' — ' + c.aiSummary : ''}`).join('\n'); | ||
| this.messages.update(msgs => [...msgs, { | ||
| role: 'ai', | ||
| text: `I've generated ${result.changes.length} change(s) for your database:\n\n${summary}\n\nReview the SQL below and approve or reject.`, | ||
| changes: result.changes, |
| this.messages.update(msgs => [...msgs, { | ||
| role: 'error', | ||
| text: `${failed.length} change(s) failed: ${failed.map(c => c.executionError).join('; ')}`, |
| <div class="collapsed-add-button" | ||
| (click)="editStructure.emit()" | ||
| matTooltip="Edit structure" | ||
| matTooltipPosition="right"> | ||
| <mat-icon class="collapsed-action-icon">construction</mat-icon> | ||
| </div> |
| @@ -55,6 +56,7 @@ interface DataToActivateActions { | |||
| MatIconModule, | |||
| MatDialogModule, | |||
| MatSidenavModule, | |||
| DbGenerateSchemaComponent, | |||
| DbTablesListComponent, | |||
There was a problem hiding this comment.
Actionable comments posted: 9
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
frontend/src/app/components/connect-db/db-credentials-forms/mongodb-credentials-form/mongodb-credentials-form.component.html (1)
87-99:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winMissing
clearAutoFilled('authSource')call for consistency.The
authSourcefield has the[class.autofilled]binding (lines 87-88), but its(change)handler on line 94 doesn't callclearAutoFilled('authSource')like all other autofilled fields (host, port, username, password, database). This inconsistency means the autofilled visual indicator won't be cleared when the user edits the authSource field.🔧 Proposed fix
angulartics2On="change" angularticsAction="Connection creds {{ connection.id ? 'edit' : 'add' }}: database authSource is edited" - (change)="posthog.capture('Connection creds {{ connection.id ? \'edit\' : \'add\' }}: database authSource is edited')" + (change)="posthog.capture('Connection creds {{ connection.id ? \'edit\' : \'add\' }}: database authSource is edited'); clearAutoFilled('authSource')" [readonly]="(accessLevel === 'readonly' || connection.isTestConnection) && connection.id"🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@frontend/src/app/components/connect-db/db-credentials-forms/mongodb-credentials-form/mongodb-credentials-form.component.html` around lines 87 - 99, The authSource input (the <input ... name="authsource" ... [(ngModel)]="connection.authSource"> with the [class.autofilled] binding) is missing a call to clearAutoFilled('authSource') in its change handler; update that input's (change) handler to invoke clearAutoFilled('authSource') (consistent with host/port/username/password/database fields) before or alongside the existing posthog.capture/angulartics logic so the autofilled visual state is cleared when the user edits connection.authSource.frontend/src/app/components/connect-db/connect-db.component.ts (1)
486-492:⚠️ Potential issue | 🟠 Major | ⚡ Quick winSync the credentials form component after parsed DB type changes.
After assigning
this.db.type = parsed.dbType, the dynamic form component is not refreshed. If the parsed type differs from the current selection, the wrong credential form can remain mounted.Proposed fix
this.db.type = parsed.dbType; + this.credentialsFormComponent = this.credentialsFormMap[this.db.type] || null; this.db.host = parsed.host; this.db.port = parsed.port;🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@frontend/src/app/components/connect-db/connect-db.component.ts` around lines 486 - 492, After setting this.db.type = parsed.dbType, ensure the credentials form is re-initialized by calling the component method that handles DB type changes so the dynamic credential form matches the new type; specifically, invoke the same handler used for user-driven changes (for example this.onDbTypeChange(parsed.dbType) or the component's existing handleDbTypeSelection/refreshCredentialsForm method) immediately after assigning this.db.type so the mounted credential form is reset/re-rendered to the parsed type.
🧹 Nitpick comments (2)
frontend/src/app/components/dashboard/db-tables-list/db-tables-list.component.ts (1)
118-123: ⚡ Quick winConsider migrating to
inject()pattern for consistency.The component uses
inject()forConnectionsService(line 80) but constructor injection here. For consistency with the coding guidelines and modern Angular patterns, consider migrating these dependencies toinject().♻️ Proposed refactor
+ private _tableState = inject(TableStateService); + private _tablesService = inject(TablesService); + private _uiSettingsService = inject(UiSettingsService); + private _dialog = inject(MatDialog); + - constructor( - private _tableState: TableStateService, - private _tablesService: TablesService, - private _uiSettingsService: UiSettingsService, - private dialog: MatDialog, - ) {}As per coding guidelines: Use
inject()function (e.g.,private _dataService = inject(DataService)) instead of constructor parameters.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@frontend/src/app/components/dashboard/db-tables-list/db-tables-list.component.ts` around lines 118 - 123, The constructor injection for _tableState (TableStateService), _tablesService (TablesService), _uiSettingsService (UiSettingsService) and dialog (MatDialog) should be migrated to the Angular inject() pattern to match the existing ConnectionsService usage: remove these parameters from the constructor and add private class fields that call inject() for each service (e.g., private _tableState = inject(TableStateService), etc.), ensure inject is imported from `@angular/core`, and update any references to the constructor (or remove the empty constructor) so the component uses the injected fields consistently.frontend/src/app/components/dashboard/db-generate-schema/db-generate-schema.component.ts (1)
122-133: ⚡ Quick winAdd error handling to
onReject().The
rejectBatchcall at line 126 lacks error handling. If the API call fails, the user won't receive feedback, and the UI state may become inconsistent.🛡️ Proposed fix
async onReject() { const batch = this.pendingBatch(); if (!batch?.batchId) return; - await this._tableSchema.rejectBatch(batch.batchId); - this.messages.update(msgs => msgs.map(m => - m === batch ? { ...m, batchId: undefined } : m - ).concat({ - role: 'ai', - text: 'Changes rejected. Feel free to describe what you need differently.', - })); + try { + await this._tableSchema.rejectBatch(batch.batchId); + this.messages.update(msgs => msgs.map(m => + m === batch ? { ...m, batchId: undefined } : m + ).concat({ + role: 'ai', + text: 'Changes rejected. Feel free to describe what you need differently.', + })); + } catch (err: unknown) { + const error = err as { error?: { message?: string }; message?: string }; + this.messages.update(msgs => [...msgs, { + role: 'error', + text: error?.error?.message || error?.message || 'Failed to reject schema changes.', + }]); + } }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@frontend/src/app/components/dashboard/db-generate-schema/db-generate-schema.component.ts` around lines 122 - 133, The onReject() handler calls _tableSchema.rejectBatch(batch.batchId) without guarding for failures, which can leave the UI inconsistent; wrap that call in a try/catch inside onReject(), only update messages (via messages.update) when the API call succeeds, and in the catch block push an error message (role: 'system' or 'ai') describing the failure and optionally log the error; ensure you still return early if pendingBatch() is missing and do not clear batchId on failure so the UI remains consistent.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@frontend/src/app/components/connect-db/connect-db.component.ts`:
- Around line 511-514: The clearAutoFilledField method sets fieldsOverridden
unconditionally; change it to only flip to true when an autofilled entry was
actually removed. In clearAutoFilledField(field: string) check whether
this.autoFilledFields contains the field (or capture the boolean result of
delete) before assigning this.autoFilledFields = new
Set(...)/this.autoFilledFields.delete(...) and only set this.fieldsOverridden =
true when the field was present and removed; keep the existing pattern of
creating a new Set to preserve immutability and update only on actual change.
- Line 475: The onConnectionStringChange method currently declares an unused
parameter _input and lacks an explicit return type; remove the unused parameter
from onConnectionStringChange and annotate the method with an explicit void
return type (i.e., change signature to onConnectionStringChange(): void), update
any callers if they pass an argument to stop passing one, and avoid using the
any type anywhere in that signature.
In `@frontend/src/app/components/dashboard/dashboard.component.html`:
- Line 132: Replace the structural directive usage on the app-db-table-row-view
element with Angular 19 control-flow syntax: remove "*ngIf=\"selectedRow &&
!showSchemaEditor\"" and use the framework's `@if` control flow for the same
condition (targeting the app-db-table-row-view element where the condition is
"selectedRow && !showSchemaEditor"); update the sibling occurrence at the other
noted spot similarly so both uses of *ngIf are converted to the Angular 19 `@if`
form.
- Line 1: Replace the structural directive usage on the
app-placeholder-table-view element with Angular 19 control-flow syntax: remove
"*ngIf" and apply the equivalent `@if`(...) control flow using the same boolean
expression (loading && !noTablesError && !isServerError) so the template uses
`@if` for conditional rendering of the app-placeholder-table-view component.
- Around line 24-29: Replace the structural *ngIf usage on the
<app-db-generate-schema> element with Angular 19's built-in control-flow `@if`
syntax: remove the *ngIf="noTablesError" and render the <app-db-generate-schema>
component using an `@if` block bound to the same condition (noTablesError),
preserving the [connectionID], (schemaApplied)="onSchemaApplied()" and
data-testid attributes so the component and its event handler remain unchanged.
- Around line 140-149: Replace the legacy structural directive "*ngIf" on the
app-db-generate-schema element with Angular 19 control-flow syntax by using the
`@if` directive (e.g., wrap or replace the component element with an ng-container
or the component element itself using `@if`="showSchemaEditor"); keep the existing
[connectionID], [showClose], (schemaApplied)="onSchemaApplied()",
(closeEditor)="showSchemaEditor = false", data-testid and the surrounding div
with its [class.schema-editor-panel--open]="showSchemaEditor" binding, and
remove the "*ngIf" attribute so the template uses `@if`="showSchemaEditor" instead
of *ngIf.
In `@frontend/src/app/components/dashboard/dashboard.component.ts`:
- Around line 454-456: The method onEditStructure lacks an access modifier and a
return type; update the declaration of onEditStructure in dashboard.component.ts
to include an explicit access modifier (e.g., public or private to match the
component's API) and add a TypeScript return type annotation (e.g., : void) so
the signature reads with the chosen access level and a void return type; ensure
any references to onEditStructure remain consistent with the chosen visibility.
- Around line 458-465: The onSchemaApplied function uses a magic setTimeout and
lacks types, error handling and proper async coordination; change
onSchemaApplied to a typed method (e.g., protected onSchemaApplied(): void) that
immediately sets this.noTablesError = false, this.showSchemaEditor = false and
this.loading = true, then await a real completion signal (a Promise or
Observable) from the schema generation component instead of using setTimeout,
call this.getData() after that signal and wrap getData() in try/catch to handle
errors and clear/reset this.loading accordingly; reference the existing
onSchemaApplied and getData methods and the this.noTablesError /
this.showSchemaEditor / this.loading fields when implementing the change.
- Line 106: The showSchemaEditor property is a plain boolean but must be an
Angular signal; change the declaration of showSchemaEditor to a private readonly
signal initialized via signal(false) and update usages: replace assignments like
this.showSchemaEditor = true/false with this.showSchemaEditor.set(true/false)
inside methods such as onEditStructure and onSchemaApplied, and update template
reads to call the signal as showSchemaEditor() (e.g.
class.table-preview-content--panel-open and *ngIf checks); also ensure
onSchemaApplied still toggles noTablesError, loading and calls getData() as
before after the timeout.
---
Outside diff comments:
In `@frontend/src/app/components/connect-db/connect-db.component.ts`:
- Around line 486-492: After setting this.db.type = parsed.dbType, ensure the
credentials form is re-initialized by calling the component method that handles
DB type changes so the dynamic credential form matches the new type;
specifically, invoke the same handler used for user-driven changes (for example
this.onDbTypeChange(parsed.dbType) or the component's existing
handleDbTypeSelection/refreshCredentialsForm method) immediately after assigning
this.db.type so the mounted credential form is reset/re-rendered to the parsed
type.
In
`@frontend/src/app/components/connect-db/db-credentials-forms/mongodb-credentials-form/mongodb-credentials-form.component.html`:
- Around line 87-99: The authSource input (the <input ... name="authsource" ...
[(ngModel)]="connection.authSource"> with the [class.autofilled] binding) is
missing a call to clearAutoFilled('authSource') in its change handler; update
that input's (change) handler to invoke clearAutoFilled('authSource')
(consistent with host/port/username/password/database fields) before or
alongside the existing posthog.capture/angulartics logic so the autofilled
visual state is cleared when the user edits connection.authSource.
---
Nitpick comments:
In
`@frontend/src/app/components/dashboard/db-generate-schema/db-generate-schema.component.ts`:
- Around line 122-133: The onReject() handler calls
_tableSchema.rejectBatch(batch.batchId) without guarding for failures, which can
leave the UI inconsistent; wrap that call in a try/catch inside onReject(), only
update messages (via messages.update) when the API call succeeds, and in the
catch block push an error message (role: 'system' or 'ai') describing the
failure and optionally log the error; ensure you still return early if
pendingBatch() is missing and do not clear batchId on failure so the UI remains
consistent.
In
`@frontend/src/app/components/dashboard/db-tables-list/db-tables-list.component.ts`:
- Around line 118-123: The constructor injection for _tableState
(TableStateService), _tablesService (TablesService), _uiSettingsService
(UiSettingsService) and dialog (MatDialog) should be migrated to the Angular
inject() pattern to match the existing ConnectionsService usage: remove these
parameters from the constructor and add private class fields that call inject()
for each service (e.g., private _tableState = inject(TableStateService), etc.),
ensure inject is imported from `@angular/core`, and update any references to the
constructor (or remove the empty constructor) so the component uses the injected
fields consistently.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: a4311ef0-e978-4fa2-9bec-a5b81cf2bf6f
📒 Files selected for processing (31)
frontend/src/app/components/connect-db/connect-db.component.cssfrontend/src/app/components/connect-db/connect-db.component.htmlfrontend/src/app/components/connect-db/connect-db.component.tsfrontend/src/app/components/connect-db/db-connection-ip-access-dialog/db-connection-ip-access-dialog.component.htmlfrontend/src/app/components/connect-db/db-credentials-forms/base-credentials-form/base-credentials-form.component.cssfrontend/src/app/components/connect-db/db-credentials-forms/base-credentials-form/base-credentials-form.component.tsfrontend/src/app/components/connect-db/db-credentials-forms/cassandra-credentials-form/cassandra-credentials-form.component.htmlfrontend/src/app/components/connect-db/db-credentials-forms/clickhouse-credentials-form/clickhouse-credentials-form.component.htmlfrontend/src/app/components/connect-db/db-credentials-forms/db2-credentials-form/db2-credentials-form.component.htmlfrontend/src/app/components/connect-db/db-credentials-forms/dynamodb-credentials-form/dynamodb-credentials-form.component.htmlfrontend/src/app/components/connect-db/db-credentials-forms/elastic-credentials-form/elastic-credentials-form.component.htmlfrontend/src/app/components/connect-db/db-credentials-forms/mongodb-credentials-form/mongodb-credentials-form.component.htmlfrontend/src/app/components/connect-db/db-credentials-forms/mssql-credentials-form/mssql-credentials-form.component.htmlfrontend/src/app/components/connect-db/db-credentials-forms/mysql-credentials-form/mysql-credentials-form.component.htmlfrontend/src/app/components/connect-db/db-credentials-forms/oracledb-credentials-form/oracledb-credentials-form.component.htmlfrontend/src/app/components/connect-db/db-credentials-forms/postgres-credentials-form/postgres-credentials-form.component.htmlfrontend/src/app/components/connect-db/db-credentials-forms/redis-credentials-form/redis-credentials-form.component.htmlfrontend/src/app/components/dashboard/dashboard.component.cssfrontend/src/app/components/dashboard/dashboard.component.htmlfrontend/src/app/components/dashboard/dashboard.component.tsfrontend/src/app/components/dashboard/db-generate-schema/db-generate-schema.component.cssfrontend/src/app/components/dashboard/db-generate-schema/db-generate-schema.component.htmlfrontend/src/app/components/dashboard/db-generate-schema/db-generate-schema.component.tsfrontend/src/app/components/dashboard/db-tables-list/db-tables-list.component.cssfrontend/src/app/components/dashboard/db-tables-list/db-tables-list.component.htmlfrontend/src/app/components/dashboard/db-tables-list/db-tables-list.component.tsfrontend/src/app/services/connections.service.spec.tsfrontend/src/app/services/connections.service.tsfrontend/src/app/services/table-schema.service.tsfrontend/src/custom-theme.scssfrontend/src/main.ts
💤 Files with no reviewable changes (1)
- frontend/src/app/components/connect-db/db-connection-ip-access-dialog/db-connection-ip-access-dialog.component.html
| } | ||
|
|
||
| applyConnectionString() { | ||
| onConnectionStringChange(_input: any) { |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Verify how the handler is called from templates to choose the narrowest input type.
rg -nP --type=html -C2 'onConnectionStringChange\s*\(([^)]*)\)'Repository: rocket-admin/rocketadmin
Length of output: 805
🏁 Script executed:
#!/bin/bash
# Read the component file to understand the method implementation and return type
cat -n frontend/src/app/components/connect-db/connect-db.component.ts | head -500 | tail -50Repository: rocket-admin/rocketadmin
Length of output: 1723
🏁 Script executed:
#!/bin/bash
# Search for the method definition and its full signature
rg -n 'onConnectionStringChange' frontend/src/app/components/connect-db/connect-db.component.ts -A 10Repository: rocket-admin/rocketadmin
Length of output: 461
🏁 Script executed:
#!/bin/bash
# Also check the template file more thoroughly for context
cat -n frontend/src/app/components/connect-db/connect-db.component.html | sed -n '85,100p'Repository: rocket-admin/rocketadmin
Length of output: 1298
🏁 Script executed:
#!/bin/bash
# Search for all calls to onConnectionStringChange to see if it's called programmatically
rg -n 'onConnectionStringChange' frontend/src/app/components/connect-db/ --type=ts -A 2 -B 2Repository: rocket-admin/rocketadmin
Length of output: 498
🏁 Script executed:
#!/bin/bash
# Search across entire codebase for programmatic calls
rg -n 'onConnectionStringChange\s*\(' --type=ts -A 1 -B 1Repository: rocket-admin/rocketadmin
Length of output: 350
🏁 Script executed:
#!/bin/bash
# Get the full method implementation to see where it ends
sed -n '475,525p' frontend/src/app/components/connect-db/connect-db.component.tsRepository: rocket-admin/rocketadmin
Length of output: 1796
Add explicit return type and remove unused parameter.
The _input parameter is never used in the method body (the method relies on this.connectionString instead). Remove the unused parameter and add an explicit void return type.
Proposed fix
- onConnectionStringChange(_input: any) {
+ onConnectionStringChange(): void {Per coding guidelines: "Always add type annotations to function parameters and return types in TypeScript" and "Avoid any types."
📝 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.
| onConnectionStringChange(_input: any) { | |
| onConnectionStringChange(): void { |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@frontend/src/app/components/connect-db/connect-db.component.ts` at line 475,
The onConnectionStringChange method currently declares an unused parameter
_input and lacks an explicit return type; remove the unused parameter from
onConnectionStringChange and annotate the method with an explicit void return
type (i.e., change signature to onConnectionStringChange(): void), update any
callers if they pass an argument to stop passing one, and avoid using the any
type anywhere in that signature.
| clearAutoFilledField(field: string): void { | ||
| this.autoFilledFields = new Set(this.autoFilledFields); | ||
| this.autoFilledFields.delete(field); | ||
| this.fieldsOverridden = true; |
There was a problem hiding this comment.
Set fieldsOverridden only when an autofilled field was actually cleared.
fieldsOverridden is currently set to true on every field change, even if no autofilled field existed. That can trigger override UI in manual-entry flows.
Proposed fix
clearAutoFilledField(field: string): void {
- this.autoFilledFields = new Set(this.autoFilledFields);
- this.autoFilledFields.delete(field);
- this.fieldsOverridden = true;
+ const hadField = this.autoFilledFields.has(field);
+ this.autoFilledFields = new Set(this.autoFilledFields);
+ this.autoFilledFields.delete(field);
+ if (hadField) {
+ this.fieldsOverridden = true;
+ }
}🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@frontend/src/app/components/connect-db/connect-db.component.ts` around lines
511 - 514, The clearAutoFilledField method sets fieldsOverridden
unconditionally; change it to only flip to true when an autofilled entry was
actually removed. In clearAutoFilledField(field: string) check whether
this.autoFilledFields contains the field (or capture the boolean result of
delete) before assigning this.autoFilledFields = new
Set(...)/this.autoFilledFields.delete(...) and only set this.fieldsOverridden =
true when the field was present and removed; keep the existing pattern of
creating a new Set to preserve immutability and update only on actual change.
| @@ -1,4 +1,4 @@ | |||
| <app-placeholder-table-view *ngIf="loading"></app-placeholder-table-view> | |||
| <app-placeholder-table-view *ngIf="loading && !noTablesError && !isServerError"></app-placeholder-table-view> | |||
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win
Use Angular 19 control flow syntax instead of structural directive.
♻️ Proposed fix
-<app-placeholder-table-view *ngIf="loading && !noTablesError && !isServerError"></app-placeholder-table-view>
+@if (loading && !noTablesError && !isServerError) {
+ <app-placeholder-table-view></app-placeholder-table-view>
+}As per coding guidelines: "Use Angular 19's built-in control flow (@if, @for, @switch) instead of structural directives (*ngIf, *ngFor, *ngSwitch) in all new code".
📝 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.
| <app-placeholder-table-view *ngIf="loading && !noTablesError && !isServerError"></app-placeholder-table-view> | |
| `@if` (loading && !noTablesError && !isServerError) { | |
| <app-placeholder-table-view></app-placeholder-table-view> | |
| } |
🧰 Tools
🪛 HTMLHint (1.9.2)
[error] 1-1: Doctype must be declared before any non-comment content.
(doctype-first)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@frontend/src/app/components/dashboard/dashboard.component.html` at line 1,
Replace the structural directive usage on the app-placeholder-table-view element
with Angular 19 control-flow syntax: remove "*ngIf" and apply the equivalent
`@if`(...) control flow using the same boolean expression (loading &&
!noTablesError && !isServerError) so the template uses `@if` for conditional
rendering of the app-placeholder-table-view component.
| <app-db-generate-schema | ||
| *ngIf="noTablesError" | ||
| [connectionID]="connectionID" | ||
| (schemaApplied)="onSchemaApplied()" | ||
| data-testid="no-tables-generate-schema"> | ||
| </app-db-generate-schema> |
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win
Use Angular 19 control flow syntax instead of structural directive.
♻️ Proposed fix
-<app-db-generate-schema
- *ngIf="noTablesError"
- [connectionID]="connectionID"
- (schemaApplied)="onSchemaApplied()"
- data-testid="no-tables-generate-schema">
-</app-db-generate-schema>
+@if (noTablesError) {
+ <app-db-generate-schema
+ [connectionID]="connectionID"
+ (schemaApplied)="onSchemaApplied()"
+ data-testid="no-tables-generate-schema">
+ </app-db-generate-schema>
+}As per coding guidelines: "Use Angular 19's built-in control flow (@if, @for, @switch) instead of structural directives (*ngIf, *ngFor, *ngSwitch) in all new code".
📝 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.
| <app-db-generate-schema | |
| *ngIf="noTablesError" | |
| [connectionID]="connectionID" | |
| (schemaApplied)="onSchemaApplied()" | |
| data-testid="no-tables-generate-schema"> | |
| </app-db-generate-schema> | |
| `@if` (noTablesError) { | |
| <app-db-generate-schema | |
| [connectionID]="connectionID" | |
| (schemaApplied)="onSchemaApplied()" | |
| data-testid="no-tables-generate-schema"> | |
| </app-db-generate-schema> | |
| } |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@frontend/src/app/components/dashboard/dashboard.component.html` around lines
24 - 29, Replace the structural *ngIf usage on the <app-db-generate-schema>
element with Angular 19's built-in control-flow `@if` syntax: remove the
*ngIf="noTablesError" and render the <app-db-generate-schema> component using an
`@if` block bound to the same condition (noTablesError), preserving the
[connectionID], (schemaApplied)="onSchemaApplied()" and data-testid attributes
so the component and its event handler remain unchanged.
| </app-db-table-view> | ||
| </div> | ||
| <app-db-table-row-view *ngIf="selectedRow" | ||
| <app-db-table-row-view *ngIf="selectedRow && !showSchemaEditor" |
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win
Use Angular 19 control flow syntax instead of structural directives.
♻️ Proposed fix
-<app-db-table-row-view *ngIf="selectedRow && !showSchemaEditor"
- [activeFilters]="filters"
-></app-db-table-row-view>
-<app-db-table-ai-panel *ngIf="isAIpanelOpened && !showSchemaEditor"
- [displayName]="selectedTableDisplayName"
- [tableColumns]="dataSource?.dataColumns || []"
- [sidebarExpanded]="shownTableTitles"
-></app-db-table-ai-panel>
+@if (selectedRow && !showSchemaEditor) {
+ <app-db-table-row-view
+ [activeFilters]="filters"
+ ></app-db-table-row-view>
+}
+@if (isAIpanelOpened && !showSchemaEditor) {
+ <app-db-table-ai-panel
+ [displayName]="selectedTableDisplayName"
+ [tableColumns]="dataSource?.dataColumns || []"
+ [sidebarExpanded]="shownTableTitles"
+ ></app-db-table-ai-panel>
+}As per coding guidelines: "Use Angular 19's built-in control flow (@if, @for, @switch) instead of structural directives (*ngIf, *ngFor, *ngSwitch) in all new code".
Also applies to: 135-135
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@frontend/src/app/components/dashboard/dashboard.component.html` at line 132,
Replace the structural directive usage on the app-db-table-row-view element with
Angular 19 control-flow syntax: remove "*ngIf=\"selectedRow &&
!showSchemaEditor\"" and use the framework's `@if` control flow for the same
condition (targeting the app-db-table-row-view element where the condition is
"selectedRow && !showSchemaEditor"); update the sibling occurrence at the other
noted spot similarly so both uses of *ngIf are converted to the Angular 19 `@if`
form.
| <div class="schema-editor-panel" [class.schema-editor-panel--open]="showSchemaEditor"> | ||
| <app-db-generate-schema | ||
| *ngIf="showSchemaEditor" | ||
| [connectionID]="connectionID" | ||
| [showClose]="true" | ||
| (schemaApplied)="onSchemaApplied()" | ||
| (closeEditor)="showSchemaEditor = false" | ||
| data-testid="edit-structure-generate-schema"> | ||
| </app-db-generate-schema> | ||
| </div> |
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win
Use Angular 19 control flow syntax instead of structural directive.
♻️ Proposed fix
<div class="schema-editor-panel" [class.schema-editor-panel--open]="showSchemaEditor">
- <app-db-generate-schema
- *ngIf="showSchemaEditor"
- [connectionID]="connectionID"
- [showClose]="true"
- (schemaApplied)="onSchemaApplied()"
- (closeEditor)="showSchemaEditor = false"
- data-testid="edit-structure-generate-schema">
- </app-db-generate-schema>
+ `@if` (showSchemaEditor) {
+ <app-db-generate-schema
+ [connectionID]="connectionID"
+ [showClose]="true"
+ (schemaApplied)="onSchemaApplied()"
+ (closeEditor)="showSchemaEditor = false"
+ data-testid="edit-structure-generate-schema">
+ </app-db-generate-schema>
+ }
</div>As per coding guidelines: "Use Angular 19's built-in control flow (@if, @for, @switch) instead of structural directives (*ngIf, *ngFor, *ngSwitch) in all new code".
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@frontend/src/app/components/dashboard/dashboard.component.html` around lines
140 - 149, Replace the legacy structural directive "*ngIf" on the
app-db-generate-schema element with Angular 19 control-flow syntax by using the
`@if` directive (e.g., wrap or replace the component element with an ng-container
or the component element itself using `@if`="showSchemaEditor"); keep the existing
[connectionID], [showClose], (schemaApplied)="onSchemaApplied()",
(closeEditor)="showSchemaEditor = false", data-testid and the surrounding div
with its [class.schema-editor-panel--open]="showSchemaEditor" binding, and
remove the "*ngIf" attribute so the template uses `@if`="showSchemaEditor" instead
of *ngIf.
| public uiSettings: ConnectionSettingsUI; | ||
| public tableFolders: any[] = []; | ||
| public isConfiguring: boolean = false; | ||
| public showSchemaEditor: boolean = false; |
There was a problem hiding this comment.
Use Angular signal for component state instead of plain boolean.
The showSchemaEditor property manages component state but is declared as a plain boolean. New code must use signals for state management.
🔄 Proposed fix using signals
-public showSchemaEditor: boolean = false;
+protected readonly showSchemaEditor = signal(false);Then update the methods to use signal API:
onEditStructure(): void {
this.showSchemaEditor.set(true);
}
onSchemaApplied(): void {
setTimeout(() => {
this.noTablesError = false;
this.showSchemaEditor.set(false);
this.loading = true;
this.getData();
}, 1500);
}And update the template to read the signal value:
[class.table-preview-content--panel-open]="showSchemaEditor()"
*ngIf="selectedRow && !showSchemaEditor()"As per coding guidelines: "All new code must use Angular signals (signal(), computed(), effect()) for state management" and "Signals for component state must be declared as protected or private readonly and initialized with signal() or computed()".
📝 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.
| public showSchemaEditor: boolean = false; | |
| protected readonly showSchemaEditor = signal(false); |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@frontend/src/app/components/dashboard/dashboard.component.ts` at line 106,
The showSchemaEditor property is a plain boolean but must be an Angular signal;
change the declaration of showSchemaEditor to a private readonly signal
initialized via signal(false) and update usages: replace assignments like
this.showSchemaEditor = true/false with this.showSchemaEditor.set(true/false)
inside methods such as onEditStructure and onSchemaApplied, and update template
reads to call the signal as showSchemaEditor() (e.g.
class.table-preview-content--panel-open and *ngIf checks); also ensure
onSchemaApplied still toggles noTablesError, loading and calls getData() as
before after the timeout.
| onEditStructure() { | ||
| this.showSchemaEditor = true; | ||
| } |
There was a problem hiding this comment.
Add access modifier and return type annotation.
📝 Proposed fix
-onEditStructure() {
+protected onEditStructure(): void {
this.showSchemaEditor = true;
}As per coding guidelines: "Always add type annotations to function parameters and return types in TypeScript".
📝 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.
| onEditStructure() { | |
| this.showSchemaEditor = true; | |
| } | |
| protected onEditStructure(): void { | |
| this.showSchemaEditor = true; | |
| } |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@frontend/src/app/components/dashboard/dashboard.component.ts` around lines
454 - 456, The method onEditStructure lacks an access modifier and a return
type; update the declaration of onEditStructure in dashboard.component.ts to
include an explicit access modifier (e.g., public or private to match the
component's API) and add a TypeScript return type annotation (e.g., : void) so
the signature reads with the chosen access level and a void return type; ensure
any references to onEditStructure remain consistent with the chosen visibility.
| onSchemaApplied() { | ||
| setTimeout(() => { | ||
| this.noTablesError = false; | ||
| this.showSchemaEditor = false; | ||
| this.loading = true; | ||
| this.getData(); | ||
| }, 1500); | ||
| } |
There was a problem hiding this comment.
Refactor setTimeout approach and add proper async handling.
This implementation has several concerns:
- Magic number timeout: The 1500ms delay is arbitrary and creates a poor user experience—users wait unnecessarily if the operation completes quickly, or see stale UI if it takes longer.
- Missing error handling: No handling if
getData()fails after schema application. - Missing type annotations: Method lacks access modifier and return type.
- Race condition risk: The timeout may complete before or after the actual backend operation finishes.
Consider refactoring to wait for actual completion signals rather than using a fixed timeout.
🔧 Proposed improvements
-onSchemaApplied() {
- setTimeout(() => {
- this.noTablesError = false;
- this.showSchemaEditor = false;
- this.loading = true;
- this.getData();
- }, 1500);
+private static readonly SCHEMA_APPLY_REFRESH_DELAY = 1500;
+
+protected onSchemaApplied(): void {
+ // TODO: Replace setTimeout with proper async completion handling
+ // Consider returning an observable from schema application and subscribing to it
+ setTimeout(() => {
+ this.noTablesError = false;
+ this.showSchemaEditor = false;
+ this.loading = true;
+ this.getData();
+ }, DashboardComponent.SCHEMA_APPLY_REFRESH_DELAY);
}For a more robust solution, consider having the schema generation component emit completion status and handle it properly:
protected onSchemaApplied(): void {
this.noTablesError = false;
this.showSchemaEditor = false;
this.loading = true;
// Wait for actual backend confirmation before refreshing
this.getData();
}As per coding guidelines: "Always add type annotations to function parameters and return types in TypeScript" and "Use UPPER_SNAKE_CASE for constants".
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@frontend/src/app/components/dashboard/dashboard.component.ts` around lines
458 - 465, The onSchemaApplied function uses a magic setTimeout and lacks types,
error handling and proper async coordination; change onSchemaApplied to a typed
method (e.g., protected onSchemaApplied(): void) that immediately sets
this.noTablesError = false, this.showSchemaEditor = false and this.loading =
true, then await a real completion signal (a Promise or Observable) from the
schema generation component instead of using setTimeout, call this.getData()
after that signal and wrap getData() in try/catch to handle errors and
clear/reset this.loading accordingly; reference the existing onSchemaApplied and
getData methods and the this.noTablesError / this.showSchemaEditor /
this.loading fields when implementing the change.
Summary by CodeRabbit
Release Notes
New Features
Style