From 5454917569df32fc011a46b97d9b991789cd11f8 Mon Sep 17 00:00:00 2001 From: Charles Gagnon Date: Mon, 7 Oct 2019 12:05:43 -0700 Subject: [PATCH] Add ability to handle enter key propagation for input model components (#7524) * Add ability to stop enter key propagation for input model components * Fix spacing * onInputEntered -> onEnterKeyPressed --- .../src/hdfs/ui/hdfsManageAccessDialog.ts | 13 ++++++++- src/sql/azdata.d.ts | 9 ++++++ src/sql/sqlops.proposed.d.ts | 9 ++++++ .../workbench/api/common/extHostModelView.ts | 13 +++++++++ .../workbench/api/common/sqlExtHostTypes.ts | 1 + .../modelComponents/inputbox.component.ts | 28 +++++++++++++++++++ .../browser/modelComponents/interfaces.ts | 1 + 7 files changed, 73 insertions(+), 1 deletion(-) diff --git a/extensions/mssql/src/hdfs/ui/hdfsManageAccessDialog.ts b/extensions/mssql/src/hdfs/ui/hdfsManageAccessDialog.ts index e5cd367a09..a24288a68f 100644 --- a/extensions/mssql/src/hdfs/ui/hdfsManageAccessDialog.ts +++ b/extensions/mssql/src/hdfs/ui/hdfsManageAccessDialog.ts @@ -130,7 +130,18 @@ export class ManageAccessDialog { rootContainer.addItem(typeContainer, { flex: '0 0 auto' }); const addUserOrGroupInputRow = modelView.modelBuilder.flexContainer().withLayout({ flexFlow: 'row' }).component(); - this.addUserOrGroupInput = modelView.modelBuilder.inputBox().withProperties({ inputType: 'text', placeHolder: enterNamePlaceholder, width: 250 }).component(); + this.addUserOrGroupInput = modelView.modelBuilder.inputBox() + .withProperties( + { + inputType: 'text', + placeHolder: enterNamePlaceholder, + width: 250, + stopEnterPropagation: true + }).component(); + this.addUserOrGroupInput.onEnterKeyPressed((value: string) => { + this.hdfsModel.createAndAddAclEntry(value, this.addUserOrGroupSelectedType); + this.addUserOrGroupInput.value = ''; + }); const addUserOrGroupButton = modelView.modelBuilder.button().withProperties({ label: addLabel, width: 75 }).component(); addUserOrGroupButton.onDidClick(() => { this.hdfsModel.createAndAddAclEntry(this.addUserOrGroupInput.value, this.addUserOrGroupSelectedType); diff --git a/src/sql/azdata.d.ts b/src/sql/azdata.d.ts index 116df5609c..35ade8d0ea 100644 --- a/src/sql/azdata.d.ts +++ b/src/sql/azdata.d.ts @@ -2991,6 +2991,11 @@ declare module 'azdata' { columns?: number; min?: number; max?: number; + /** + * Whether to stop key event propagation when enter is pressed in the input box. Leaving this as false + * means the event will propagate up to any parents that have handlers (such as validate on Dialogs) + */ + stopEnterPropagation?: boolean; } export interface TableColumn { @@ -3235,6 +3240,10 @@ declare module 'azdata' { export interface InputBoxComponent extends Component, InputBoxProperties { onTextChanged: vscode.Event; + /** + * Event that's fired whenever enter is pressed within the input box + */ + onEnterKeyPressed: vscode.Event; } export interface RadioButtonComponent extends Component, RadioButtonProperties { diff --git a/src/sql/sqlops.proposed.d.ts b/src/sql/sqlops.proposed.d.ts index 8136386cb7..542f5ba51b 100644 --- a/src/sql/sqlops.proposed.d.ts +++ b/src/sql/sqlops.proposed.d.ts @@ -514,6 +514,11 @@ declare module 'sqlops' { columns?: number; min?: number; max?: number; + /** + * Whether to stop key event propagation when enter is pressed in the input box. Leaving this as false + * means the event will propagate up to any parents that have handlers (such as validate on Dialogs) + */ + stopEnterPropagation?: boolean; } export interface TableColumn { @@ -703,6 +708,10 @@ declare module 'sqlops' { export interface InputBoxComponent extends Component, InputBoxProperties { onTextChanged: vscode.Event; + /** + * Event that's fired whenever enter is pressed within the input box + */ + onEnterKeyPressed: vscode.Event; } export interface RadioButtonComponent extends Component, RadioButtonProperties { diff --git a/src/sql/workbench/api/common/extHostModelView.ts b/src/sql/workbench/api/common/extHostModelView.ts index 1b6e41dc3f..4d2258e49d 100644 --- a/src/sql/workbench/api/common/extHostModelView.ts +++ b/src/sql/workbench/api/common/extHostModelView.ts @@ -769,6 +769,7 @@ class InputBoxWrapper extends ComponentWrapper implements azdata.InputBoxCompone super(proxy, handle, ModelComponentTypes.InputBox, id); this.properties = {}; this._emitterMap.set(ComponentEventType.onDidChange, new Emitter()); + this._emitterMap.set(ComponentEventType.onEnterKeyPressed, new Emitter()); } public get value(): string { @@ -841,10 +842,22 @@ class InputBoxWrapper extends ComponentWrapper implements azdata.InputBoxCompone this.setProperty('inputType', v); } + public get stopEnterPropagation(): boolean { + return this.properties['stopEnterPropagation']; + } + public set stopEnterPropagation(v: boolean) { + this.setProperty('stopEnterPropagation', v); + } + public get onTextChanged(): vscode.Event { let emitter = this._emitterMap.get(ComponentEventType.onDidChange); return emitter && emitter.event; } + + public get onEnterKeyPressed(): vscode.Event { + const emitter = this._emitterMap.get(ComponentEventType.onEnterKeyPressed); + return emitter && emitter.event; + } } class CheckBoxWrapper extends ComponentWrapper implements azdata.CheckBoxComponent { diff --git a/src/sql/workbench/api/common/sqlExtHostTypes.ts b/src/sql/workbench/api/common/sqlExtHostTypes.ts index 67c4bdc7ab..573aca390e 100644 --- a/src/sql/workbench/api/common/sqlExtHostTypes.ts +++ b/src/sql/workbench/api/common/sqlExtHostTypes.ts @@ -225,6 +225,7 @@ export enum ComponentEventType { onSelectedRowChanged, onComponentCreated, onCellAction, + onEnterKeyPressed } export interface IComponentEventArgs { diff --git a/src/sql/workbench/browser/modelComponents/inputbox.component.ts b/src/sql/workbench/browser/modelComponents/inputbox.component.ts index 345a1a4b6e..d5baf710cf 100644 --- a/src/sql/workbench/browser/modelComponents/inputbox.component.ts +++ b/src/sql/workbench/browser/modelComponents/inputbox.component.ts @@ -72,6 +72,17 @@ export default class InputBoxComponent extends ComponentBase implements ICompone }; if (this._inputContainer) { this._input = new InputBox(this._inputContainer.nativeElement, this.contextViewService, inputOptions); + this.onkeydown(this._input.inputElement, (e: StandardKeyboardEvent) => { + if (e.keyCode === KeyCode.Enter) { + this.fireEvent({ + eventType: ComponentEventType.onEnterKeyPressed, + args: this._input.value + }); + if (this.stopEnterPropagation) { + e.stopPropagation(); + } + } + }); this.registerInput(this._input, () => !this.multiline); } if (this._textareaContainer) { @@ -81,6 +92,15 @@ export default class InputBoxComponent extends ComponentBase implements ICompone if (this.tryHandleKeyEvent(e)) { e.stopPropagation(); } + if (e.keyCode === KeyCode.Enter) { + this.fireEvent({ + eventType: ComponentEventType.onEnterKeyPressed, + args: this._textAreaInput.value + }); + if (this.stopEnterPropagation) { + e.stopPropagation(); + } + } // Else assume that keybinding service handles routing this to a command }); @@ -308,4 +328,12 @@ export default class InputBoxComponent extends ComponentBase implements ICompone public set required(newValue: boolean) { this.setPropertyFromUI((props, value) => props.required = value, newValue); } + + public get stopEnterPropagation(): boolean { + return this.getPropertyOrDefault((props) => props.stopEnterPropagation, false); + } + + public set stopEnterPropagation(newValue: boolean) { + this.setPropertyFromUI((props, value) => props.stopEnterPropagation = value, newValue); + } } diff --git a/src/sql/workbench/browser/modelComponents/interfaces.ts b/src/sql/workbench/browser/modelComponents/interfaces.ts index 450e110208..85792ef236 100644 --- a/src/sql/workbench/browser/modelComponents/interfaces.ts +++ b/src/sql/workbench/browser/modelComponents/interfaces.ts @@ -69,6 +69,7 @@ export enum ComponentEventType { onSelectedRowChanged, onComponentCreated, onCellAction, + onEnterKeyPressed } export interface IModelStore {