Skip to content

Commit 61d38c7

Browse files
feat(edit-schema): better empty state, template cards, AST-based preview
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>
1 parent a45b454 commit 61d38c7

4 files changed

Lines changed: 420 additions & 103 deletions

File tree

frontend/src/app/components/edit-database-schema/edit-database-schema.component.css

Lines changed: 214 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -95,15 +95,23 @@
9595
overflow-y: auto;
9696
}
9797

98-
.schema-editor__welcome-icon {
99-
width: 48px !important;
100-
height: 48px !important;
101-
animation: rocket-float 3s ease-in-out infinite;
98+
.schema-editor__welcome-icon-box {
99+
width: 48px;
100+
height: 48px;
101+
border-radius: 12px;
102+
background: color-mix(in srgb, var(--color-accentedPalette-500), transparent 88%);
103+
display: flex;
104+
align-items: center;
105+
justify-content: center;
106+
margin-bottom: 4px;
102107
}
103108

104-
@keyframes rocket-float {
105-
0%, 100% { transform: translateY(0) rotate(0deg); }
106-
50% { transform: translateY(-2px) rotate(2deg); }
109+
.schema-editor__welcome-icon {
110+
color: var(--color-accentedPalette-500);
111+
font-size: 26px !important;
112+
width: 26px !important;
113+
height: 26px !important;
114+
transform: rotate(-90deg);
107115
}
108116

109117
.schema-editor__welcome-title {
@@ -130,26 +138,146 @@
130138
}
131139
}
132140

141+
.schema-editor__suggestions-block {
142+
display: flex;
143+
flex-direction: column;
144+
align-items: center;
145+
gap: 6px;
146+
margin-top: 8px;
147+
}
148+
149+
.schema-editor__suggestions-heading {
150+
font-size: 12px;
151+
font-weight: 500;
152+
text-transform: uppercase;
153+
letter-spacing: 0.6px;
154+
color: rgba(0, 0, 0, 0.42);
155+
margin: 0;
156+
text-align: center;
157+
}
158+
159+
@media (prefers-color-scheme: dark) {
160+
.schema-editor__suggestions-heading {
161+
color: rgba(255, 255, 255, 0.45);
162+
}
163+
}
164+
133165
.schema-editor__suggestions {
134166
display: flex;
135167
flex-wrap: wrap;
136168
justify-content: center;
137169
gap: 8px;
138-
margin-top: 8px;
170+
margin-top: 0;
171+
}
172+
173+
.schema-editor__templates {
174+
display: grid;
175+
grid-template-columns: repeat(2, minmax(0, 1fr));
176+
gap: 6px;
177+
width: 100%;
178+
max-width: 460px;
179+
}
180+
181+
.template-card {
182+
display: flex;
183+
flex-direction: column;
184+
gap: 4px;
185+
padding: 8px 10px;
186+
text-align: left;
187+
background: var(--mat-sidenav-content-background-color);
188+
border: 1px solid rgba(0, 0, 0, 0.1);
189+
border-radius: 8px;
190+
cursor: pointer;
191+
transition: border-color 0.15s ease, background-color 0.15s ease, box-shadow 0.15s ease;
192+
}
193+
194+
.template-card:hover {
195+
border-color: var(--color-accentedPalette-500);
196+
box-shadow: 0 1px 0 0 color-mix(in srgb, var(--color-accentedPalette-500), transparent 80%);
197+
}
198+
199+
@media (prefers-color-scheme: dark) {
200+
.template-card {
201+
border-color: rgba(255, 255, 255, 0.12);
202+
color: rgba(255, 255, 255, 0.9);
203+
}
204+
}
205+
206+
.template-card__head {
207+
display: flex;
208+
align-items: center;
209+
gap: 8px;
210+
min-width: 0;
211+
}
212+
213+
.template-card__icon-box {
214+
flex-shrink: 0;
215+
width: 20px;
216+
height: 20px;
217+
border-radius: 5px;
218+
display: flex;
219+
align-items: center;
220+
justify-content: center;
221+
background: color-mix(in srgb, var(--color-accentedPalette-500), transparent 88%);
222+
}
223+
224+
.template-card__icon {
225+
font-size: 13px !important;
226+
width: 13px !important;
227+
height: 13px !important;
228+
color: var(--color-accentedPalette-500);
229+
}
230+
231+
.template-card__title {
232+
flex: 1;
233+
font-size: 12.5px;
234+
font-weight: 600;
235+
color: rgba(0, 0, 0, 0.88);
236+
line-height: 1.25;
237+
white-space: nowrap;
238+
overflow: hidden;
239+
text-overflow: ellipsis;
240+
}
241+
242+
@media (prefers-color-scheme: dark) {
243+
.template-card__title {
244+
color: rgba(255, 255, 255, 0.92);
245+
}
246+
}
247+
248+
.template-card__tables {
249+
font-size: 11px;
250+
color: rgba(0, 0, 0, 0.5);
251+
line-height: 1.35;
252+
}
253+
254+
@media (prefers-color-scheme: dark) {
255+
.template-card__tables {
256+
color: rgba(255, 255, 255, 0.5);
257+
}
139258
}
140259

141260
.suggestion-chip {
142261
display: inline-flex;
143262
align-items: center;
263+
gap: 6px;
144264
background-color: var(--mat-sidenav-content-background-color);
145265
border: 1px solid #d3d3d3;
146266
border-radius: 16px;
147-
padding: 6px 14px;
267+
padding: 6px 14px 6px 10px;
148268
font-size: 13px;
149269
cursor: pointer;
150270
transition: background-color 0.2s ease;
151271
}
152272

273+
.suggestion-chip__icon {
274+
font-size: 16px;
275+
width: 16px;
276+
height: 16px;
277+
color: var(--color-primaryPalette-500);
278+
flex-shrink: 0;
279+
}
280+
153281
.suggestion-chip:hover {
154282
background-color: var(--color-primaryPalette-50);
155283
}
@@ -226,9 +354,17 @@
226354
}
227355

