mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-14 01:25:37 -05:00
Add double click action support for query history (#20204)
* Add double click action support for query history * localize descriptions
This commit is contained in:
@@ -39,6 +39,19 @@
|
||||
"type": "boolean",
|
||||
"default": true,
|
||||
"description": "%queryHistory.captureEnabledDesc%"
|
||||
},
|
||||
"queryHistory.doubleClickAction": {
|
||||
"type": "string",
|
||||
"description": "%queryHistory.doubleClickAction%",
|
||||
"default": "open",
|
||||
"enum": [
|
||||
"open",
|
||||
"run"
|
||||
],
|
||||
"enumDescriptions": [
|
||||
"%queryHistory.doubleClickAction.open%",
|
||||
"%queryHistory.doubleClickAction.run%"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
"queryHistory.displayName": "Query History",
|
||||
"queryHistory.description": "View and run previously executed queries",
|
||||
"queryHistory.captureEnabledDesc": "Whether Query History capture is enabled. If false queries executed will not be captured.",
|
||||
"queryHistory.doubleClickAction": "The action taken when a history item is double clicked",
|
||||
"queryHistory.doubleClickAction.open": "Open a new disconnected editor with the query from the selected history item",
|
||||
"queryHistory.doubleClickAction.run": "Open a new connected editor with the query and connection from the selected history item and automatically run the query",
|
||||
"queryHistory.open": "Open Query",
|
||||
"queryHistory.run": "Run Query",
|
||||
"queryHistory.delete": "Delete",
|
||||
|
||||
10
extensions/query-history/src/constants.ts
Normal file
10
extensions/query-history/src/constants.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
export const QUERY_HISTORY_CONFIG_SECTION = 'queryHistory';
|
||||
export const CAPTURE_ENABLED_CONFIG_SECTION = 'captureEnabled';
|
||||
export const DOUBLE_CLICK_ACTION_CONFIG_SECTION = 'doubleClickAction';
|
||||
|
||||
export const ITEM_SELECTED_COMMAND_ID = 'queryHistory.itemSelected';
|
||||
@@ -5,37 +5,89 @@
|
||||
|
||||
import * as azdata from 'azdata';
|
||||
import * as vscode from 'vscode';
|
||||
import { DOUBLE_CLICK_ACTION_CONFIG_SECTION, ITEM_SELECTED_COMMAND_ID, QUERY_HISTORY_CONFIG_SECTION } from './constants';
|
||||
import { QueryHistoryItem } from './queryHistoryItem';
|
||||
import { QueryHistoryProvider } from './queryHistoryProvider';
|
||||
|
||||
let lastSelectedItem: { item: QueryHistoryItem | undefined, time: number | undefined } = {
|
||||
item: undefined,
|
||||
time: undefined
|
||||
};
|
||||
/**
|
||||
* The time in ms between clicks to count as a double click on our tree view items
|
||||
*/
|
||||
const DOUBLE_CLICK_TIMEOUT_MS = 500;
|
||||
|
||||
export async function activate(context: vscode.ExtensionContext): Promise<void> {
|
||||
const provider = new QueryHistoryProvider();
|
||||
context.subscriptions.push(provider);
|
||||
context.subscriptions.push(vscode.window.registerTreeDataProvider('queryHistory', provider));
|
||||
const treeDataProvider = new QueryHistoryProvider();
|
||||
context.subscriptions.push(treeDataProvider);
|
||||
const treeView = vscode.window.createTreeView('queryHistory', {
|
||||
treeDataProvider,
|
||||
canSelectMany: false
|
||||
});
|
||||
context.subscriptions.push(treeView);
|
||||
// This is an internal-only command so not adding to package.json
|
||||
context.subscriptions.push(vscode.commands.registerCommand(ITEM_SELECTED_COMMAND_ID, async (selectedItem: QueryHistoryItem) => {
|
||||
// VS Code doesn't provide a native way to detect a double-click so we track it ourselves by keeping track of the last item clicked and
|
||||
// when it was clicked to compare, then if a click happens on the same element quickly enough we trigger the configured action
|
||||
const clickTime = new Date().getTime();
|
||||
if (lastSelectedItem.item === selectedItem && lastSelectedItem.time && (clickTime - lastSelectedItem.time) < DOUBLE_CLICK_TIMEOUT_MS) {
|
||||
const doubleClickAction = vscode.workspace.getConfiguration(QUERY_HISTORY_CONFIG_SECTION).get<string>(DOUBLE_CLICK_ACTION_CONFIG_SECTION);
|
||||
switch (doubleClickAction) {
|
||||
case 'run':
|
||||
await runQuery(selectedItem);
|
||||
break;
|
||||
case 'open':
|
||||
default:
|
||||
await openQuery(selectedItem);
|
||||
break;
|
||||
}
|
||||
// Clear out the last selected item so we don't run the command again on a 3rd click
|
||||
lastSelectedItem = {
|
||||
item: undefined,
|
||||
time: undefined
|
||||
};
|
||||
} else {
|
||||
// Update the last selected item since we didn't run a command
|
||||
lastSelectedItem = {
|
||||
item: selectedItem,
|
||||
time: clickTime
|
||||
};
|
||||
}
|
||||
|
||||
}));
|
||||
context.subscriptions.push(vscode.commands.registerCommand('queryHistory.open', async (item: QueryHistoryItem) => {
|
||||
return azdata.queryeditor.openQueryDocument(
|
||||
{
|
||||
content: item.queryText
|
||||
}, item.connectionProfile?.providerId);
|
||||
return openQuery(item);
|
||||
}));
|
||||
context.subscriptions.push(vscode.commands.registerCommand('queryHistory.run', async (item: QueryHistoryItem) => {
|
||||
const doc = await azdata.queryeditor.openQueryDocument(
|
||||
{
|
||||
content: item.queryText
|
||||
}, item.connectionProfile?.providerId);
|
||||
await azdata.queryeditor.connect(doc.uri, item.connectionProfile?.connectionId || '');
|
||||
azdata.queryeditor.runQuery(doc.uri);
|
||||
return runQuery(item);
|
||||
}));
|
||||
context.subscriptions.push(vscode.commands.registerCommand('queryHistory.delete', (item: QueryHistoryItem) => {
|
||||
provider.deleteItem(item);
|
||||
treeDataProvider.deleteItem(item);
|
||||
}));
|
||||
context.subscriptions.push(vscode.commands.registerCommand('queryHistory.clear', () => {
|
||||
provider.clearAll();
|
||||
treeDataProvider.clearAll();
|
||||
}));
|
||||
context.subscriptions.push(vscode.commands.registerCommand('queryHistory.disableCapture', async () => {
|
||||
return provider.setCaptureEnabled(false);
|
||||
return treeDataProvider.setCaptureEnabled(false);
|
||||
}));
|
||||
context.subscriptions.push(vscode.commands.registerCommand('queryHistory.enableCapture', async () => {
|
||||
return provider.setCaptureEnabled(true);
|
||||
return treeDataProvider.setCaptureEnabled(true);
|
||||
}));
|
||||
}
|
||||
|
||||
async function openQuery(item: QueryHistoryItem): Promise<void> {
|
||||
await azdata.queryeditor.openQueryDocument(
|
||||
{
|
||||
content: item.queryText
|
||||
}, item.connectionProfile?.providerId);
|
||||
}
|
||||
|
||||
async function runQuery(item: QueryHistoryItem): Promise<void> {
|
||||
const doc = await azdata.queryeditor.openQueryDocument(
|
||||
{
|
||||
content: item.queryText
|
||||
}, item.connectionProfile?.providerId);
|
||||
await azdata.queryeditor.connect(doc.uri, item.connectionProfile?.connectionId || '');
|
||||
azdata.queryeditor.runQuery(doc.uri);
|
||||
}
|
||||
|
||||
@@ -8,9 +8,8 @@ import * as azdata from 'azdata';
|
||||
import { EOL } from 'os';
|
||||
import { QueryHistoryItem } from './queryHistoryItem';
|
||||
import { removeNewLines } from './utils';
|
||||
import { CAPTURE_ENABLED_CONFIG_SECTION, ITEM_SELECTED_COMMAND_ID, QUERY_HISTORY_CONFIG_SECTION } from './constants';
|
||||
|
||||
const QUERY_HISTORY_CONFIG_SECTION = 'queryHistory';
|
||||
const CAPTURE_ENABLED_CONFIG_SECTION = 'captureEnabled';
|
||||
const DEFAULT_CAPTURE_ENABLED = true;
|
||||
const successIcon = new vscode.ThemeIcon('check', new vscode.ThemeColor('testing.iconPassed'));
|
||||
const failedIcon = new vscode.ThemeIcon('error', new vscode.ThemeColor('testing.iconFailed'));
|
||||
@@ -70,6 +69,7 @@ export class QueryHistoryProvider implements vscode.TreeDataProvider<QueryHistor
|
||||
treeItem.iconPath = item.isSuccess ? successIcon : failedIcon;
|
||||
treeItem.tooltip = item.queryText;
|
||||
treeItem.description = item.connectionProfile ? `${item.connectionProfile.serverName}|${item.connectionProfile.databaseName} ${item.timestamp.toLocaleString()}` : item.timestamp.toLocaleString();
|
||||
treeItem.command = { title: '', command: ITEM_SELECTED_COMMAND_ID, arguments: [item] };
|
||||
return treeItem;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user