Improve user experience when no database is selected (#3214)
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
|
||||
## [UNRELEASED]
|
||||
|
||||
- If you run a query without having selected a database, we show a more intuitive prompt to help you select a database. [#3214](https://github.com/github/vscode-codeql/pull/3214)
|
||||
- Add a prompt for downloading a GitHub database when opening a GitHub repository. [#3138](https://github.com/github/vscode-codeql/pull/3138)
|
||||
- Avoid showing a popup when hovering over source elements in database source files. [#3125](https://github.com/github/vscode-codeql/pull/3125)
|
||||
- Add comparison of alerts when comparing query results. This allows viewing path explanations for differences in alerts. [#3113](https://github.com/github/vscode-codeql/pull/3113)
|
||||
|
||||
@@ -5,6 +5,7 @@ import type {
|
||||
ProviderResult,
|
||||
TreeDataProvider,
|
||||
CancellationToken,
|
||||
QuickPickItem,
|
||||
} from "vscode";
|
||||
import {
|
||||
EventEmitter,
|
||||
@@ -28,7 +29,11 @@ import type {
|
||||
ProgressCallback,
|
||||
ProgressContext,
|
||||
} from "../common/vscode/progress";
|
||||
import { withInheritedProgress, withProgress } from "../common/vscode/progress";
|
||||
import {
|
||||
UserCancellationException,
|
||||
withInheritedProgress,
|
||||
withProgress,
|
||||
} from "../common/vscode/progress";
|
||||
import {
|
||||
isLikelyDatabaseRoot,
|
||||
isLikelyDbLanguageFolder,
|
||||
@@ -52,7 +57,10 @@ import {
|
||||
createMultiSelectionCommand,
|
||||
createSingleSelectionCommand,
|
||||
} from "../common/vscode/selection-commands";
|
||||
import { tryGetQueryLanguage } from "../common/query-language";
|
||||
import {
|
||||
getLanguageDisplayName,
|
||||
tryGetQueryLanguage,
|
||||
} from "../common/query-language";
|
||||
import type { LanguageContextStore } from "../language-context-store";
|
||||
|
||||
enum SortOrder {
|
||||
@@ -227,6 +235,18 @@ async function chooseDatabaseDir(byFolder: boolean): Promise<Uri | undefined> {
|
||||
return getFirst(chosen);
|
||||
}
|
||||
|
||||
interface DatabaseSelectionQuickPickItem extends QuickPickItem {
|
||||
databaseKind: "new" | "existing";
|
||||
}
|
||||
|
||||
export interface DatabaseQuickPickItem extends QuickPickItem {
|
||||
databaseItem: DatabaseItem;
|
||||
}
|
||||
|
||||
interface DatabaseImportQuickPickItems extends QuickPickItem {
|
||||
importType: "URL" | "github" | "archive" | "folder";
|
||||
}
|
||||
|
||||
export class DatabaseUI extends DisposableObject {
|
||||
private treeDataProvider: DatabaseTreeDataProvider;
|
||||
|
||||
@@ -794,13 +814,120 @@ export class DatabaseUI extends DisposableObject {
|
||||
* notification if it tries to perform any long-running operations.
|
||||
*/
|
||||
private async getDatabaseItemInternal(
|
||||
progress: ProgressContext | undefined,
|
||||
progressContext: ProgressContext | undefined,
|
||||
): Promise<DatabaseItem | undefined> {
|
||||
if (this.databaseManager.currentDatabaseItem === undefined) {
|
||||
await this.chooseAndSetDatabase(false, progress);
|
||||
progressContext?.progress({
|
||||
maxStep: 2,
|
||||
step: 1,
|
||||
message: "Choosing database",
|
||||
});
|
||||
await this.promptForDatabase();
|
||||
}
|
||||
return this.databaseManager.currentDatabaseItem;
|
||||
}
|
||||
|
||||
private async promptForDatabase(): Promise<void> {
|
||||
const quickPickItems: DatabaseSelectionQuickPickItem[] = [
|
||||
{
|
||||
label: "$(database) Existing database",
|
||||
detail: "Select an existing database from your workspace",
|
||||
alwaysShow: true,
|
||||
databaseKind: "existing",
|
||||
},
|
||||
{
|
||||
label: "$(arrow-down) New database",
|
||||
detail: "Import a new database from the cloud or your local machine",
|
||||
alwaysShow: true,
|
||||
databaseKind: "new",
|
||||
},
|
||||
];
|
||||
const selectedOption =
|
||||
await window.showQuickPick<DatabaseSelectionQuickPickItem>(
|
||||
quickPickItems,
|
||||
{
|
||||
placeHolder: "Select an option",
|
||||
ignoreFocusOut: true,
|
||||
},
|
||||
);
|
||||
|
||||
if (!selectedOption) {
|
||||
throw new UserCancellationException("No database selected", true);
|
||||
}
|
||||
|
||||
return this.databaseManager.currentDatabaseItem;
|
||||
if (selectedOption.databaseKind === "existing") {
|
||||
await this.selectExistingDatabase();
|
||||
} else if (selectedOption.databaseKind === "new") {
|
||||
await this.importNewDatabase();
|
||||
}
|
||||
}
|
||||
|
||||
private async selectExistingDatabase() {
|
||||
const dbItems: DatabaseQuickPickItem[] =
|
||||
this.databaseManager.databaseItems.map((dbItem) => ({
|
||||
label: dbItem.name,
|
||||
description: getLanguageDisplayName(dbItem.language),
|
||||
databaseItem: dbItem,
|
||||
}));
|
||||
|
||||
const selectedDatabase = await window.showQuickPick(dbItems, {
|
||||
placeHolder: "Select a database",
|
||||
ignoreFocusOut: true,
|
||||
});
|
||||
|
||||
if (!selectedDatabase) {
|
||||
throw new UserCancellationException("No database selected", true);
|
||||
}
|
||||
|
||||
await this.databaseManager.setCurrentDatabaseItem(
|
||||
selectedDatabase.databaseItem,
|
||||
);
|
||||
}
|
||||
|
||||
private async importNewDatabase() {
|
||||
const importOptions: DatabaseImportQuickPickItems[] = [
|
||||
{
|
||||
label: "$(github) GitHub",
|
||||
detail: "Import a database from a GitHub repository",
|
||||
alwaysShow: true,
|
||||
importType: "github",
|
||||
},
|
||||
{
|
||||
label: "$(link) URL",
|
||||
detail: "Import a database archive or folder from a remote URL",
|
||||
alwaysShow: true,
|
||||
importType: "URL",
|
||||
},
|
||||
{
|
||||
label: "$(file-zip) Archive",
|
||||
detail: "Import a database from a local ZIP archive",
|
||||
alwaysShow: true,
|
||||
importType: "archive",
|
||||
},
|
||||
{
|
||||
label: "$(folder) Folder",
|
||||
detail: "Import a database from a local folder",
|
||||
alwaysShow: true,
|
||||
importType: "folder",
|
||||
},
|
||||
];
|
||||
const selectedImportOption =
|
||||
await window.showQuickPick<DatabaseImportQuickPickItems>(importOptions, {
|
||||
placeHolder: "Import a database from...",
|
||||
ignoreFocusOut: true,
|
||||
});
|
||||
if (!selectedImportOption) {
|
||||
throw new UserCancellationException("No database selected", true);
|
||||
}
|
||||
if (selectedImportOption.importType === "github") {
|
||||
await this.handleChooseDatabaseGithub();
|
||||
} else if (selectedImportOption.importType === "URL") {
|
||||
await this.handleChooseDatabaseInternet();
|
||||
} else if (selectedImportOption.importType === "archive") {
|
||||
await this.handleChooseDatabaseArchive();
|
||||
} else if (selectedImportOption.importType === "folder") {
|
||||
await this.handleChooseDatabaseFolder();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -3,12 +3,7 @@ import type {
|
||||
ProgressUpdate,
|
||||
} from "../common/vscode/progress";
|
||||
import { withProgress } from "../common/vscode/progress";
|
||||
import type {
|
||||
CancellationToken,
|
||||
QuickPickItem,
|
||||
Range,
|
||||
TabInputText,
|
||||
} from "vscode";
|
||||
import type { CancellationToken, Range, TabInputText } from "vscode";
|
||||
import { CancellationTokenSource, Uri, window } from "vscode";
|
||||
import {
|
||||
TeeLogger,
|
||||
@@ -23,7 +18,10 @@ import { getOnDiskWorkspaceFolders } from "../common/vscode/workspace-folders";
|
||||
import { displayQuickQuery } from "./quick-query";
|
||||
import type { CoreCompletedQuery, QueryRunner } from "../query-server";
|
||||
import type { QueryHistoryManager } from "../query-history/query-history-manager";
|
||||
import type { DatabaseUI } from "../databases/local-databases-ui";
|
||||
import type {
|
||||
DatabaseQuickPickItem,
|
||||
DatabaseUI,
|
||||
} from "../databases/local-databases-ui";
|
||||
import type { ResultsView } from "./results-view";
|
||||
import type {
|
||||
DatabaseItem,
|
||||
@@ -55,10 +53,6 @@ import { tryGetQueryLanguage } from "../common/query-language";
|
||||
import type { LanguageContextStore } from "../language-context-store";
|
||||
import type { ExtensionApp } from "../common/vscode/vscode-app";
|
||||
|
||||
interface DatabaseQuickPickItem extends QuickPickItem {
|
||||
databaseItem: DatabaseItem;
|
||||
}
|
||||
|
||||
export enum QuickEvalType {
|
||||
None,
|
||||
QuickEval,
|
||||
|
||||
Reference in New Issue
Block a user