228356
.schema-editor__messages-empty {
229-
font-size: 13px;
230-
color: rgba(0, 0, 0, 0.5);
231-
margin: 8px 0 0;
357+
font-size: 14px;
358+
color: rgba(0, 0, 0, 0.6);
359+
margin: 4px 0 0;
360+
line-height: 1.45;
361+
}
362+
363+
.schema-editor__try-asking-block {
364+
margin-top: auto;
365+
display: flex;
366+
flex-direction: column;
367+
gap: 8px;
232368
}
233369

234370
@media (prefers-color-scheme: dark) {
@@ -237,6 +373,68 @@
237373
}
238374
}
239375

376+
.schema-editor__try-asking-heading {
377+
font-size: 11px;
378+
font-weight: 600;
379+
text-transform: uppercase;
380+
letter-spacing: 0.7px;
381+
color: rgba(0, 0, 0, 0.42);
382+
margin: 4px 0 0;
383+
}
384+
385+
@media (prefers-color-scheme: dark) {
386+
.schema-editor__try-asking-heading {
387+
color: rgba(255, 255, 255, 0.45);
388+
}
389+
}
390+
391+
.schema-editor__try-asking {
392+
display: flex;
393+
flex-direction: column;
394+
gap: 6px;
395+
}
396+
397+
.try-asking-item {
398+
display: flex;
399+
align-items: flex-start;
400+
gap: 8px;
401+
background: none;
402+
border: 1px dashed rgba(0, 0, 0, 0.14);
403+
border-radius: 10px;
404+
padding: 8px 10px;
405+
text-align: left;
406+
font-size: 12.5px;
407+
line-height: 1.4;
408+
color: rgba(0, 0, 0, 0.7);
409+
cursor: pointer;
410+
transition: border-color 0.15s ease, background-color 0.15s ease, color 0.15s ease;
411+
}
412+
413+
.try-asking-item:hover {
414+
border-color: var(--color-accentedPalette-500);
415+
background-color: color-mix(in srgb, var(--color-accentedPalette-500), transparent 94%);
416+
color: rgba(0, 0, 0, 0.9);
417+
}
418+
419+
@media (prefers-color-scheme: dark) {
420+
.try-asking-item {
421+
border-color: rgba(255, 255, 255, 0.16);
422+
color: rgba(255, 255, 255, 0.7);
423+
}
424+
.try-asking-item:hover {
425+
color: rgba(255, 255, 255, 0.95);
426+
}
427+
}
428+
429+
.try-asking-item__icon {
430+
font-size: 14px !important;
431+
width: 14px !important;
432+
height: 14px !important;
433+
margin-top: 1px;
434+
color: var(--color-accentedPalette-500);
435+
flex-shrink: 0;
436+
}
437+
240438
.schema-editor__message {
241439
border-radius: 8px;
242440
padding: 10px 14px;
@@ -258,17 +456,13 @@
258456
}
259457

260458
.schema-editor__message--ai {
261-
align-self: flex-start;
262-
background-color: rgba(99, 132, 255, 0.08);
459+
align-self: stretch;
460+
background-color: transparent;
461+
padding-left: 0;
462+
padding-right: 0;
263463
max-width: 100%;
264464
}
265465

266-
@media (prefers-color-scheme: dark) {
267-
.schema-editor__message--ai {
268-
background-color: rgba(99, 132, 255, 0.12);
269-
}
270-
}
271-
272466
.schema-editor__message-text {
273467
white-space: pre-wrap;
274468
}

0 commit comments

Comments
 (0)