66 NotebookCellStatusBarItemProvider ,
77 NotebookEdit ,
88 ProviderResult ,
9+ QuickPickItem ,
10+ QuickPickItemKind ,
911 WorkspaceEdit ,
1012 commands ,
1113 l10n ,
@@ -17,9 +19,9 @@ import { inject, injectable } from 'inversify';
1719
1820import { IExtensionSyncActivationService } from '../../platform/activation/types' ;
1921import { IDisposableRegistry } from '../../platform/common/types' ;
20- import { Commands } from '../../platform/common/constants' ;
2122import { IIntegrationStorage } from './integrations/types' ;
22- import { DATAFRAME_SQL_INTEGRATION_ID } from '../../platform/notebooks/deepnote/integrationTypes' ;
23+ import { Commands } from '../../platform/common/constants' ;
24+ import { DATAFRAME_SQL_INTEGRATION_ID , IntegrationType } from '../../platform/notebooks/deepnote/integrationTypes' ;
2325
2426/**
2527 * Provides status bar items for SQL cells showing the integration name and variable name
@@ -53,6 +55,13 @@ export class SqlCellStatusBarProvider implements NotebookCellStatusBarItemProvid
5355 } )
5456 ) ;
5557
58+ // Register command to switch SQL integration
59+ this . disposables . push (
60+ commands . registerCommand ( 'deepnote.switchSqlIntegration' , async ( cell : NotebookCell ) => {
61+ await this . switchIntegration ( cell ) ;
62+ } )
63+ ) ;
64+
5665 // Dispose our emitter with the extension
5766 this . disposables . push ( this . _onDidChangeCellStatusBarItems ) ;
5867 }
@@ -113,7 +122,12 @@ export class SqlCellStatusBarProvider implements NotebookCellStatusBarItemProvid
113122 return {
114123 text : `$(database) ${ l10n . t ( 'DataFrame SQL (DuckDB)' ) } ` ,
115124 alignment : 1 , // NotebookCellStatusBarAlignment.Left
116- tooltip : l10n . t ( 'Internal DuckDB integration for querying DataFrames' )
125+ tooltip : l10n . t ( 'Internal DuckDB integration for querying DataFrames\nClick to switch' ) ,
126+ command : {
127+ title : l10n . t ( 'Switch Integration' ) ,
128+ command : 'deepnote.switchSqlIntegration' ,
129+ arguments : [ cell ]
130+ }
117131 } ;
118132 }
119133
@@ -126,15 +140,15 @@ export class SqlCellStatusBarProvider implements NotebookCellStatusBarItemProvid
126140 const config = await this . integrationStorage . getProjectIntegrationConfig ( projectId , integrationId ) ;
127141 const displayName = config ?. name || l10n . t ( 'Unknown integration (configure)' ) ;
128142
129- // Create a status bar item that opens the integration management UI
143+ // Create a status bar item that opens the integration picker
130144 return {
131145 text : `$(database) ${ displayName } ` ,
132146 alignment : 1 , // NotebookCellStatusBarAlignment.Left
133- tooltip : l10n . t ( 'SQL Integration: {0}\nClick to configure' , displayName ) ,
147+ tooltip : l10n . t ( 'SQL Integration: {0}\nClick to switch or configure' , displayName ) ,
134148 command : {
135- title : l10n . t ( 'Configure Integration' ) ,
136- command : Commands . ManageIntegrations ,
137- arguments : [ integrationId ]
149+ title : l10n . t ( 'Switch Integration' ) ,
150+ command : 'deepnote.switchSqlIntegration' ,
151+ arguments : [ cell ]
138152 }
139153 } ;
140154 }
@@ -201,4 +215,106 @@ export class SqlCellStatusBarProvider implements NotebookCellStatusBarItemProvid
201215 // Trigger status bar update
202216 this . _onDidChangeCellStatusBarItems . fire ( ) ;
203217 }
218+
219+ private async switchIntegration ( cell : NotebookCell ) : Promise < void > {
220+ const currentIntegrationId = this . getIntegrationId ( cell ) ;
221+
222+ // Get all available integrations
223+ const allIntegrations = await this . integrationStorage . getAll ( ) ;
224+
225+ // Build quick pick items
226+ const items : QuickPickItem [ ] = [ ] ;
227+
228+ // Check if current integration is unknown (not in the list)
229+ const isCurrentIntegrationUnknown =
230+ currentIntegrationId &&
231+ currentIntegrationId !== DATAFRAME_SQL_INTEGRATION_ID &&
232+ ! allIntegrations . some ( ( i ) => i . id === currentIntegrationId ) ;
233+
234+ // Add current unknown integration first if it exists
235+ if ( isCurrentIntegrationUnknown && currentIntegrationId ) {
236+ items . push ( {
237+ label : l10n . t ( 'Unknown integration (configure)' ) ,
238+ description : currentIntegrationId ,
239+ detail : l10n . t ( 'Currently selected' ) ,
240+ id : currentIntegrationId
241+ } as QuickPickItem & { id : string } ) ;
242+ }
243+
244+ // Add all configured integrations
245+ for ( const integration of allIntegrations ) {
246+ const typeLabel = this . getIntegrationTypeLabel ( integration . type ) ;
247+ items . push ( {
248+ label : integration . name || integration . id ,
249+ description : typeLabel ,
250+ detail : integration . id === currentIntegrationId ? l10n . t ( 'Currently selected' ) : undefined ,
251+ // Store the integration ID in a custom property
252+ id : integration . id
253+ } as QuickPickItem & { id : string } ) ;
254+ }
255+
256+ // Add DuckDB integration
257+ items . push ( {
258+ label : l10n . t ( 'DataFrame SQL (DuckDB)' ) ,
259+ description : l10n . t ( 'DuckDB' ) ,
260+ detail : currentIntegrationId === DATAFRAME_SQL_INTEGRATION_ID ? l10n . t ( 'Currently selected' ) : undefined ,
261+ id : DATAFRAME_SQL_INTEGRATION_ID
262+ } as QuickPickItem & { id : string } ) ;
263+
264+ // Add separator
265+ items . push ( {
266+ label : '' ,
267+ kind : QuickPickItemKind . Separator
268+ } ) ;
269+
270+ // Add "Configure current integration" option
271+ if ( currentIntegrationId && currentIntegrationId !== DATAFRAME_SQL_INTEGRATION_ID ) {
272+ items . push ( {
273+ label : l10n . t ( 'Configure current integration' ) ,
274+ id : '__configure__'
275+ } as QuickPickItem & { id : string } ) ;
276+ }
277+
278+ const selected = await window . showQuickPick ( items , {
279+ placeHolder : l10n . t ( 'Select SQL integration' ) ,
280+ matchOnDescription : true
281+ } ) ;
282+
283+ if ( ! selected ) {
284+ return ;
285+ }
286+
287+ const selectedId = ( selected as QuickPickItem & { id : string } ) . id ;
288+
289+ // Handle "Configure current integration" option
290+ if ( selectedId === '__configure__' && currentIntegrationId ) {
291+ await commands . executeCommand ( Commands . ManageIntegrations , currentIntegrationId ) ;
292+ return ;
293+ }
294+
295+ // Update cell metadata with new integration ID
296+ const edit = new WorkspaceEdit ( ) ;
297+ const updatedMetadata = {
298+ ...cell . metadata ,
299+ sql_integration_id : selectedId
300+ } ;
301+
302+ edit . set ( cell . notebook . uri , [ NotebookEdit . updateCellMetadata ( cell . index , updatedMetadata ) ] ) ;
303+
304+ await workspace . applyEdit ( edit ) ;
305+
306+ // Trigger status bar update
307+ this . _onDidChangeCellStatusBarItems . fire ( ) ;
308+ }
309+
310+ private getIntegrationTypeLabel ( type : IntegrationType ) : string {
311+ switch ( type ) {
312+ case IntegrationType . Postgres :
313+ return l10n . t ( 'PostgreSQL' ) ;
314+ case IntegrationType . BigQuery :
315+ return l10n . t ( 'BigQuery' ) ;
316+ default :
317+ return type ;
318+ }
319+ }
204320}
0 commit comments