handle edit and save race condition (#20462)

* handle edit and save race condition

* handle more race condition scenarios

* fix error
This commit is contained in:
Alan Ren
2022-08-25 08:10:23 -07:00
committed by GitHub
parent b7a633be25
commit f86d02e753
4 changed files with 110 additions and 43 deletions

View File

@@ -51,6 +51,8 @@ import { RowMoveManager, RowMoveOnDragEventData } from 'sql/base/browser/ui/tabl
import { ITaskbarContent, Taskbar } from 'sql/base/browser/ui/taskbar/taskbar';
import { RowSelectionModel } from 'sql/base/browser/ui/table/plugins/rowSelectionModel.plugin';
import { listFocusAndSelectionBackground } from 'sql/platform/theme/common/colors';
import { timeout } from 'vs/base/common/async';
import { onUnexpectedError } from 'vs/base/common/errors';
export interface IDesignerStyle {
tabbedPanelStyles?: ITabbedPanelStyles;
@@ -282,6 +284,9 @@ export class Designer extends Disposable implements IThemable {
public setInput(input: DesignerComponentInput): void {
if (this._input) {
void this.submitPendingChanges().catch(onUnexpectedError);
}
this.saveUIState();
if (this._loadingTimeoutHandle) {
this.stopLoading();
@@ -303,7 +308,9 @@ export class Designer extends Disposable implements IThemable {
this._inputDisposable.add(this._input.onRefreshRequested(() => {
this.refresh();
}));
this._inputDisposable.add(this._input.onSubmitPendingEditRequested(async () => {
await this.submitPendingChanges();
}));
if (this._input.view === undefined) {
this._input.initialize();
} else {
@@ -319,6 +326,14 @@ export class Designer extends Disposable implements IThemable {
this._inputDisposable?.dispose();
}
public async submitPendingChanges(): Promise<void> {
if (this._container.contains(document.activeElement) && document.activeElement instanceof HTMLInputElement) {
// Force the elements to fire the blur event to submit the pending changes.
document.activeElement.blur();
return timeout(10);
}
}
private clearUI(): void {
this._componentMap.forEach(item => item.component.dispose());
this._componentMap.clear();

View File

@@ -28,6 +28,11 @@ export interface DesignerComponentInput {
*/
readonly onRefreshRequested: Event<void>;
/**
* The event that is triggerd when force submit of the pending edit is requested.
*/
readonly onSubmitPendingEditRequested: Event<void>;
/**
* Gets the object type display name.
*/

View File

@@ -21,6 +21,7 @@ export class DesignerTableAction extends Action {
protected _table: Table<Slick.SlickData>;
constructor(
private _designer: Designer,
id: string,
label: string,
icon: string,
@@ -43,6 +44,10 @@ export class DesignerTableAction extends Action {
}
}
}
public override async run(context: DesignerTableActionContext): Promise<void> {
await this._designer.submitPendingChanges();
}
}
export class AddRowAction extends DesignerTableAction {
@@ -54,12 +59,13 @@ export class AddRowAction extends DesignerTableAction {
private designer: Designer,
tableProperties: DesignerTableProperties,
) {
super(AddRowAction.ID, tableProperties.labelForAddNewButton || AddRowAction.LABEL, AddRowAction.ICON, false);
super(designer, AddRowAction.ID, tableProperties.labelForAddNewButton || AddRowAction.LABEL, AddRowAction.ICON, false);
this.designer = designer;
this._tooltip = localize('designer.newRowButtonAriaLabel', "Add new row to '{0}' table", tableProperties.ariaLabel);
}
public override async run(context: DesignerTableActionContext): Promise<void> {
await super.run(context);
const lastIndex = context.table.getData().getItems().length;
return new Promise((resolve) => {
this.designer.handleEdit({
@@ -78,13 +84,14 @@ export class MoveRowUpAction extends DesignerTableAction {
public static LABEL = localize('designer.moveRowUpAction', 'Move Up');
constructor(private designer: Designer) {
super(MoveRowUpAction.ID, MoveRowUpAction.LABEL, MoveRowUpAction.ICON, true);
super(designer, MoveRowUpAction.ID, MoveRowUpAction.LABEL, MoveRowUpAction.ICON, true);
this.designer = designer;
this._tooltip = localize('designer.moveRowUpButtonAriaLabel', "Move selected row up one position");
this.enabled = false;
}
public override async run(context: DesignerTableActionContext): Promise<void> {
await super.run(context);
let rowIndex = context.selectedRow ?? context.table.getSelectedRows()[0];
if (rowIndex - 1 < 0) {
return;
@@ -116,13 +123,14 @@ export class MoveRowDownAction extends DesignerTableAction {
public static LABEL = localize('designer.moveRowDownAction', 'Move Down');
constructor(private designer: Designer) {
super(MoveRowDownAction.ID, MoveRowDownAction.LABEL, MoveRowDownAction.ICON, true);
super(designer, MoveRowDownAction.ID, MoveRowDownAction.LABEL, MoveRowDownAction.ICON, true);
this.designer = designer;
this._tooltip = localize('designer.moveRowDownButtonAriaLabel', "Move selected row down one position");
this.enabled = false;
}
public override async run(context: DesignerTableActionContext): Promise<void> {
await super.run(context);
let rowIndex = context.selectedRow ?? context.table.getSelectedRows()[0];
const tableData = context.table.getData().getItems();
if (rowIndex + 1 >= tableData.length) {