From f8ccafd2af1af0bbf543808e3054001e36ea4ef0 Mon Sep 17 00:00:00 2001 From: Anthony Dresser Date: Tue, 28 May 2019 12:44:22 -0700 Subject: [PATCH] Add focus logic to the tabbed panel (#5649) * add focus logic to the tabbed panel * change enter to be on key up * fix tests --- src/sql/base/browser/ui/panel/panel.ts | 11 +++++++++-- src/sql/platform/dialog/dialogPane.ts | 7 ++++--- src/sql/workbench/parts/charts/browser/chartView.ts | 3 +++ .../parts/profiler/browser/profilerEditor.ts | 6 ++++-- src/sql/workbench/parts/query/browser/messagePanel.ts | 7 ++++++- src/sql/workbench/parts/query/browser/queryEditor.ts | 4 ++-- .../workbench/parts/query/browser/queryResultsView.ts | 8 ++++++++ .../parts/query/electron-browser/gridPanel.ts | 4 ++++ .../parts/query/modelViewTab/queryModelViewTab.ts | 4 ++++ .../parts/queryPlan/browser/topOperations.ts | 4 ++++ .../parts/queryPlan/electron-browser/queryPlan.ts | 4 ++++ .../workbench/parts/restore/browser/restoreDialog.ts | 9 ++++++--- .../connection/browser/connectionDialogWidget.ts | 6 ++++-- 13 files changed, 62 insertions(+), 15 deletions(-) diff --git a/src/sql/base/browser/ui/panel/panel.ts b/src/sql/base/browser/ui/panel/panel.ts index 1e515dcb44..eaab021b1e 100644 --- a/src/sql/base/browser/ui/panel/panel.ts +++ b/src/sql/base/browser/ui/panel/panel.ts @@ -29,6 +29,7 @@ export interface IPanelOptions { export interface IPanelView { render(container: HTMLElement): void; layout(dimension: DOM.Dimension): void; + focus(): void; remove?(): void; } @@ -143,7 +144,7 @@ export class TabbedPanel extends Disposable { tabLabel.innerText = tab.title; tabElement.appendChild(tabLabel); tab.disposables.push(DOM.addDisposableListener(tabHeaderElement, DOM.EventType.CLICK, e => this.showTab(tab.identifier))); - tab.disposables.push(DOM.addDisposableListener(tabHeaderElement, DOM.EventType.KEY_DOWN, (e: KeyboardEvent) => { + tab.disposables.push(DOM.addDisposableListener(tabHeaderElement, DOM.EventType.KEY_UP, (e: KeyboardEvent) => { let event = new StandardKeyboardEvent(e); if (event.equals(KeyCode.Enter)) { this.showTab(tab.identifier); @@ -188,6 +189,7 @@ export class TabbedPanel extends Disposable { if (this._currentDimensions) { this._layoutCurrentTab(new DOM.Dimension(this._currentDimensions.width, this._currentDimensions.height - this.headersize)); } + this.focus(); } public removeTab(tab: PanelTabIdentifier) { @@ -306,7 +308,12 @@ export class TabbedPanel extends Disposable { } public focus(): void { - + if (this._shownTabId) { + const tab = this._tabMap.get(this._shownTabId); + if (tab) { + tab.view.focus(); + } + } } public set collapsed(val: boolean) { diff --git a/src/sql/platform/dialog/dialogPane.ts b/src/sql/platform/dialog/dialogPane.ts index 18e43fc488..38bf27546e 100644 --- a/src/sql/platform/dialog/dialogPane.ts +++ b/src/sql/platform/dialog/dialogPane.ts @@ -78,9 +78,10 @@ export class DialogPane extends Disposable implements IThemable { container.appendChild(tabContainer); tabContainer.style.display = 'block'; }, - layout: (dimension) => { this.getTabDimension(); } - } as IPanelView - } as IPanelTab); + layout: (dimension) => { this.getTabDimension(); }, + focus: () => { } + } + }); }); } diff --git a/src/sql/workbench/parts/charts/browser/chartView.ts b/src/sql/workbench/parts/charts/browser/chartView.ts index 988e609ee8..7b92a5e8c4 100644 --- a/src/sql/workbench/parts/charts/browser/chartView.ts +++ b/src/sql/workbench/parts/charts/browser/chartView.ts @@ -177,6 +177,9 @@ export class ChartView extends Disposable implements IPanelView { } } + focus(): void { + } + public set queryRunner(runner: QueryRunner) { this._queryRunner = runner; this.shouldGraph(); diff --git a/src/sql/workbench/parts/profiler/browser/profilerEditor.ts b/src/sql/workbench/parts/profiler/browser/profilerEditor.ts index c23f4f878f..e9e837ba37 100644 --- a/src/sql/workbench/parts/profiler/browser/profilerEditor.ts +++ b/src/sql/workbench/parts/profiler/browser/profilerEditor.ts @@ -341,7 +341,8 @@ export class ProfilerEditor extends BaseEditor { title: nls.localize('text', "Text"), view: { layout: dim => this._editor.layout(dim), - render: parent => parent.appendChild(editorContainer) + render: parent => parent.appendChild(editorContainer), + focus: () => this._editor.focus() } }); @@ -379,7 +380,8 @@ export class ProfilerEditor extends BaseEditor { title: nls.localize('details', "Details"), view: { layout: dim => this._detailTable.layout(dim), - render: parent => parent.appendChild(detailTableContainer) + render: parent => parent.appendChild(detailTableContainer), + focus: () => this._detailTable.focus() } }); diff --git a/src/sql/workbench/parts/query/browser/messagePanel.ts b/src/sql/workbench/parts/query/browser/messagePanel.ts index 6e40f0e41f..d15299d29f 100644 --- a/src/sql/workbench/parts/query/browser/messagePanel.ts +++ b/src/sql/workbench/parts/query/browser/messagePanel.ts @@ -94,6 +94,7 @@ export class MessagePanel extends Disposable { renderer: this.renderer, controller: this.controller }, { keyboardSupport: false, horizontalScrollMode: ScrollbarVisibility.Auto })); + this.tree.setInput(this.model); this.tree.onDidScroll(e => { // convert to old VS Code tree interface with expandable methods let expandableTree: IExpandableTree = this.tree; @@ -158,7 +159,6 @@ export class MessagePanel extends Disposable { this.container.style.height = '100%'; this._register(attachListStyler(this.tree, this.themeService)); container.appendChild(this.container); - this.tree.setInput(this.model); } public layout(size: Dimension): void { @@ -176,6 +176,11 @@ export class MessagePanel extends Disposable { } } + public focus(): void { + this.tree.refresh(); + this.tree.domFocus(); + } + public set queryRunner(runner: QueryRunner) { dispose(this.queryRunnerDisposables); this.queryRunnerDisposables = []; diff --git a/src/sql/workbench/parts/query/browser/queryEditor.ts b/src/sql/workbench/parts/query/browser/queryEditor.ts index 2079665794..8f0ac81759 100644 --- a/src/sql/workbench/parts/query/browser/queryEditor.ts +++ b/src/sql/workbench/parts/query/browser/queryEditor.ts @@ -110,7 +110,7 @@ export class QueryEditor extends BaseEditor { this.splitview.addView({ element: this.textEditorContainer, layout: size => this.textEditor.layout(new DOM.Dimension(this.dimension.width, size)), - minimumSize: 220, + minimumSize: 0, maximumSize: Number.POSITIVE_INFINITY, onDidChange: Event.None }, Sizing.Distribute); @@ -336,7 +336,7 @@ export class QueryEditor extends BaseEditor { this.splitview.addView({ element: this.resultsEditorContainer, layout: size => this.resultsEditor && this.resultsEditor.layout(new DOM.Dimension(this.dimension.width, size)), - minimumSize: 220, + minimumSize: 0, maximumSize: Number.POSITIVE_INFINITY, onDidChange: Event.None }, Sizing.Distribute); diff --git a/src/sql/workbench/parts/query/browser/queryResultsView.ts b/src/sql/workbench/parts/query/browser/queryResultsView.ts index c891aec59d..96b855ada2 100644 --- a/src/sql/workbench/parts/query/browser/queryResultsView.ts +++ b/src/sql/workbench/parts/query/browser/queryResultsView.ts @@ -42,6 +42,10 @@ class MessagesView extends Disposable implements IPanelView { this.messagePanel.layout(dimension); } + focus(): void { + this.messagePanel.focus(); + } + public clear() { this.messagePanel.clear(); } @@ -85,6 +89,10 @@ class ResultsView extends Disposable implements IPanelView { this.gridPanel.layout(dimension); } + focus(): void { + this.gridPanel.focus(); + } + public clear() { this.gridPanel.clear(); } diff --git a/src/sql/workbench/parts/query/electron-browser/gridPanel.ts b/src/sql/workbench/parts/query/electron-browser/gridPanel.ts index 2fb931ff76..d949df64af 100644 --- a/src/sql/workbench/parts/query/electron-browser/gridPanel.ts +++ b/src/sql/workbench/parts/query/electron-browser/gridPanel.ts @@ -155,6 +155,10 @@ export class GridPanel { this.currentHeight = size.height; } + public focus(): void { + // will need to add logic to save the focused grid and focus that + } + public set queryRunner(runner: QueryRunner) { dispose(this.queryRunnerDisposables); this.reset(); diff --git a/src/sql/workbench/parts/query/modelViewTab/queryModelViewTab.ts b/src/sql/workbench/parts/query/modelViewTab/queryModelViewTab.ts index b3530f9400..6c93cec522 100644 --- a/src/sql/workbench/parts/query/modelViewTab/queryModelViewTab.ts +++ b/src/sql/workbench/parts/query/modelViewTab/queryModelViewTab.ts @@ -49,6 +49,10 @@ export class QueryModelViewTabView implements IPanelView { public layout(dimension: Dimension): void { } + public focus(): void { + + } + /** * Load the angular components and record for this input that we have done so */ diff --git a/src/sql/workbench/parts/queryPlan/browser/topOperations.ts b/src/sql/workbench/parts/queryPlan/browser/topOperations.ts index f4cd2122a0..be3cd1a582 100644 --- a/src/sql/workbench/parts/queryPlan/browser/topOperations.ts +++ b/src/sql/workbench/parts/queryPlan/browser/topOperations.ts @@ -89,6 +89,10 @@ export class TopOperationsView implements IPanelView { this.table.layout(dimension); } + public focus(): void { + this.table.focus(); + } + public clear() { this.dataView.clear(); } diff --git a/src/sql/workbench/parts/queryPlan/electron-browser/queryPlan.ts b/src/sql/workbench/parts/queryPlan/electron-browser/queryPlan.ts index ef39834f8b..2f05840da1 100644 --- a/src/sql/workbench/parts/queryPlan/electron-browser/queryPlan.ts +++ b/src/sql/workbench/parts/queryPlan/electron-browser/queryPlan.ts @@ -64,6 +64,10 @@ export class QueryPlanView implements IPanelView { this.container.style.height = dimension.height + 'px'; } + public focus() { + this.container.focus(); + } + public clear() { if (this.qp) { this.qp.xml = undefined; diff --git a/src/sql/workbench/parts/restore/browser/restoreDialog.ts b/src/sql/workbench/parts/restore/browser/restoreDialog.ts index a7ea4bddf6..a7786dd3c3 100644 --- a/src/sql/workbench/parts/restore/browser/restoreDialog.ts +++ b/src/sql/workbench/parts/restore/browser/restoreDialog.ts @@ -336,7 +336,8 @@ export class RestoreDialog extends Modal { render: c => { DOM.append(c, generalTab); }, - layout: () => { } + layout: () => { }, + focus: () => generalTab.focus() } }); @@ -347,7 +348,8 @@ export class RestoreDialog extends Modal { layout: () => { }, render: c => { c.appendChild(fileContentElement); - } + }, + focus: () => fileContentElement.focus() } }); @@ -358,7 +360,8 @@ export class RestoreDialog extends Modal { layout: () => { }, render: c => { c.appendChild(optionsContentElement); - } + }, + focus: () => optionsContentElement.focus() } }); diff --git a/src/sql/workbench/services/connection/browser/connectionDialogWidget.ts b/src/sql/workbench/services/connection/browser/connectionDialogWidget.ts index 3e19e17038..b646b5b2fa 100644 --- a/src/sql/workbench/services/connection/browser/connectionDialogWidget.ts +++ b/src/sql/workbench/services/connection/browser/connectionDialogWidget.ts @@ -163,7 +163,8 @@ export class ConnectionDialogWidget extends Modal { render: c => { c.append(recentConnectionTab); }, - layout: () => { } + layout: () => { }, + focus: () => this._recentConnectionTree.domFocus() } }); @@ -174,7 +175,8 @@ export class ConnectionDialogWidget extends Modal { layout: () => { }, render: c => { c.append(savedConnectionTab); - } + }, + focus: () => this._savedConnectionTree.domFocus() } });