edit-schema: full-screen AI canvas with templates and live preview#1784
edit-schema: full-screen AI canvas with templates and live preview#1784karinakharchenko wants to merge 9 commits into
Conversation
Restructure the schema editor into a Figma-style canvas with the AI chat docked on the right. Adds a new SchemaDiagramViewer with mouse pan (grab cursor), wheel-anchored zoom, double-click focus, a floating searchable tables sidebar, fit-to-screen / reset controls, and a minimap with a draggable viewport rectangle. Diagram re-renders re-fit automatically when the source changes. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…reen Generate a mermaid ER preview from AI-returned CREATE TABLE SQL and show it on the canvas as "Schema Preview" before the user applies — useful for empty databases where the backend has no schema yet. Switch the prompt textarea to cdkTextareaAutosize so it grows as the user types (2–10 rows). Make the diagram viewer's fit-to-screen scale up to fill the visible area (previously capped at 1×), measure the viewport live if ResizeObserver hasn't fired yet, and reset transform + size signals when the source changes so a new diagram is centered and sized from a clean state. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
|
📝 WalkthroughWalkthroughRefactors the schema editor into a two-column editor (left diagram canvas, right assistant chat), extracts a standalone SchemaDiagramViewer with pan/zoom/focus and table search, and adds SQL→mermaid ER preview generation wired into submit/reject flows plus styling and Mermaid theme updates. ChangesSchema Editor Refactoring
Sequence DiagramsequenceDiagram
participant User
participant EditDatabaseSchemaComponent
participant SchemaDiagramViewerComponent
participant ChatPanel
User->>EditDatabaseSchemaComponent: Open schema editor
EditDatabaseSchemaComponent->>SchemaDiagramViewerComponent: Render currentDiagram() source
SchemaDiagramViewerComponent->>SchemaDiagramViewerComponent: Observe SVG, compute fit/scale
User->>SchemaDiagramViewerComponent: Zoom / Pan / Double-click entity
SchemaDiagramViewerComponent->>User: Update viewport / highlight entity
User->>ChatPanel: Submit schema change prompt
ChatPanel->>EditDatabaseSchemaComponent: onSubmit()
EditDatabaseSchemaComponent->>EditDatabaseSchemaComponent: _buildMermaidFromChanges(SQL)
EditDatabaseSchemaComponent->>SchemaDiagramViewerComponent: Append diagram message (mermaid ER)
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Suggested reviewers
Poem
🚥 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)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
ESLint skipped: no ESLint configuration detected in root package.json. To enable, add 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
Note
Copilot was unable to run its full agentic suite in this review.
Adds a dedicated schema diagram viewer and refactors the schema editor UI to show an interactive diagram alongside a docked chat panel, including generation of a “schema preview” diagram from AI-generated SQL changes.
Changes:
- Introduces
SchemaDiagramViewerComponentwith pan/zoom, fit-to-screen, table search, and minimap. - Refactors Edit Database Schema view into a two-column layout (diagram canvas + chat panel) and removes legacy diagram zoom controls.
- Generates a Mermaid ER preview diagram from
CREATE TABLEchanges and inserts it into the message stream.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| frontend/src/app/components/edit-database-schema/schema-diagram-viewer/schema-diagram-viewer.component.ts | New interactive viewer logic (transform, pan/zoom, minimap cloning, table list). |
| frontend/src/app/components/edit-database-schema/schema-diagram-viewer/schema-diagram-viewer.component.html | Viewer template with toolbar, sidebar, viewport interactions, minimap. |
| frontend/src/app/components/edit-database-schema/schema-diagram-viewer/schema-diagram-viewer.component.css | Viewer styling for layout, sidebar, minimap, highlight animation. |
| frontend/src/app/components/edit-database-schema/edit-database-schema.component.ts | Adds computed diagram selection + Mermaid preview builder; wires in new viewer component. |
| frontend/src/app/components/edit-database-schema/edit-database-schema.component.html | Reworks UI into diagram canvas + right chat panel; removes old inline diagram rendering/zoom. |
| frontend/src/app/components/edit-database-schema/edit-database-schema.component.css | Updates styles for new “schema-editor” layout, panel, and responsive behavior. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| const minimap = this.minimapRef?.nativeElement; | ||
| if (!viewport) return; | ||
| this._resizeObserver = new ResizeObserver(() => { | ||
| const vpRect = viewport.getBoundingClientRect(); | ||
| this.viewportSize.set({ w: vpRect.width, h: vpRect.height }); | ||
| if (minimap) { | ||
| const mmRect = minimap.getBoundingClientRect(); | ||
| this.minimapSize.set({ w: mmRect.width, h: mmRect.height }); | ||
| } | ||
| }); | ||
| this._resizeObserver.observe(viewport); | ||
| if (minimap) this._resizeObserver.observe(minimap); |
| private _renderMinimapClone(svg: SVGSVGElement) { | ||
| const host = this.minimapCanvasRef?.nativeElement; | ||
| if (!host) return; | ||
| const { w, h } = this.svgSize(); | ||
| if (!w || !h) return; | ||
| host.innerHTML = ''; | ||
| const clone = svg.cloneNode(true) as SVGSVGElement; | ||
| clone.removeAttribute('id'); | ||
| clone.removeAttribute('style'); | ||
| clone.style.display = 'block'; | ||
| clone.style.margin = '0'; | ||
| clone.style.pointerEvents = 'none'; | ||
| clone.setAttribute('width', String(w)); | ||
| clone.setAttribute('height', String(h)); | ||
| host.appendChild(clone); | ||
| } |
| (wheel)="onWheel($event)" | ||
| (dblclick)="onDoubleClick($event)"> | ||
| <div #canvas class="schema-diagram__canvas" [style.transform]="transformStyle()"> | ||
| <markdown mermaid [data]="_source()"></markdown> |
| <button mat-icon-button type="button" matTooltip="Toggle tables list" | ||
| [class.schema-diagram__toolbar-button--active]="sidebarOpen()" | ||
| (click)="onToggleSidebar()"> | ||
| <mat-icon>list</mat-icon> | ||
| </button> | ||
| <button mat-icon-button type="button" matTooltip="Toggle minimap" | ||
| [class.schema-diagram__toolbar-button--active]="minimapOpen()" | ||
| (click)="onToggleMinimap()"> | ||
| <mat-icon>map</mat-icon> | ||
| </button> | ||
| <span class="schema-diagram__toolbar-divider"></span> | ||
| <button mat-icon-button type="button" matTooltip="Zoom out" (click)="onZoomOut()"> | ||
| <mat-icon>remove</mat-icon> | ||
| </button> | ||
| <span class="schema-diagram__zoom-label">{{ scaleLabel() }}</span> | ||
| <button mat-icon-button type="button" matTooltip="Zoom in" (click)="onZoomIn()"> | ||
| <mat-icon>add</mat-icon> | ||
| </button> | ||
| <button mat-icon-button type="button" matTooltip="Fit to screen" (click)="onFitToScreen()"> | ||
| <mat-icon>fit_screen</mat-icon> | ||
| </button> | ||
| <button mat-icon-button type="button" matTooltip="Reset view" (click)="onZoomReset()"> |
| this._renderMinimapClone(svg); | ||
| this.svgReady.set(true); | ||
| requestAnimationFrame(() => this.onFitToScreen()); | ||
| setTimeout(() => this.onFitToScreen(), 80); |
| private _buildMermaidFromChanges(changes: SchemaChangeResponse[]): string { | ||
| const tables: { name: string; columns: { type: string; name: string; pk: boolean; fk: boolean }[] }[] = []; | ||
| const relations: { from: string; to: string }[] = []; | ||
| const isCreate = /^\s*CREATE\s+TABLE/i; | ||
|
|
||
| for (const change of changes) { | ||
| const sql = change.forwardSql ?? ''; | ||
| if (!isCreate.test(sql)) continue; | ||
| const tableMatch = sql.match(/CREATE\s+TABLE\s+(?:IF\s+NOT\s+EXISTS\s+)?["`]?(\w+)["`]?\s*\(([\s\S]*)\)\s*;?\s*$/i); | ||
| if (!tableMatch) continue; | ||
| const tableName = tableMatch[1]; | ||
| const body = tableMatch[2]; | ||
|
|
||
| const parts: string[] = []; | ||
| let depth = 0; | ||
| let buf = ''; | ||
| for (const ch of body) { | ||
| if (ch === '(') depth++; | ||
| else if (ch === ')') depth--; | ||
| if (ch === ',' && depth === 0) { | ||
| if (buf.trim()) parts.push(buf.trim()); | ||
| buf = ''; | ||
| } else { | ||
| buf += ch; | ||
| } | ||
| } | ||
| if (buf.trim()) parts.push(buf.trim()); |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (3)
frontend/src/app/components/edit-database-schema/edit-database-schema.component.css (1)
464-490: 💤 Low valueStylelint errors for
::ng-deepare expected in Angular.The static analysis flags
::ng-deepas an unknown pseudo-element, but this is the standard Angular pattern for styling encapsulated Material components. Consider configuring Stylelint to recognize Angular pseudo-elements:{ "rules": { "selector-pseudo-element-no-unknown": [ true, { "ignorePseudoElements": ["ng-deep"] } ] } }Note:
::ng-deepis deprecated but Angular hasn't provided a full replacement yet, so this usage is acceptable for Material component styling.🤖 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/edit-database-schema/edit-database-schema.component.css` around lines 464 - 490, Stylelint flags the Angular pseudo-element ::ng-deep in edit-database-schema.component.css as unknown; update the Stylelint configuration to allow Angular pseudo-elements by adding the selector-pseudo-element-no-unknown rule with an ignorePseudoElements entry for "ng-deep" (so selectors like .schema-editor__input-field ::ng-deep ... and related Material selectors are accepted); modify your global Stylelint config (e.g., .stylelintrc) to include "selector-pseudo-element-no-unknown": [true, { "ignorePseudoElements": ["ng-deep"] }] so the component CSS passes linting while preserving the existing ::ng-deep usage.frontend/src/app/components/edit-database-schema/edit-database-schema.component.ts (1)
94-94: 💤 Low valueAdd explicit return type annotation to async method.
The async methods
onSubmit,onApprove,onReject, and_loadDiagramare missing explicitPromise<void>return type annotations.📝 Example fix
- async onSubmit() { + async onSubmit(): Promise<void> {Apply the same pattern to
onApprove(),onReject(), and_loadDiagram().🤖 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/edit-database-schema/edit-database-schema.component.ts` at line 94, The async methods onSubmit, onApprove, onReject, and _loadDiagram in EditDatabaseSchemaComponent are missing explicit return types; update each method signature to include an explicit Promise<void> return type (e.g., change "async onSubmit()" to "async onSubmit(): Promise<void>" and apply the same change to onApprove(), onReject(), and _loadDiagram()) so TypeScript accurately reflects their async void-like behavior.frontend/src/app/components/edit-database-schema/schema-diagram-viewer/schema-diagram-viewer.component.ts (1)
171-452: ⚡ Quick winAdd explicit return types to class methods.
Multiple methods (for example Line 171, Line 175, Line 179, Line 184, Line 206, Line 223, and private helpers through Line 452) omit explicit return type annotations.
As per coding guidelines, "Always add type annotations to function parameters and return types in TypeScript".Example pattern
-onZoomIn() { +onZoomIn(): void { this._zoomAt(this.scale() + ZOOM_STEP); }🤖 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/edit-database-schema/schema-diagram-viewer/schema-diagram-viewer.component.ts` around lines 171 - 452, The methods in SchemaDiagramViewerComponent (e.g., onZoomIn, onZoomOut, onZoomReset, onFitToScreen, onPanStart, onWheel, onDoubleClick, onFocusTable, onMinimapMouseDown, onToggleSidebar, onToggleMinimap and private helpers like _handlePanMove, _handlePanEnd, _handleMinimapDragMove, _handleMinimapDragEnd, _centerMinimapAt, _zoomAt, _centerContent, _observeRender, _observeResize, _prepareSvg, _renderMinimapClone, _findEntityNode, _findNodeByName, _focusElement) lack explicit return type annotations; update each signature to include the proper TypeScript return type (e.g., : void for methods that do not return, : SVGGraphicsElement | null for _findEntityNode/_findNodeByName, etc.), ensuring the types match their actual return values and keeping parameter types as-is. Make these changes directly on the method declarations so IDE/typechecker will enforce the annotations.
🤖 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/edit-database-schema/schema-diagram-viewer/schema-diagram-viewer.component.css`:
- Around line 262-277: The Stylelint errors are caused by Angular deep selectors
used in the rules for .schema-diagram__canvas ::ng-deep markdown,
.schema-diagram__canvas ::ng-deep svg and related .schema-diagram__highlight
rules; wrap this block with a local Stylelint suppression (disable before the
block and re-enable after) so CI stops flagging unknown selectors (e.g., use the
appropriate stylelint-disable comment for unknown pseudo-class/selector and
restore with stylelint-enable) while leaving the selectors themselves unchanged.
In
`@frontend/src/app/components/edit-database-schema/schema-diagram-viewer/schema-diagram-viewer.component.ts`:
- Around line 25-39: The `@Component` metadata for SchemaDiagramViewerComponent
(selector 'app-schema-diagram-viewer' in schema-diagram-viewer.component.ts) is
missing standalone: true; add standalone: true to the component decorator so the
existing imports array is valid and the component complies with the Angular 19
standalone component pattern.
---
Nitpick comments:
In
`@frontend/src/app/components/edit-database-schema/edit-database-schema.component.css`:
- Around line 464-490: Stylelint flags the Angular pseudo-element ::ng-deep in
edit-database-schema.component.css as unknown; update the Stylelint
configuration to allow Angular pseudo-elements by adding the
selector-pseudo-element-no-unknown rule with an ignorePseudoElements entry for
"ng-deep" (so selectors like .schema-editor__input-field ::ng-deep ... and
related Material selectors are accepted); modify your global Stylelint config
(e.g., .stylelintrc) to include "selector-pseudo-element-no-unknown": [true, {
"ignorePseudoElements": ["ng-deep"] }] so the component CSS passes linting while
preserving the existing ::ng-deep usage.
In
`@frontend/src/app/components/edit-database-schema/edit-database-schema.component.ts`:
- Line 94: The async methods onSubmit, onApprove, onReject, and _loadDiagram in
EditDatabaseSchemaComponent are missing explicit return types; update each
method signature to include an explicit Promise<void> return type (e.g., change
"async onSubmit()" to "async onSubmit(): Promise<void>" and apply the same
change to onApprove(), onReject(), and _loadDiagram()) so TypeScript accurately
reflects their async void-like behavior.
In
`@frontend/src/app/components/edit-database-schema/schema-diagram-viewer/schema-diagram-viewer.component.ts`:
- Around line 171-452: The methods in SchemaDiagramViewerComponent (e.g.,
onZoomIn, onZoomOut, onZoomReset, onFitToScreen, onPanStart, onWheel,
onDoubleClick, onFocusTable, onMinimapMouseDown, onToggleSidebar,
onToggleMinimap and private helpers like _handlePanMove, _handlePanEnd,
_handleMinimapDragMove, _handleMinimapDragEnd, _centerMinimapAt, _zoomAt,
_centerContent, _observeRender, _observeResize, _prepareSvg,
_renderMinimapClone, _findEntityNode, _findNodeByName, _focusElement) lack
explicit return type annotations; update each signature to include the proper
TypeScript return type (e.g., : void for methods that do not return, :
SVGGraphicsElement | null for _findEntityNode/_findNodeByName, etc.), ensuring
the types match their actual return values and keeping parameter types as-is.
Make these changes directly on the method declarations so IDE/typechecker will
enforce the annotations.
🪄 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: a33b5e12-f7bd-41f8-aad4-15de63dd1d12
📒 Files selected for processing (6)
frontend/src/app/components/edit-database-schema/edit-database-schema.component.cssfrontend/src/app/components/edit-database-schema/edit-database-schema.component.htmlfrontend/src/app/components/edit-database-schema/edit-database-schema.component.tsfrontend/src/app/components/edit-database-schema/schema-diagram-viewer/schema-diagram-viewer.component.cssfrontend/src/app/components/edit-database-schema/schema-diagram-viewer/schema-diagram-viewer.component.htmlfrontend/src/app/components/edit-database-schema/schema-diagram-viewer/schema-diagram-viewer.component.ts
| .schema-diagram__canvas ::ng-deep markdown, | ||
| .schema-diagram__canvas ::ng-deep markdown > * { | ||
| display: block; | ||
| margin: 0 !important; | ||
| padding: 0 !important; | ||
| line-height: 0; | ||
| } | ||
|
|
||
| .schema-diagram__canvas ::ng-deep svg { | ||
| max-width: none !important; | ||
| max-height: none !important; | ||
| display: block; | ||
| margin: 0 !important; | ||
| } | ||
|
|
||
| .schema-diagram__canvas ::ng-deep .schema-diagram__highlight { |
There was a problem hiding this comment.
Resolve Stylelint blockers for Angular deep selectors.
Line 262–Line 277 use ::ng-deep and markdown selectors that Stylelint currently flags as unknown, which will block lint checks. Please add a local suppression around this block (or update lint config) so CI stays green.
Proposed lint-safe patch
+/* stylelint-disable selector-pseudo-element-no-unknown, selector-type-no-unknown */
.schema-diagram__canvas ::ng-deep markdown,
.schema-diagram__canvas ::ng-deep markdown > * {
display: block;
margin: 0 !important;
padding: 0 !important;
line-height: 0;
}
.schema-diagram__canvas ::ng-deep svg {
max-width: none !important;
max-height: none !important;
display: block;
margin: 0 !important;
}
.schema-diagram__canvas ::ng-deep .schema-diagram__highlight {
animation: highlight-pulse 1.6s ease;
}
+/* stylelint-enable selector-pseudo-element-no-unknown, selector-type-no-unknown */🧰 Tools
🪛 Stylelint (17.11.1)
[error] 262-262: Unknown pseudo-element selector "::ng-deep" (selector-pseudo-element-no-unknown)
(selector-pseudo-element-no-unknown)
[error] 263-263: Unknown pseudo-element selector "::ng-deep" (selector-pseudo-element-no-unknown)
(selector-pseudo-element-no-unknown)
[error] 270-270: Unknown pseudo-element selector "::ng-deep" (selector-pseudo-element-no-unknown)
(selector-pseudo-element-no-unknown)
[error] 277-277: Unknown pseudo-element selector "::ng-deep" (selector-pseudo-element-no-unknown)
(selector-pseudo-element-no-unknown)
[error] 262-262: Unknown type selector "markdown" (selector-type-no-unknown)
(selector-type-no-unknown)
[error] 263-263: Unknown type selector "markdown" (selector-type-no-unknown)
(selector-type-no-unknown)
🤖 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/edit-database-schema/schema-diagram-viewer/schema-diagram-viewer.component.css`
around lines 262 - 277, The Stylelint errors are caused by Angular deep
selectors used in the rules for .schema-diagram__canvas ::ng-deep markdown,
.schema-diagram__canvas ::ng-deep svg and related .schema-diagram__highlight
rules; wrap this block with a local Stylelint suppression (disable before the
block and re-enable after) so CI stops flagging unknown selectors (e.g., use the
appropriate stylelint-disable comment for unknown pseudo-class/selector and
restore with stylelint-enable) while leaving the selectors themselves unchanged.
| @Component({ | ||
| selector: 'app-schema-diagram-viewer', | ||
| templateUrl: './schema-diagram-viewer.component.html', | ||
| styleUrls: ['./schema-diagram-viewer.component.css'], | ||
| imports: [ | ||
| CommonModule, | ||
| FormsModule, | ||
| MatButtonModule, | ||
| MatFormFieldModule, | ||
| MatIconModule, | ||
| MatInputModule, | ||
| MatTooltipModule, | ||
| MarkdownModule, | ||
| ], | ||
| }) |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
find . -type f -name "schema-diagram-viewer.component.ts" | head -5Repository: rocket-admin/rocketadmin
Length of output: 176
🏁 Script executed:
cat -n "./frontend/src/app/components/edit-database-schema/schema-diagram-viewer/schema-diagram-viewer.component.ts" | head -60Repository: rocket-admin/rocketadmin
Length of output: 2193
🏁 Script executed:
cat -n "./frontend/src/app/components/edit-database-schema/schema-diagram-viewer/schema-diagram-viewer.component.ts" | sed -n '40,150p'Repository: rocket-admin/rocketadmin
Length of output: 4728
🏁 Script executed:
wc -l "./frontend/src/app/components/edit-database-schema/schema-diagram-viewer/schema-diagram-viewer.component.ts"Repository: rocket-admin/rocketadmin
Length of output: 180
🏁 Script executed:
cat -n "./frontend/src/app/components/edit-database-schema/schema-diagram-viewer/schema-diagram-viewer.component.ts" | sed -n '148,250p'Repository: rocket-admin/rocketadmin
Length of output: 3687
🏁 Script executed:
cat -n "./frontend/src/app/components/edit-database-schema/schema-diagram-viewer/schema-diagram-viewer.component.ts" | sed -n '25,39p'Repository: rocket-admin/rocketadmin
Length of output: 501
Add standalone: true to the component metadata.
The imports array in a component decorator requires standalone: true to be present. Without it, Angular compilation will fail.
Proposed fix
`@Component`({
selector: 'app-schema-diagram-viewer',
+ standalone: true,
templateUrl: './schema-diagram-viewer.component.html',
styleUrls: ['./schema-diagram-viewer.component.css'],
imports: [Per coding guidelines: "Use standalone components in Angular 19 frontend (no NgModules)".
📝 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.
| @Component({ | |
| selector: 'app-schema-diagram-viewer', | |
| templateUrl: './schema-diagram-viewer.component.html', | |
| styleUrls: ['./schema-diagram-viewer.component.css'], | |
| imports: [ | |
| CommonModule, | |
| FormsModule, | |
| MatButtonModule, | |
| MatFormFieldModule, | |
| MatIconModule, | |
| MatInputModule, | |
| MatTooltipModule, | |
| MarkdownModule, | |
| ], | |
| }) | |
| `@Component`({ | |
| selector: 'app-schema-diagram-viewer', | |
| standalone: true, | |
| templateUrl: './schema-diagram-viewer.component.html', | |
| styleUrls: ['./schema-diagram-viewer.component.css'], | |
| imports: [ | |
| CommonModule, | |
| FormsModule, | |
| MatButtonModule, | |
| MatFormFieldModule, | |
| MatIconModule, | |
| MatInputModule, | |
| MatTooltipModule, | |
| MarkdownModule, | |
| ], | |
| }) |
🤖 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/edit-database-schema/schema-diagram-viewer/schema-diagram-viewer.component.ts`
around lines 25 - 39, The `@Component` metadata for SchemaDiagramViewerComponent
(selector 'app-schema-diagram-viewer' in schema-diagram-viewer.component.ts) is
missing standalone: true; add standalone: true to the component decorator so the
existing imports array is valid and the component complies with the Angular 19
standalone component pattern.
Remove the corner minimap (clone, viewport rectangle, drag handlers, toggle, and resize tracking). Introduce a baseScale signal that holds the fit-to-screen scale, and display zoom as a percentage relative to it so 100% = filling the visible area. Zoom in/out steps and clamps are expressed relative to baseScale (20%–800% of fit), so users always have the same headroom to zoom in regardless of how big or small the diagram is. Reset view now re-runs fit-to-screen. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Switch the Schema Preview builder from regex/comma-splitting to a real SQL parser via node-sql-parser (PostgresQL with MySQL fallback) so multi-line constraints, quoted identifiers, dialect-specific suffixes, and standalone PRIMARY/FOREIGN KEY declarations are all picked up correctly. Rejecting a batch now also wipes any "Schema Preview" diagram message it produced. Refresh the empty-database welcome screen: replace the rocket with a dashboard-style icon-box around the Material "schema" glyph, retitle to "Generate your first table to start managing data", and show four template cards (E-commerce, Blog, Project management, CRM) listing their tables. In the right-docked Schema Assistant panel, the "Try asking" examples are pinned near the input and only render when the connection has no tables; prompt textarea grows with content via cdkTextareaAutosize. User messages keep a bubble while AI replies blend into the panel background. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Push the "Describe what you need…" hint down with a 40px top margin so it breathes from the top of the panel, and rename the templates section heading to "or use a template" for clarity. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
🧹 Nitpick comments (1)
frontend/src/app/components/edit-database-schema/schema-diagram-viewer/schema-diagram-viewer.component.ts (1)
124-333: ⚡ Quick winAdd explicit return type annotations to all void methods.
All 16 methods in this range lack return type annotations, violating the TypeScript guideline. Each method either has no return statement or early returns without a value, so they should all be annotated with
: void.Proposed patch
-onZoomIn() { +onZoomIn(): void { this._zoomAt(this.scale() + this.baseScale() * ZOOM_STEP); } -onZoomOut() { +onZoomOut(): void { this._zoomAt(this.scale() - this.baseScale() * ZOOM_STEP); } -onZoomReset() { +onZoomReset(): void { this.onFitToScreen(); } -onFitToScreen() { +onFitToScreen(): void { // ... } -onPanStart(event: MouseEvent) { +onPanStart(event: MouseEvent): void { // ... } -onWheel(event: WheelEvent) { +onWheel(event: WheelEvent): void { // ... } -onDoubleClick(event: MouseEvent) { +onDoubleClick(event: MouseEvent): void { // ... } -onFocusTable(name: string) { +onFocusTable(name: string): void { // ... } -onToggleSidebar() { +onToggleSidebar(): void { this.sidebarOpen.update(v => !v); } -private _handlePanMove(event: MouseEvent) { +private _handlePanMove(event: MouseEvent): void { // ... } -private _handlePanEnd() { +private _handlePanEnd(): void { // ... } -private _zoomAt(targetScale: number, originX?: number, originY?: number) { +private _zoomAt(targetScale: number, originX?: number, originY?: number): void { // ... } -private _observeRender() { +private _observeRender(): void { // ... } -private _observeResize() { +private _observeResize(): void { // ... } -private _prepareSvg(svg: SVGSVGElement) { +private _prepareSvg(svg: SVGSVGElement): void { // ... } -private _focusElement(node: SVGGraphicsElement) { +private _focusElement(node: SVGGraphicsElement): 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/edit-database-schema/schema-diagram-viewer/schema-diagram-viewer.component.ts` around lines 124 - 333, Add explicit TypeScript void return annotations to each method in this component that currently lacks one; specifically update onZoomIn, onZoomOut, onZoomReset, onFitToScreen, onPanStart, onWheel, onDoubleClick, onFocusTable, onToggleSidebar, _handlePanMove, _handlePanEnd, _zoomAt, _observeRender, _observeResize, _prepareSvg, _findEntityNode, _findNodeByName, and _focusElement to declare a return type of : void (or for methods that conceptually return nullable elements keep : SVGGraphicsElement | null for the two finder methods if appropriate, otherwise : void). Ensure the signature changes only add the return type annotation and do not change implementation or behavior.
🤖 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.
Nitpick comments:
In
`@frontend/src/app/components/edit-database-schema/schema-diagram-viewer/schema-diagram-viewer.component.ts`:
- Around line 124-333: Add explicit TypeScript void return annotations to each
method in this component that currently lacks one; specifically update onZoomIn,
onZoomOut, onZoomReset, onFitToScreen, onPanStart, onWheel, onDoubleClick,
onFocusTable, onToggleSidebar, _handlePanMove, _handlePanEnd, _zoomAt,
_observeRender, _observeResize, _prepareSvg, _findEntityNode, _findNodeByName,
and _focusElement to declare a return type of : void (or for methods that
conceptually return nullable elements keep : SVGGraphicsElement | null for the
two finder methods if appropriate, otherwise : void). Ensure the signature
changes only add the return type annotation and do not change implementation or
behavior.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 5b51f2a5-7c6f-4a31-9249-1f96b64f0ca0
⛔ Files ignored due to path filters (1)
frontend/yarn.lockis excluded by!**/yarn.lock,!**/*.lock
📒 Files selected for processing (6)
frontend/src/app/components/edit-database-schema/edit-database-schema.component.cssfrontend/src/app/components/edit-database-schema/edit-database-schema.component.htmlfrontend/src/app/components/edit-database-schema/edit-database-schema.component.tsfrontend/src/app/components/edit-database-schema/schema-diagram-viewer/schema-diagram-viewer.component.cssfrontend/src/app/components/edit-database-schema/schema-diagram-viewer/schema-diagram-viewer.component.htmlfrontend/src/app/components/edit-database-schema/schema-diagram-viewer/schema-diagram-viewer.component.ts
🚧 Files skipped from review as they are similar to previous changes (1)
- frontend/src/app/components/edit-database-schema/edit-database-schema.component.ts
Add node-sql-parser to frontend/package.json so the lockfile and CI's immutable install agree; the AST-based Schema Preview builder was already using it. Move the "Describe what you need…" hint out of the chat panel empty state and into the empty-DB welcome screen as a subtitle under a shorter "Create your first table" title; keep the chat-panel hint only when a diagram is already loaded. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Wrap title and subtitle in a single heading block with its own 4px gap so "Describe what you need and AI will generate the SQL" sits right under "Create your first table" instead of inheriting the 16px welcome gap. Drop the trailing period from the subtitle. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replace the raw SQL block AI returns with a structured change card per change: action label + icon tinted by tone (add / edit / remove), table name as a monospaced heading, free-text aiSummary, and a column grid for CREATE TABLE entries that lines up the type/badge columns across rows via CSS subgrid (display: contents). Columns get PK/FK badges (with tooltips showing the referenced table), plus NOT NULL / UNIQUE / DEFAULT chips. Raw SQL is still available, but tucked behind a "View SQL" details toggle. Recolor the schema diagram in dark mode via mermaid themeVariables + CSS safety net: dark violet backgrounds (#1d143a), muted purple borders (#3d2b6e), light-lilac text and edges, no alternating row stripes — so the diagram has a Rocketadmin-violet feel instead of bare mermaid gray. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
For freshly created, table-less connections the diagram endpoint returns
a non-empty string like just "erDiagram\n", which used to fool the
component into rendering an empty diagram viewer instead of the welcome
state with the template cards. Add a guard that checks for at least one
"NAME {" entity declaration in the mermaid source before pushing the
diagram message — when there are no entities, currentDiagram() stays
null and the welcome / templates screen renders.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
frontend/src/app/components/edit-database-schema/edit-database-schema.component.ts (1)
263-267:⚠️ Potential issue | 🟠 Major | ⚡ Quick winUse the correct node-sql-parser PostgreSQL dialect token.
At lines 263 and 438,
'PostgresQL'is invalid; the correct dialect identifier is'Postgresql'. Using the wrong token causes the parser to fail and fall back to MySQL, breaking PostgreSQL-specific SQL parsing.Proposed fix
- parsed = parser.astify(sql, { database: 'PostgresQL' }); + parsed = parser.astify(sql, { database: 'Postgresql' }); ... - ast = parser.astify(sql, { database: 'PostgresQL' }); + ast = parser.astify(sql, { database: 'Postgresql' });🤖 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/edit-database-schema/edit-database-schema.component.ts` around lines 263 - 267, The parser is using the wrong PostgreSQL dialect token ('PostgresQL') in the parser.astify calls, causing incorrect fallback to MySQL; update the dialect token to 'Postgresql' in the parser.astify invocations (the ones that assign to parsed using parser.astify(sql, { database: 'PostgresQL' })) in edit-database-schema.component.ts so PostgreSQL-specific SQL parses correctly.
🤖 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.
Outside diff comments:
In
`@frontend/src/app/components/edit-database-schema/edit-database-schema.component.ts`:
- Around line 263-267: The parser is using the wrong PostgreSQL dialect token
('PostgresQL') in the parser.astify calls, causing incorrect fallback to MySQL;
update the dialect token to 'Postgresql' in the parser.astify invocations (the
ones that assign to parsed using parser.astify(sql, { database: 'PostgresQL' }))
in edit-database-schema.component.ts so PostgreSQL-specific SQL parses
correctly.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: c4857e32-4e48-4c14-91aa-d5144155bade
⛔ Files ignored due to path filters (1)
frontend/yarn.lockis excluded by!**/yarn.lock,!**/*.lock
📒 Files selected for processing (6)
frontend/package.jsonfrontend/src/app/components/edit-database-schema/edit-database-schema.component.cssfrontend/src/app/components/edit-database-schema/edit-database-schema.component.htmlfrontend/src/app/components/edit-database-schema/edit-database-schema.component.tsfrontend/src/app/components/edit-database-schema/schema-diagram-viewer/schema-diagram-viewer.component.cssfrontend/src/main.ts
✅ Files skipped from review due to trivial changes (1)
- frontend/package.json
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
frontend/src/app/components/edit-database-schema/edit-database-schema.component.ts (1)
237-258:⚠️ Potential issue | 🟠 Major | ⚡ Quick winClear the previous diagram when the refreshed Mermaid is empty.
If
fetchDiagram()returns onlyerDiagram\nafter a non-empty schema was already shown, this branch does nothing and leaves the olddiagrammessage inmessages. SincecurrentDiagramresolves from stored diagram messages, the viewer can keep rendering stale schema state instead of falling back to the empty/welcome screen.Suggested fix
private async _loadDiagram(label: string) { this.initialDiagramLoading.set(true); try { const diagram = await this._tableSchema.fetchDiagram(this.connectionID); const source = diagram?.diagram ?? ''; - if (this._mermaidHasEntities(source)) { - this.messages.update(msgs => [...msgs, { - role: 'diagram' as const, - text: label, - diagramSource: '```mermaid\n' + source + '\n```', - }]); - } + this.messages.update(msgs => { + const next = msgs.filter(m => m.role !== 'diagram'); + if (this._mermaidHasEntities(source)) { + next.push({ + role: 'diagram', + text: label, + diagramSource: `\`\`\`mermaid\n${source}\n\`\`\``, + }); + } + return next; + }); } catch { // Diagram is supplementary - don't show error if it fails } finally { this.initialDiagramLoading.set(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/edit-database-schema/edit-database-schema.component.ts` around lines 237 - 258, When refresh returns an empty Mermaid source the old diagram message remains, so update the messages state in the fetchDiagram flow to always remove existing diagram messages before optionally adding the new one: in the block that currently calls this.messages.update(...) replace the simple append with a messages.update that filters out msgs with role === 'diagram' and then, only if this._mermaidHasEntities(source) is true, push the new diagram object; reference the existing symbols this.messages.update, this._mermaidHasEntities(source) and the diagram message shape (role: 'diagram', text: label, diagramSource) so currentDiagram will fall back correctly when the new source is empty.
🤖 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.
Outside diff comments:
In
`@frontend/src/app/components/edit-database-schema/edit-database-schema.component.ts`:
- Around line 237-258: When refresh returns an empty Mermaid source the old
diagram message remains, so update the messages state in the fetchDiagram flow
to always remove existing diagram messages before optionally adding the new one:
in the block that currently calls this.messages.update(...) replace the simple
append with a messages.update that filters out msgs with role === 'diagram' and
then, only if this._mermaidHasEntities(source) is true, push the new diagram
object; reference the existing symbols this.messages.update,
this._mermaidHasEntities(source) and the diagram message shape (role: 'diagram',
text: label, diagramSource) so currentDiagram will fall back correctly when the
new source is empty.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 5bb17e23-51eb-44f0-a028-9a130cba57d1
📒 Files selected for processing (1)
frontend/src/app/components/edit-database-schema/edit-database-schema.component.ts
Summary
SchemaDiagramViewercomponent with mouse pan (grab cursor), wheel-anchored zoom, double-click table focus, Fit to screen + Reset view toolbar, and a floating searchable tables sidebar that lets you center on any table.CREATE TABLESQL is parsed on the frontend vianode-sql-parser(PostgresQL → MySQL fallback) and turned into a Schema Preview mermaid ER diagram shown live on the canvas before the user applies; rejecting the batch wipes the preview.schemaglyph, "Generate your first table to start managing data", and four template cards (E-commerce, Blog, Project management, CRM) listing the tables each generates.cdkTextareaAutosize; "Try asking" examples pinned near the input (only when the connection has no tables); user messages keep a bubble while AI replies blend into the panel background.Test plan
/edit-database-schema/<connection-id>for a connection with tables — diagram fills the canvas; zoom indicator reads 100%🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Style