mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-17 17:22:42 -05:00
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:
@@ -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();
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user