diff --git a/extensions/query-history/package.json b/extensions/query-history/package.json index cc01b6ed7b..eeb8e7ec20 100644 --- a/extensions/query-history/package.json +++ b/extensions/query-history/package.json @@ -22,6 +22,22 @@ }, "extensionDependencies": [ ], + "contributes": { + "commands": [ + { + "command": "queryHistory.clear", + "title": "%queryHistory.clear%", + "category": "%queryHistory.displayName%" + } + ], + "menus": { + "commandPalette": [ + { + "command": "queryHistory.clear" + } + ] + } + }, "dependencies": { }, "devDependencies": { diff --git a/extensions/query-history/package.nls.json b/extensions/query-history/package.nls.json index 74e62fbf05..19a373d209 100644 --- a/extensions/query-history/package.nls.json +++ b/extensions/query-history/package.nls.json @@ -1,4 +1,5 @@ { "queryHistory.displayName": "Query History", - "queryHistory.description": "View and run previously executed queries" + "queryHistory.description": "View and run previously executed queries", + "queryHistory.clear": "Clear All History" } diff --git a/src/sql/platform/queryHistory/common/queryHistoryService.ts b/src/sql/platform/queryHistory/common/queryHistoryService.ts index a12e16a663..0eae3982ba 100644 --- a/src/sql/platform/queryHistory/common/queryHistoryService.ts +++ b/src/sql/platform/queryHistory/common/queryHistoryService.ts @@ -21,5 +21,6 @@ export interface IQueryHistoryService { getQueryHistoryInfos(): QueryHistoryInfo[]; deleteQueryHistoryInfo(info: QueryHistoryInfo): void; + clearQueryHistory(): void; start(): void; } diff --git a/src/sql/platform/queryHistory/common/queryHistoryServiceImpl.ts b/src/sql/platform/queryHistory/common/queryHistoryServiceImpl.ts index 5deb65374f..9ffb73376f 100644 --- a/src/sql/platform/queryHistory/common/queryHistoryServiceImpl.ts +++ b/src/sql/platform/queryHistory/common/queryHistoryServiceImpl.ts @@ -78,6 +78,14 @@ export class QueryHistoryService extends Disposable implements IQueryHistoryServ this._onInfosUpdated.fire(this._infos); } + /** + * Clears all infos from the cache + */ + public clearQueryHistory() { + this._infos = []; + this._onInfosUpdated.fire(this._infos); + } + /** * Method to force initialization of the service so that it can start tracking query events */ diff --git a/src/sql/workbench/parts/queryHistory/browser/queryHistoryActionProvider.ts b/src/sql/workbench/parts/queryHistory/browser/queryHistoryActionProvider.ts index 7daa53e168..3795fdc8b2 100644 --- a/src/sql/workbench/parts/queryHistory/browser/queryHistoryActionProvider.ts +++ b/src/sql/workbench/parts/queryHistory/browser/queryHistoryActionProvider.ts @@ -3,7 +3,7 @@ * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { DeleteAction, OpenQueryAction, RunQueryAction } from 'sql/workbench/parts/queryHistory/browser/queryHistoryActions'; +import { DeleteAction, OpenQueryAction, RunQueryAction, ClearHistoryAction } from 'sql/workbench/parts/queryHistory/browser/queryHistoryActions'; import { ITree } from 'vs/base/parts/tree/browser/tree'; import { ContributableActionProvider } from 'vs/workbench/browser/actions'; import { IAction } from 'vs/base/common/actions'; @@ -15,40 +15,46 @@ import { QueryHistoryNode } from 'sql/workbench/parts/queryHistory/browser/query */ export class QueryHistoryActionProvider extends ContributableActionProvider { + private _actions: { + openQueryAction: IAction, + runQueryAction: IAction, + deleteAction: IAction, + clearAction: IAction + }; + constructor( - @IInstantiationService private _instantiationService: IInstantiationService + @IInstantiationService instantiationService: IInstantiationService ) { super(); + this._actions = { + openQueryAction: instantiationService.createInstance(OpenQueryAction, OpenQueryAction.ID, OpenQueryAction.LABEL), + runQueryAction: instantiationService.createInstance(RunQueryAction, RunQueryAction.ID, RunQueryAction.LABEL), + deleteAction: instantiationService.createInstance(DeleteAction, DeleteAction.ID, DeleteAction.LABEL), + clearAction: instantiationService.createInstance(ClearHistoryAction, ClearHistoryAction.ID, ClearHistoryAction.LABEL) + }; } - public hasActions(tree: ITree, element: any): boolean { + public hasActions(element: any): boolean { return element instanceof QueryHistoryNode; } /** - * Return actions given an element in the tree + * Return actions for a selected node - or the default actions if no node is selected */ - public getActions(tree: ITree, element: any): IAction[] { + public getActions(element: any): IAction[] { + const actions: IAction[] = []; if (element instanceof QueryHistoryNode && element.info) { - return this.getQueryHistoryActions(tree, element); + if (element.info && element.info.queryText && element.info.queryText !== '') { + actions.push(this._actions.openQueryAction); + actions.push(this._actions.runQueryAction); + } + actions.push(this._actions.deleteAction); } - return []; + actions.push(this._actions.clearAction); + return actions; } public hasSecondaryActions(tree: ITree, element: any): boolean { return false; } - - /** - * Return actions for query history task - */ - public getQueryHistoryActions(tree: ITree, element: QueryHistoryNode): IAction[] { - const actions: IAction[] = []; - if (element.info && element.info.queryText && element.info.queryText !== '') { - actions.push(this._instantiationService.createInstance(OpenQueryAction, OpenQueryAction.ID, OpenQueryAction.LABEL)); - actions.push(this._instantiationService.createInstance(RunQueryAction, RunQueryAction.ID, RunQueryAction.LABEL)); - } - actions.push(this._instantiationService.createInstance(DeleteAction, DeleteAction.ID, DeleteAction.LABEL)); - return actions; - } } diff --git a/src/sql/workbench/parts/queryHistory/browser/queryHistoryActions.ts b/src/sql/workbench/parts/queryHistory/browser/queryHistoryActions.ts index a8844201ea..6310ce7411 100644 --- a/src/sql/workbench/parts/queryHistory/browser/queryHistoryActions.ts +++ b/src/sql/workbench/parts/queryHistory/browser/queryHistoryActions.ts @@ -15,6 +15,7 @@ import { IQueryHistoryService } from 'sql/platform/queryHistory/common/queryHist import { QueryHistoryNode } from 'sql/workbench/parts/queryHistory/browser/queryHistoryNode'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { openNewQuery } from 'sql/workbench/parts/query/browser/queryActions'; +import { ICommandService } from 'vs/platform/commands/common/commands'; export class ToggleQueryHistoryAction extends TogglePanelAction { @@ -42,11 +43,27 @@ export class DeleteAction extends Action { super(id, label); } - public async run(element: QueryHistoryNode): Promise { + public async run(element: QueryHistoryNode): Promise { if (element instanceof QueryHistoryNode && element.info) { this._queryHistoryService.deleteQueryHistoryInfo(element.info); } - return true; + } +} + +export class ClearHistoryAction extends Action { + public static ID = 'queryHistory.clear'; + public static LABEL = localize('queryHistory.clearLabel', "Clear All History"); + + constructor( + id: string, + label: string, + @ICommandService private _commandService: ICommandService + ) { + super(id, label, 'clear-query-history-action codicon-clear-all'); + } + + public async run(): Promise { + this._commandService.executeCommand('queryHistory.clear'); } } @@ -63,11 +80,10 @@ export class OpenQueryAction extends Action { super(id, label); } - public async run(element: QueryHistoryNode): Promise { + public async run(element: QueryHistoryNode): Promise { if (element instanceof QueryHistoryNode && element.info) { return this._instantiationService.invokeFunction(openNewQuery, element.info.connectionProfile, element.info.queryText, RunQueryOnConnectionMode.none).then(() => true, () => false); } - return true; } } @@ -83,11 +99,10 @@ export class RunQueryAction extends Action { super(id, label); } - public async run(element: QueryHistoryNode): Promise { + public async run(element: QueryHistoryNode): Promise { if (element instanceof QueryHistoryNode && element.info) { return this._instantiationService.invokeFunction(openNewQuery, element.info.connectionProfile, element.info.queryText, RunQueryOnConnectionMode.executeQuery).catch(() => true, () => false); } - return true; } } diff --git a/src/sql/workbench/parts/queryHistory/browser/queryHistoryController.ts b/src/sql/workbench/parts/queryHistory/browser/queryHistoryController.ts index 96d1c6a6ce..11b0e65795 100644 --- a/src/sql/workbench/parts/queryHistory/browser/queryHistoryController.ts +++ b/src/sql/workbench/parts/queryHistory/browser/queryHistoryController.ts @@ -65,7 +65,7 @@ export class QueryHistoryController extends treeDefaults.DefaultController { let anchor = { x: event.posx + 1, y: event.posy }; this.contextMenuService.showContextMenu({ getAnchor: () => anchor, - getActions: () => this.actionProvider.getActions(tree, element), + getActions: () => this.actionProvider.getActions(element), getKeyBinding: (action) => this.keybindingService.lookupKeybinding(action.id), onHide: (wasCancelled?: boolean) => { if (wasCancelled) { diff --git a/src/sql/workbench/parts/queryHistory/browser/queryHistoryPanel.ts b/src/sql/workbench/parts/queryHistory/browser/queryHistoryPanel.ts index 4712ce3c26..810c797914 100644 --- a/src/sql/workbench/parts/queryHistory/browser/queryHistoryPanel.ts +++ b/src/sql/workbench/parts/queryHistory/browser/queryHistoryPanel.ts @@ -12,6 +12,7 @@ import { QueryHistoryView } from 'sql/workbench/parts/queryHistory/browser/query import { IStorageService } from 'vs/platform/storage/common/storage'; import { Panel } from 'vs/workbench/browser/panel'; import { QUERY_HISTORY_PANEL_ID } from 'sql/workbench/parts/queryHistory/common/constants'; +import { IAction } from 'vs/base/common/actions'; export class QueryHistoryPanel extends Panel { @@ -40,4 +41,8 @@ export class QueryHistoryPanel extends Panel { public layout({ height }: Dimension): void { this._queryHistoryView.layout(height); } + + getActions(): IAction[] { + return this._queryHistoryView.getActions(); + } } diff --git a/src/sql/workbench/parts/queryHistory/browser/queryHistoryView.ts b/src/sql/workbench/parts/queryHistory/browser/queryHistoryView.ts index 4fda4e27bc..bb2bc25552 100644 --- a/src/sql/workbench/parts/queryHistory/browser/queryHistoryView.ts +++ b/src/sql/workbench/parts/queryHistory/browser/queryHistoryView.ts @@ -12,7 +12,7 @@ import { ITree } from 'vs/base/parts/tree/browser/tree'; import { Disposable } from 'vs/base/common/lifecycle'; import { DefaultFilter, DefaultDragAndDrop, DefaultAccessibilityProvider } from 'vs/base/parts/tree/browser/treeDefaults'; import { localize } from 'vs/nls'; -import { hide, $, append } from 'vs/base/browser/dom'; +import { hide, $, append, show } from 'vs/base/browser/dom'; import { QueryHistoryRenderer } from 'sql/workbench/parts/queryHistory/browser/queryHistoryRenderer'; import { QueryHistoryDataSource } from 'sql/workbench/parts/queryHistory/browser/queryHistoryDataSource'; import { QueryHistoryController } from 'sql/workbench/parts/queryHistory/browser/queryHistoryController'; @@ -21,12 +21,14 @@ import { IExpandableTree } from 'sql/workbench/parts/objectExplorer/browser/tree import { IQueryHistoryService } from 'sql/platform/queryHistory/common/queryHistoryService'; import { QueryHistoryNode } from 'sql/workbench/parts/queryHistory/browser/queryHistoryNode'; import { QueryHistoryInfo } from 'sql/platform/queryHistory/common/queryHistoryInfo'; +import { IAction } from 'vs/base/common/actions'; /** * QueryHistoryView implements the dynamic tree view for displaying Query History */ export class QueryHistoryView extends Disposable { private _messages: HTMLElement; private _tree: ITree; + private _actionProvider: QueryHistoryActionProvider; constructor( @IInstantiationService private _instantiationService: IInstantiationService, @@ -34,6 +36,7 @@ export class QueryHistoryView extends Disposable { @IQueryHistoryService private readonly _queryHistoryService: IQueryHistoryService ) { super(); + this._actionProvider = this._instantiationService.createInstance(QueryHistoryActionProvider); } /** @@ -64,9 +67,8 @@ export class QueryHistoryView extends Disposable { */ public createQueryHistoryTree(treeContainer: HTMLElement, instantiationService: IInstantiationService): Tree { const dataSource = instantiationService.createInstance(QueryHistoryDataSource); - const actionProvider = instantiationService.createInstance(QueryHistoryActionProvider); const renderer = instantiationService.createInstance(QueryHistoryRenderer); - const controller = instantiationService.createInstance(QueryHistoryController, actionProvider); + const controller = instantiationService.createInstance(QueryHistoryController, this._actionProvider); const dnd = new DefaultDragAndDrop(); const filter = new DefaultFilter(); const sorter = null; @@ -85,9 +87,6 @@ export class QueryHistoryView extends Disposable { let selectedElement: any; let targetsToExpand: any[]; - // Focus - this._tree.domFocus(); - if (this._tree) { const selection = this._tree.getSelection(); if (selection && selection.length === 1) { @@ -102,6 +101,8 @@ export class QueryHistoryView extends Disposable { if (nodes.length > 0) { hide(this._messages); + } else { + show(this._messages); } // Set the tree input - root node is just an empty container node @@ -117,7 +118,6 @@ export class QueryHistoryView extends Disposable { if (selectedElement) { this._tree.select(selectedElement); } - this._tree.getFocus(); }, errors.onUnexpectedError); } @@ -138,4 +138,9 @@ export class QueryHistoryView extends Disposable { this._tree.onHidden(); } } + + + public getActions(): IAction[] { + return this._actionProvider.getActions(undefined); + } } diff --git a/src/sql/workbench/parts/queryHistory/electron-browser/queryHistory.ts b/src/sql/workbench/parts/queryHistory/electron-browser/queryHistory.ts index 798702850b..05f5cf6bab 100644 --- a/src/sql/workbench/parts/queryHistory/electron-browser/queryHistory.ts +++ b/src/sql/workbench/parts/queryHistory/electron-browser/queryHistory.ts @@ -23,11 +23,6 @@ export class QueryHistoryWorkbenchContribution implements IWorkbenchContribution constructor( @IQueryHistoryService _queryHistoryService: IQueryHistoryService ) { - // We need this to be running in the background even if the Panel (which is currently the only thing using it) - // isn't shown yet. Otherwise the service won't be initialized until the Panel is which means we might miss out - // on some events - _queryHistoryService.start(); - // This feature is in preview so for now hide it behind a flag. We expose this as a command // so that the query-history extension can call it. We eventually want to move all this into // the extension itself so this should be a temporary workaround @@ -38,6 +33,20 @@ export class QueryHistoryWorkbenchContribution implements IWorkbenchContribution // we don't want to try and register multiple times if (!this.queryHistoryEnabled) { this.queryHistoryEnabled = true; + + // We need this to be running in the background even if the Panel (which is currently the only thing using it) + // isn't shown yet. Otherwise the service won't be initialized until the Panel is which means we might miss out + // on some events + _queryHistoryService.start(); + + CommandsRegistry.registerCommand({ + id: 'queryHistory.clear', + handler: (accessor) => { + const queryHistoryService = accessor.get(IQueryHistoryService); + queryHistoryService.clearQueryHistory(); + } + }); + const registry = Registry.as(ActionExtensions.WorkbenchActions); registry.registerWorkbenchAction( new SyncActionDescriptor(