@@ -45,98 +45,109 @@ export function SchemaDriftSheet({
4545 }
4646 } ;
4747
48- if ( ! driftDetails ) return null ;
49-
50- const hasAdded = driftDetails . tablesAdded . length > 0 ;
51- const hasRemoved = driftDetails . tablesRemoved . length > 0 ;
52- const hasModified = driftDetails . tablesModified . length > 0 ;
48+ const hasAdded = ( driftDetails ?. tablesAdded ?. length ?? 0 ) > 0 ;
49+ const hasRemoved = ( driftDetails ?. tablesRemoved ?. length ?? 0 ) > 0 ;
50+ const hasModified = ( driftDetails ?. tablesModified ?. length ?? 0 ) > 0 ;
51+ const hasDriftData = hasAdded || hasRemoved || hasModified ;
5352
5453 return (
5554 < Sheet open = { open } onOpenChange = { onOpenChange } >
5655 < SheetContent className = "sm:max-w-xl w-3/4 flex flex-col gap-4" >
5756 < SheetHeader >
5857 < SheetTitle > Schema Drift — { connectionName } </ SheetTitle >
5958 < SheetDescription >
60- Live database differs from schema.json{ capturedDate ? ` captured ${ new Date ( capturedDate ) . toLocaleString ( ) } ` : "" } .
59+ Live database differs from schema.json
60+ { capturedDate ? ` captured ${ new Date ( capturedDate ) . toLocaleString ( ) } ` : "" } .
6161 </ SheetDescription >
6262 </ SheetHeader >
6363
64- < ScrollArea className = "flex-1 pr-4 -mr-4" >
65- < div className = "space-y-4" >
66- { hasAdded && (
67- < Collapsible defaultOpen className = "border rounded-md" >
68- < CollapsibleTrigger className = "flex items-center justify-between w-full p-4 font-medium hover:bg-muted/50 transition-colors" >
69- < div className = "flex items-center gap-2" >
70- < span className = "text-green-600" > Tables Added</ span >
71- < Badge variant = "outline" className = "bg-green-600/10 text-green-600 border-green-600/20" >
72- { driftDetails . tablesAdded . length }
73- </ Badge >
74- </ div >
75- < ChevronDown className = "h-4 w-4" />
76- </ CollapsibleTrigger >
77- < CollapsibleContent className = "p-4 pt-0 border-t bg-muted/20" >
78- < ul className = "list-disc pl-4 mt-2 text-sm text-green-600" >
79- { driftDetails . tablesAdded . map ( ( t ) => < li key = { t } > { t } </ li > ) }
80- </ ul >
81- </ CollapsibleContent >
82- </ Collapsible >
83- ) }
64+ { ! hasDriftData ? (
65+ < div className = "flex-1 flex flex-col items-center justify-center gap-3 text-center py-12" >
66+ < div className = "text-4xl" > 🔍</ div >
67+ < p className = "text-sm font-medium text-foreground" > No detailed drift data available</ p >
68+ < p className = "text-xs text-muted-foreground max-w-xs" >
69+ Structural schema diffing is not yet implemented. Drift was detected from pending
70+ migrations, not a live schema comparison. This is tracked for a future release.
71+ </ p >
72+ </ div >
73+ ) : (
74+ < ScrollArea className = "flex-1 pr-4 -mr-4" >
75+ < div className = "space-y-4" >
76+ { hasAdded && (
77+ < Collapsible defaultOpen className = "border rounded-md" >
78+ < CollapsibleTrigger className = "flex items-center justify-between w-full p-4 font-medium hover:bg-muted/50 transition-colors" >
79+ < div className = "flex items-center gap-2" >
80+ < span className = "text-green-600" > Tables Added</ span >
81+ < Badge variant = "outline" className = "bg-green-600/10 text-green-600 border-green-600/20" >
82+ { driftDetails ! . tablesAdded . length }
83+ </ Badge >
84+ </ div >
85+ < ChevronDown className = "h-4 w-4" />
86+ </ CollapsibleTrigger >
87+ < CollapsibleContent className = "p-4 pt-0 border-t bg-muted/20" >
88+ < ul className = "list-disc pl-4 mt-2 text-sm text-green-600" >
89+ { driftDetails ! . tablesAdded . map ( ( t ) => < li key = { t } > { t } </ li > ) }
90+ </ ul >
91+ </ CollapsibleContent >
92+ </ Collapsible >
93+ ) }
8494
85- { hasRemoved && (
86- < Collapsible defaultOpen className = "border rounded-md" >
87- < CollapsibleTrigger className = "flex items-center justify-between w-full p-4 font-medium hover:bg-muted/50 transition-colors" >
88- < div className = "flex items-center gap-2" >
89- < span className = "text-destructive" > Tables Removed</ span >
90- < Badge variant = "destructive" className = "bg-destructive/10 text-destructive border-destructive/20" >
91- { driftDetails . tablesRemoved . length }
92- </ Badge >
93- </ div >
94- < ChevronDown className = "h-4 w-4" />
95- </ CollapsibleTrigger >
96- < CollapsibleContent className = "p-4 pt-0 border-t bg-muted/20" >
97- < ul className = "list-disc pl-4 mt-2 text-sm text-destructive" >
98- { driftDetails . tablesRemoved . map ( ( t ) => < li key = { t } > { t } </ li > ) }
99- </ ul >
100- </ CollapsibleContent >
101- </ Collapsible >
102- ) }
95+ { hasRemoved && (
96+ < Collapsible defaultOpen className = "border rounded-md" >
97+ < CollapsibleTrigger className = "flex items-center justify-between w-full p-4 font-medium hover:bg-muted/50 transition-colors" >
98+ < div className = "flex items-center gap-2" >
99+ < span className = "text-destructive" > Tables Removed</ span >
100+ < Badge variant = "destructive" className = "bg-destructive/10 text-destructive border-destructive/20" >
101+ { driftDetails ! . tablesRemoved . length }
102+ </ Badge >
103+ </ div >
104+ < ChevronDown className = "h-4 w-4" />
105+ </ CollapsibleTrigger >
106+ < CollapsibleContent className = "p-4 pt-0 border-t bg-muted/20" >
107+ < ul className = "list-disc pl-4 mt-2 text-sm text-destructive" >
108+ { driftDetails ! . tablesRemoved . map ( ( t ) => < li key = { t } > { t } </ li > ) }
109+ </ ul >
110+ </ CollapsibleContent >
111+ </ Collapsible >
112+ ) }
103113
104- { hasModified && (
105- < Collapsible defaultOpen className = "border rounded-md" >
106- < CollapsibleTrigger className = "flex items-center justify-between w-full p-4 font-medium hover:bg-muted/50 transition-colors" >
107- < div className = "flex items-center gap-2" >
108- < span className = "text-orange-600" > Tables Modified</ span >
109- < Badge variant = "outline" className = "bg-orange-600/10 text-orange-600 border-orange-600/20" >
110- { driftDetails . tablesModified . length }
111- </ Badge >
112- </ div >
113- < ChevronDown className = "h-4 w-4" />
114- </ CollapsibleTrigger >
115- < CollapsibleContent className = "p-4 pt-0 border-t bg-muted/20" >
116- < div className = "space-y-4 mt-2" >
117- { driftDetails . tablesModified . map ( ( m ) => (
118- < div key = { m . tableName } className = "text-sm" >
119- < div className = "font-semibold text-foreground mb-1" > { m . tableName } </ div >
120- { m . columnsAdded . length > 0 && (
121- < div className = "text-green-600 ml-2" > + { m . columnsAdded . join ( ", " ) } </ div >
122- ) }
123- { m . columnsRemoved . length > 0 && (
124- < div className = "text-destructive ml-2" > - { m . columnsRemoved . join ( ", " ) } </ div >
125- ) }
126- { m . columnsChanged . length > 0 && (
127- < div className = "text-orange-600 ml-2" > ~ { m . columnsChanged . join ( ", " ) } </ div >
128- ) }
129- { m . constraintsChanged . length > 0 && (
130- < div className = "text-blue-600 ml-2" > ~ { m . constraintsChanged . join ( ", " ) } </ div >
131- ) }
132- </ div >
133- ) ) }
134- </ div >
135- </ CollapsibleContent >
136- </ Collapsible >
137- ) }
138- </ div >
139- </ ScrollArea >
114+ { hasModified && (
115+ < Collapsible defaultOpen className = "border rounded-md" >
116+ < CollapsibleTrigger className = "flex items-center justify-between w-full p-4 font-medium hover:bg-muted/50 transition-colors" >
117+ < div className = "flex items-center gap-2" >
118+ < span className = "text-orange-600" > Tables Modified</ span >
119+ < Badge variant = "outline" className = "bg-orange-600/10 text-orange-600 border-orange-600/20" >
120+ { driftDetails ! . tablesModified . length }
121+ </ Badge >
122+ </ div >
123+ < ChevronDown className = "h-4 w-4" />
124+ </ CollapsibleTrigger >
125+ < CollapsibleContent className = "p-4 pt-0 border-t bg-muted/20" >
126+ < div className = "space-y-4 mt-2" >
127+ { driftDetails ! . tablesModified . map ( ( m ) => (
128+ < div key = { m . tableName } className = "text-sm" >
129+ < div className = "font-semibold text-foreground mb-1" > { m . tableName } </ div >
130+ { m . columnsAdded . length > 0 && (
131+ < div className = "text-green-600 ml-2" > + { m . columnsAdded . join ( ", " ) } </ div >
132+ ) }
133+ { m . columnsRemoved . length > 0 && (
134+ < div className = "text-destructive ml-2" > - { m . columnsRemoved . join ( ", " ) } </ div >
135+ ) }
136+ { m . columnsChanged . length > 0 && (
137+ < div className = "text-orange-600 ml-2" > ~ { m . columnsChanged . join ( ", " ) } </ div >
138+ ) }
139+ { m . constraintsChanged . length > 0 && (
140+ < div className = "text-blue-600 ml-2" > ~ { m . constraintsChanged . join ( ", " ) } </ div >
141+ ) }
142+ </ div >
143+ ) ) }
144+ </ div >
145+ </ CollapsibleContent >
146+ </ Collapsible >
147+ ) }
148+ </ div >
149+ </ ScrollArea >
150+ ) }
140151
141152 < div className = "flex justify-end gap-2 pt-4 border-t mt-auto" >
142153 < Button variant = "outline" onClick = { ( ) => onOpenChange ( false ) } > Close</ Button >
0 commit comments