From a6ba44e435ef5ebe5ef720748d76bb129e774662 Mon Sep 17 00:00:00 2001 From: Abbie Petchtes Date: Thu, 5 Apr 2018 14:42:21 -0700 Subject: [PATCH] Fix accessibility issue for clear history button in connection dialog (#1084) * change clear history connections button to action bar * formatting --- .../connection/common/connectionActions.ts | 102 ++++++++++++------ .../connectionDialogWidget.ts | 33 ++---- .../media/connectionDialog.css | 18 ++-- 3 files changed, 90 insertions(+), 63 deletions(-) diff --git a/src/sql/parts/connection/common/connectionActions.ts b/src/sql/parts/connection/common/connectionActions.ts index 3adde95480..fa10033384 100644 --- a/src/sql/parts/connection/common/connectionActions.ts +++ b/src/sql/parts/connection/common/connectionActions.ts @@ -12,58 +12,94 @@ import { IConnectionProfile } from 'sql/parts/connection/common/interfaces'; import { IConnectionManagementService } from 'sql/parts/connection/common/connectionManagement'; import { INotificationService, INotificationActions } from 'vs/platform/notification/common/notification'; import Severity from 'vs/base/common/severity'; +import { IConfirmationService, IChoiceService, IConfirmation, IConfirmationResult, Choice } from 'vs/platform/dialogs/common/dialogs'; /** * Workbench action to clear the recent connnections list */ export class ClearRecentConnectionsAction extends Action { - public static ID = 'clearRecentConnectionsAction'; - public static LABEL = nls.localize('ClearRecentlyUsedLabel', 'Clear Recent Connections List'); + public static ID = 'clearRecentConnectionsAction'; + public static LABEL = nls.localize('ClearRecentlyUsedLabel', 'Clear Recent Connections List'); + public static ICON = 'search-action clear-search-results'; - constructor( - id: string, - label: string, - @IConnectionManagementService private _connectionManagementService: IConnectionManagementService, - @INotificationService private _notificationService: INotificationService, - @IQuickOpenService private _quickOpenService: IQuickOpenService - ) { - super(id, label); - this.enabled = true; - } + private _onRecentConnectionsRemoved = new Emitter(); + public onRecentConnectionsRemoved: Event = this._onRecentConnectionsRemoved.event; - public run(): TPromise { - let self = this; - return self.promptToClearRecentConnectionsList().then(result => { + private _useConfirmationMessage = false; + + constructor( + id: string, + label: string, + @IConnectionManagementService private _connectionManagementService: IConnectionManagementService, + @INotificationService private _notificationService: INotificationService, + @IQuickOpenService private _quickOpenService: IQuickOpenService, + @IConfirmationService private _confirmationService: IConfirmationService, + ) { + super(id, label, ClearRecentConnectionsAction.ICON); + this.enabled = true; + } + + public set useConfirmationMessage(value: boolean) { + this._useConfirmationMessage = value; + } + + public run(): TPromise { + if (this._useConfirmationMessage) { + return this.promptConfirmationMessage().then(result => { if (result) { - self._connectionManagementService.clearRecentConnectionsList(); + this._connectionManagementService.clearRecentConnectionsList(); + this._onRecentConnectionsRemoved.fire(); + } + }); + } else { + return this.promptQuickOpenService().then(result => { + if (result) { + this._connectionManagementService.clearRecentConnectionsList(); - const actions: INotificationActions = { primary: [ ] }; - self._notificationService.notify({ + const actions: INotificationActions = { primary: [] }; + this._notificationService.notify({ severity: Severity.Info, message: nls.localize('ClearedRecentConnections', 'Recent connections list cleared'), actions }); + this._onRecentConnectionsRemoved.fire(); } }); } - - private promptToClearRecentConnectionsList(): TPromise { - const self = this; - return new TPromise((resolve, reject) => { - let choices: { key, value }[] = [ - { key: nls.localize('connectionAction.yes', 'Yes'), value: true }, - { key: nls.localize('connectionAction.no', 'No'), value: false } - ]; - - self._quickOpenService.pick(choices.map(x => x.key), { placeHolder: nls.localize('ClearRecentlyUsedLabel', 'Clear Recent Connections List'), ignoreFocusLost: true }).then((choice) => { - let confirm = choices.find(x => x.key === choice); - resolve(confirm && confirm.value); - }); - }); - } } + private promptQuickOpenService(): TPromise { + const self = this; + return new TPromise((resolve, reject) => { + let choices: { key, value }[] = [ + { key: nls.localize('connectionAction.yes', 'Yes'), value: true }, + { key: nls.localize('connectionAction.no', 'No'), value: false } + ]; + + self._quickOpenService.pick(choices.map(x => x.key), { placeHolder: nls.localize('ClearRecentlyUsedLabel', 'Clear Recent Connections List'), ignoreFocusLost: true }).then((choice) => { + let confirm = choices.find(x => x.key === choice); + resolve(confirm && confirm.value); + }); + }); + } + + private promptConfirmationMessage(): TPromise { + let confirm: IConfirmation = { + message: nls.localize('clearRecentConnectionMessage', 'Are you sure you want to delete all the connections from the list?'), + primaryButton: nls.localize('connectionDialog.yes', 'Yes'), + secondaryButton: nls.localize('connectionDialog.no', 'No'), + type: 'question' + }; + + return new TPromise((resolve, reject) => { + this._confirmationService.confirm(confirm).then((confirmed) => { + resolve(confirmed); + }); + }); + } +} + /** * Action to delete one recently used connection from the MRU */ diff --git a/src/sql/parts/connection/connectionDialog/connectionDialogWidget.ts b/src/sql/parts/connection/connectionDialog/connectionDialogWidget.ts index fac3df4011..3f01a8de49 100644 --- a/src/sql/parts/connection/connectionDialog/connectionDialogWidget.ts +++ b/src/sql/parts/connection/connectionDialog/connectionDialogWidget.ts @@ -18,6 +18,7 @@ import { TabbedPanel, PanelTabIdentifier } from 'sql/base/browser/ui/panel/panel import { RecentConnectionTreeController, RecentConnectionActionsProvider } from 'sql/parts/connection/connectionDialog/recentConnectionTreeController'; import { SavedConnectionTreeController } from 'sql/parts/connection/connectionDialog/savedConnectionTreeController'; import * as TelemetryKeys from 'sql/common/telemetryKeys'; +import { ClearRecentConnectionsAction } from 'sql/parts/connection/common/connectionActions'; import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { IWorkbenchThemeService, IColorTheme } from 'vs/workbench/services/themes/common/workbenchThemeService'; @@ -32,11 +33,11 @@ import { localize } from 'vs/nls'; import { ITree } from 'vs/base/parts/tree/browser/tree'; import { IContextMenuService, IContextViewService } from 'vs/platform/contextview/browser/contextView'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; -import { IConfirmationService, IChoiceService, IConfirmation, IConfirmationResult, Choice } from 'vs/platform/dialogs/common/dialogs'; import * as styler from 'vs/platform/theme/common/styler'; import { TPromise } from 'vs/base/common/winjs.base'; import * as DOM from 'vs/base/browser/dom'; import { DialogService } from 'vs/workbench/services/dialogs/electron-browser/dialogs'; +import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar'; export interface OnShowUIResponse { selectedProviderType: string; @@ -58,6 +59,7 @@ export class ConnectionDialogWidget extends Modal { private _savedConnectionTree: ITree; private $connectionUIContainer: Builder; private _databaseDropdownExpanded: boolean; + private _actionbar: ActionBar; private _panel: TabbedPanel; private _recentConnectionTabId: PanelTabIdentifier; @@ -90,7 +92,6 @@ export class ConnectionDialogWidget extends Modal { @ITelemetryService telemetryService: ITelemetryService, @IContextKeyService contextKeyService: IContextKeyService, @IContextMenuService private _contextMenuService: IContextMenuService, - @IConfirmationService private _confirmationService: IConfirmationService, @IContextViewService private _contextViewService: IContextViewService ) { super(localize('connection', 'Connection'), TelemetryKeys.Connection, _partService, telemetryService, contextKeyService, { hasSpinner: true, hasErrors: true }); @@ -257,26 +258,6 @@ export class ConnectionDialogWidget extends Modal { this.hide(); } - private clearRecentConnectionList(): TPromise { - - let confirm: IConfirmation = { - message: localize('clearRecentConnectionMessage', 'Are you sure you want to delete all the connections from the list?'), - primaryButton: localize('connectionDialog.yes', 'Yes'), - secondaryButton: localize('connectionDialog.no', 'No'), - type: 'question' - }; - - return new TPromise((resolve, reject) => { - this._confirmationService.confirm(confirm).then((confirmed) => { - if (confirmed) { - this._connectionManagementService.clearRecentConnectionsList(); - this.open(false); - } - resolve(confirmed); - }); - }); - } - private createRecentConnectionList(): void { this._recentConnectionBuilder.div({ class: 'connection-recent-content' }, (recentConnectionContainer) => { let recentHistoryLabel = localize('recentHistory', 'Recent history'); @@ -284,8 +265,12 @@ export class ConnectionDialogWidget extends Modal { container.div({ class: 'connection-history-label' }, (recentTitle) => { recentTitle.innerHtml(recentHistoryLabel); }); - container.div({ class: 'search-action clear-search-results' }, (clearSearchIcon) => { - clearSearchIcon.on('click', () => this.clearRecentConnectionList()); + container.div({ class: 'connection-history-actions' }, (actionsContainer) => { + this._actionbar = this._register(new ActionBar(actionsContainer, { animated: false })); + let clearAction = this._instantiationService.createInstance(ClearRecentConnectionsAction, ClearRecentConnectionsAction.ID, ClearRecentConnectionsAction.LABEL); + clearAction.useConfirmationMessage = true; + clearAction.onRecentConnectionsRemoved(() => this.open(false)); + this._actionbar.push(clearAction, { icon: true, label: false }); }); }); recentConnectionContainer.div({ class: 'server-explorer-viewlet' }, (divContainer: Builder) => { diff --git a/src/sql/parts/connection/connectionDialog/media/connectionDialog.css b/src/sql/parts/connection/connectionDialog/media/connectionDialog.css index fbf25ffbfe..2aeed52c7d 100644 --- a/src/sql/parts/connection/connectionDialog/media/connectionDialog.css +++ b/src/sql/parts/connection/connectionDialog/media/connectionDialog.css @@ -69,15 +69,21 @@ overflow-y: hidden; } +.connection-dialog .connection-history-actions .action-label.icon { + display: block; + height: 20px; + line-height: 20px; + min-width: 20px; + background-size: 16px; + background-position: center center; + background-repeat: no-repeat; +} + .search-action.clear-search-results { - background: url('clear-search-results.svg') center right no-repeat; - width: 10%; - cursor: pointer; + background: url('clear-search-results.svg'); } .vs-dark .search-action.clear-search-results, .hc-black .search-action.clear-search-results { - background: url('clear-search-results-dark.svg') center right no-repeat; - width: 10%; - cursor: pointer; + background: url('clear-search-results-dark.svg'); } \ No newline at end of file