@@ -5,6 +5,7 @@ import type {
55 ProviderResult ,
66 TreeDataProvider ,
77 CancellationToken ,
8+ QuickPickItem ,
89} from "vscode" ;
910import {
1011 EventEmitter ,
@@ -28,7 +29,11 @@ import type {
2829 ProgressCallback ,
2930 ProgressContext ,
3031} from "../common/vscode/progress" ;
31- import { withInheritedProgress , withProgress } from "../common/vscode/progress" ;
32+ import {
33+ UserCancellationException ,
34+ withInheritedProgress ,
35+ withProgress ,
36+ } from "../common/vscode/progress" ;
3237import {
3338 isLikelyDatabaseRoot ,
3439 isLikelyDbLanguageFolder ,
@@ -52,7 +57,10 @@ import {
5257 createMultiSelectionCommand ,
5358 createSingleSelectionCommand ,
5459} from "../common/vscode/selection-commands" ;
55- import { tryGetQueryLanguage } from "../common/query-language" ;
60+ import {
61+ getLanguageDisplayName ,
62+ tryGetQueryLanguage ,
63+ } from "../common/query-language" ;
5664import type { LanguageContextStore } from "../language-context-store" ;
5765
5866enum SortOrder {
@@ -227,6 +235,18 @@ async function chooseDatabaseDir(byFolder: boolean): Promise<Uri | undefined> {
227235 return getFirst ( chosen ) ;
228236}
229237
238+ interface DatabaseSelectionQuickPickItem extends QuickPickItem {
239+ databaseKind : "new" | "existing" ;
240+ }
241+
242+ export interface DatabaseQuickPickItem extends QuickPickItem {
243+ databaseItem : DatabaseItem ;
244+ }
245+
246+ interface DatabaseImportQuickPickItems extends QuickPickItem {
247+ importType : "URL" | "github" | "archive" | "folder" ;
248+ }
249+
230250export class DatabaseUI extends DisposableObject {
231251 private treeDataProvider : DatabaseTreeDataProvider ;
232252
@@ -794,15 +814,122 @@ export class DatabaseUI extends DisposableObject {
794814 * notification if it tries to perform any long-running operations.
795815 */
796816 private async getDatabaseItemInternal (
797- progress : ProgressContext | undefined ,
817+ progressContext : ProgressContext | undefined ,
798818 ) : Promise < DatabaseItem | undefined > {
799819 if ( this . databaseManager . currentDatabaseItem === undefined ) {
800- await this . chooseAndSetDatabase ( false , progress ) ;
820+ progressContext ?. progress ( {
821+ maxStep : 2 ,
822+ step : 1 ,
823+ message : "Choosing database" ,
824+ } ) ;
825+ await this . promptForDatabase ( ) ;
801826 }
802-
803827 return this . databaseManager . currentDatabaseItem ;
804828 }
805829
830+ private async promptForDatabase ( ) : Promise < void > {
831+ const quickPickItems : DatabaseSelectionQuickPickItem [ ] = [
832+ {
833+ label : "$(database) Existing database" ,
834+ detail : "Select an existing database from your workspace" ,
835+ alwaysShow : true ,
836+ databaseKind : "existing" ,
837+ } ,
838+ {
839+ label : "$(arrow-down) New database" ,
840+ detail : "Import a new database from the cloud or your local machine" ,
841+ alwaysShow : true ,
842+ databaseKind : "new" ,
843+ } ,
844+ ] ;
845+ const selectedOption =
846+ await window . showQuickPick < DatabaseSelectionQuickPickItem > (
847+ quickPickItems ,
848+ {
849+ placeHolder : "Select an option" ,
850+ ignoreFocusOut : true ,
851+ } ,
852+ ) ;
853+
854+ if ( ! selectedOption ) {
855+ throw new UserCancellationException ( "No database selected" , true ) ;
856+ }
857+
858+ if ( selectedOption . databaseKind === "existing" ) {
859+ await this . selectExistingDatabase ( ) ;
860+ } else if ( selectedOption . databaseKind === "new" ) {
861+ await this . importNewDatabase ( ) ;
862+ }
863+ }
864+
865+ private async selectExistingDatabase ( ) {
866+ const dbItems : DatabaseQuickPickItem [ ] =
867+ this . databaseManager . databaseItems . map ( ( dbItem ) => ( {
868+ label : dbItem . name ,
869+ description : getLanguageDisplayName ( dbItem . language ) ,
870+ databaseItem : dbItem ,
871+ } ) ) ;
872+
873+ const selectedDatabase = await window . showQuickPick ( dbItems , {
874+ placeHolder : "Select a database" ,
875+ ignoreFocusOut : true ,
876+ } ) ;
877+
878+ if ( ! selectedDatabase ) {
879+ throw new UserCancellationException ( "No database selected" , true ) ;
880+ }
881+
882+ await this . databaseManager . setCurrentDatabaseItem (
883+ selectedDatabase . databaseItem ,
884+ ) ;
885+ }
886+
887+ private async importNewDatabase ( ) {
888+ const importOptions : DatabaseImportQuickPickItems [ ] = [
889+ {
890+ label : "$(github) GitHub" ,
891+ detail : "Import a database from a GitHub repository" ,
892+ alwaysShow : true ,
893+ importType : "github" ,
894+ } ,
895+ {
896+ label : "$(link) URL" ,
897+ detail : "Import a database archive or folder from a remote URL" ,
898+ alwaysShow : true ,
899+ importType : "URL" ,
900+ } ,
901+ {
902+ label : "$(file-zip) Archive" ,
903+ detail : "Import a database from a local ZIP archive" ,
904+ alwaysShow : true ,
905+ importType : "archive" ,
906+ } ,
907+ {
908+ label : "$(folder) Folder" ,
909+ detail : "Import a database from a local folder" ,
910+ alwaysShow : true ,
911+ importType : "folder" ,
912+ } ,
913+ ] ;
914+ const selectedImportOption =
915+ await window . showQuickPick < DatabaseImportQuickPickItems > ( importOptions , {
916+ placeHolder : "Import a database from..." ,
917+ ignoreFocusOut : true ,
918+ } ) ;
919+ if ( ! selectedImportOption ) {
920+ throw new UserCancellationException ( "No database selected" , true ) ;
921+ }
922+ if ( selectedImportOption . importType === "github" ) {
923+ await this . handleChooseDatabaseGithub ( ) ;
924+ } else if ( selectedImportOption . importType === "URL" ) {
925+ await this . handleChooseDatabaseInternet ( ) ;
926+ } else if ( selectedImportOption . importType === "archive" ) {
927+ await this . handleChooseDatabaseArchive ( ) ;
928+ } else if ( selectedImportOption . importType === "folder" ) {
929+ await this . handleChooseDatabaseFolder ( ) ;
930+ }
931+ }
932+
806933 /**
807934 * Ask the user for a database directory. Returns the chosen database, or `undefined` if the
808935 * operation was canceled.
0 commit comments