fix(plugin-data-viewer): CB-1243 focus and selection behavior

This commit is contained in:
Wroud
2021-10-06 19:56:23 +03:00
parent 98ecd96406
commit a43f074edb
18 changed files with 210 additions and 71 deletions
@@ -196,6 +196,7 @@ export function useGridSelectionContext(
if (!multiple) {
selectionAction.clear();
return;
}
if (temporary) {
@@ -229,14 +230,14 @@ export function useGridSelectionContext(
return;
}
const column = props.tableData.getColumn(cell.colIdx);
if (state.range) {
return;
}
const isIndexColumn = props.tableData.isIndexColumn(column.key);
const column = props.tableData.getColumn(cell.colIdx);
const isIndexColumn = props.tableData.isIndexColumn(column.key);
const row = props.tableData.getRow(cell.rowIdx);
if (isIndexColumn) {
selectRows(row, row, undefined, multiple, temporary);
return;
@@ -81,6 +81,19 @@ export const DataGridTable = observer<IDataPresentationProps<any, IDatabaseResul
},
});
function isGridInFocus(): boolean {
const gridDiv = gridContainerRef.current;
const focusSink = gridDiv?.querySelector('.rdg-focus-sink');
if (!gridDiv || !focusSink) {
return false;
}
const active = document.activeElement;
return gridDiv === active || focusSink === active;
}
function setContainersRef(element: HTMLDivElement) {
gridContainerRef.current = element;
@@ -93,7 +106,7 @@ export const DataGridTable = observer<IDataPresentationProps<any, IDatabaseResul
}
}
const { onKeydownHandler } = useGridSelectedCellsCopy(tableData, gridSelectionContext);
const { onKeydownHandler } = useGridSelectedCellsCopy(tableData, selectionAction, gridSelectionContext);
const { onMouseDownHandler, onMouseMoveHandler } = useGridDragging({
onDragStart: startPosition => {
dataGridRef.current?.selectCell({ idx: startPosition.colIdx, rowIdx: startPosition.rowIdx });
@@ -154,17 +167,19 @@ export const DataGridTable = observer<IDataPresentationProps<any, IDatabaseResul
tableData.editor.action.addHandler(syncEditor);
function syncFocus(data: DatabaseDataSelectActionsData<IResultSetPartialKey>) {
if (data.type === 'focus') {
if (!data.key?.column || !data.key.row) {
return;
setTimeout(() => { // TODO: update focus after render rows update
if (data.type === 'focus') {
if (!data.key?.column || !data.key.row) {
return;
}
const idx = tableData.getColumnIndexFromColumnKey(data.key.column);
const rowIdx = tableData.getRowIndexFromKey(data.key.row);
focusSyncRef.current = { idx, rowIdx };
dataGridRef.current?.selectCell({ idx, rowIdx });
}
const idx = tableData.getColumnIndexFromColumnKey(data.key.column);
const rowIdx = tableData.getRowIndexFromKey(data.key.row);
focusSyncRef.current = { idx, rowIdx };
dataGridRef.current?.selectCell({ idx, rowIdx });
}
}, 1);
}
selectionAction.actions.addHandler(syncFocus);
@@ -229,10 +244,10 @@ export const DataGridTable = observer<IDataPresentationProps<any, IDatabaseResul
actions,
columnResize,
resultIndex,
isGridInFocus: () => gridContainerRef.current === document.activeElement,
isGridInFocus,
getEditorPortal: () => editorRef.current,
getDataGridApi: () => dataGridRef.current,
}), [model, actions, resultIndex, editorRef, dataGridRef]);
}), [model, actions, resultIndex, editorRef, dataGridRef, gridContainerRef]);
return styled(styles)(
<DataGridContext.Provider value={gridContext}>
@@ -10,7 +10,7 @@ import { useCallback } from 'react';
import { useObjectRef } from '@cloudbeaver/core-blocks';
import { copyToClipboard } from '@cloudbeaver/core-utils';
import { IResultSetColumnKey, IResultSetElementKey, ResultSetDataKeysUtils } from '@cloudbeaver/plugin-data-viewer';
import { IResultSetColumnKey, IResultSetElementKey, ResultSetDataKeysUtils, ResultSetSelectAction } from '@cloudbeaver/plugin-data-viewer';
import type { IDataGridSelectionContext } from './DataGridSelection/DataGridSelectionContext';
import type { ITableData } from './TableDataContext';
@@ -19,7 +19,13 @@ const EVENT_KEY_CODE = {
C: 'KeyC',
};
function copyGridSelectedDataToClipboard(
function getCellCopyValue(tableData: ITableData, key: IResultSetElementKey): string {
const cell = tableData.getCellValue(key);
const cellValue = cell !== undefined ? tableData.format.getText(cell) : undefined;
return cellValue ?? '';
}
function getSelectedCellsValue(
tableData: ITableData,
selectedCells: Map<string, IResultSetElementKey[]>
) {
@@ -48,9 +54,7 @@ function copyGridSelectedDataToClipboard(
const cellKey = rowSelection.find(key => ResultSetDataKeysUtils.isEqual(key.column, column));
if (cellKey) {
const cell = tableData.getCellValue(cellKey);
const cellValue = cell !== undefined ? tableData.format.getText(cell) : undefined;
rowCellsValues.push(cellValue ?? '');
rowCellsValues.push(getCellCopyValue(tableData, cellKey));
} else {
rowCellsValues.push('');
}
@@ -58,7 +62,7 @@ function copyGridSelectedDataToClipboard(
rowsValues.push(rowCellsValues.join('\t'));
}
copyToClipboard(rowsValues.join('\r\n'));
return rowsValues.join('\r\n');
}
// needed for event.code
@@ -66,16 +70,28 @@ type IKeyboardEvent = React.KeyboardEvent<HTMLDivElement> & KeyboardEvent;
export function useGridSelectedCellsCopy(
tableData: ITableData,
resultSetSelectAction: ResultSetSelectAction,
selectionContext: IDataGridSelectionContext
) {
const props = useObjectRef({ tableData, selectionContext });
const props = useObjectRef({ tableData, selectionContext, resultSetSelectAction });
const onKeydownHandler = useCallback((event: IKeyboardEvent) => {
if ((event.ctrlKey || event.metaKey) && event.code === EVENT_KEY_CODE.C) {
copyGridSelectedDataToClipboard(
props.tableData,
props.selectionContext.selectedCells
);
const focusedElement = props.resultSetSelectAction.getFocusedElement();
let value: string | null = null;
if (Array.from(props.selectionContext.selectedCells.keys()).length > 0) {
value = getSelectedCellsValue(
props.tableData,
props.selectionContext.selectedCells
);
} else if (focusedElement) {
value = getCellCopyValue(tableData, focusedElement);
}
if (value !== null) {
copyToClipboard(value);
}
}
}, []);
@@ -40,9 +40,9 @@ export function useTableData(
const editor = model.source.getAction(resultIndex, ResultSetEditAction);
const view = model.source.getAction(resultIndex, ResultSetViewAction);
return useObservableRef<ITableData>(() => ({
return useObservableRef<ITableData & { gridDIVElement: React.RefObject<HTMLDivElement | null> }>(() => ({
get gridDiv(): HTMLDivElement | null {
return gridDIVElement.current;
return this.gridDIVElement.current;
},
get columnKeys(): IResultSetColumnKey[] {
return this.view.columnKeys;
@@ -160,10 +160,12 @@ export function useTableData(
data: observable.ref,
editor: observable.ref,
view: observable.ref,
gridDIVElement: observable.ref,
}, {
format,
data,
editor,
view,
gridDIVElement,
});
}
@@ -149,6 +149,13 @@ export class ContainerDataSource extends DatabaseDataSource<IDataContainerOption
const response = await this.graphQLService.sdk.updateResultsDataBatch(updateVariables);
this.requestInfo = {
...this.requestInfo,
requestDuration: response.result.duration,
requestMessage: 'Saved successfully',
source: null,
};
if (editor) {
const responseResult = this.transformResults(executionContextInfo, response.result.results, 0)
.find(newResult => newResult.id === result.id);
@@ -156,13 +163,6 @@ export class ContainerDataSource extends DatabaseDataSource<IDataContainerOption
if (responseResult) {
editor.applyUpdate(responseResult);
}
this.requestInfo = {
...this.requestInfo,
requestDuration: response.result.duration,
requestMessage: 'Saved successfully',
source: null,
};
}
}
this.clearError();
@@ -6,14 +6,14 @@
* you may not use this file except in compliance with the License.
*/
import { Executor, IExecutor } from '@cloudbeaver/core-executor';
import { ISyncExecutor, SyncExecutor } from '@cloudbeaver/core-executor';
import type { ResultDataFormat } from '@cloudbeaver/core-sdk';
import { DatabaseDataAction } from '../DatabaseDataAction';
import type { IDatabaseDataResult } from '../IDatabaseDataResult';
import type { IDatabaseDataSource } from '../IDatabaseDataSource';
import { databaseDataAction } from './DatabaseDataActionDecorator';
import type { DatabaseEditChangeType, IDatabaseDataEditAction, IDatabaseDataEditActionData } from './IDatabaseDataEditAction';
import type { DatabaseEditChangeType, IDatabaseDataEditAction, IDatabaseDataEditActionData, IDatabaseDataEditApplyActionData } from './IDatabaseDataEditAction';
@databaseDataAction()
export abstract class DatabaseEditAction<TKey, TValue, TResult extends IDatabaseDataResult>
@@ -21,12 +21,14 @@ export abstract class DatabaseEditAction<TKey, TValue, TResult extends IDatabase
implements IDatabaseDataEditAction<TKey, TValue, TResult> {
static dataFormat: ResultDataFormat | null = null;
readonly action: IExecutor<IDatabaseDataEditActionData<TKey, TValue>>;
readonly action: ISyncExecutor<IDatabaseDataEditActionData<TKey, TValue>>;
readonly applyAction: ISyncExecutor<IDatabaseDataEditApplyActionData<any>>;
protected features: Array<keyof this>;
constructor(source: IDatabaseDataSource<any, TResult>, result: TResult) {
super(source, result);
this.action = new Executor();
this.action = new SyncExecutor();
this.applyAction = new SyncExecutor();
this.features = [];
}
@@ -6,7 +6,7 @@
* you may not use this file except in compliance with the License.
*/
import { Executor, IExecutor } from '@cloudbeaver/core-executor';
import { ISyncExecutor, SyncExecutor } from '@cloudbeaver/core-executor';
import type { ResultDataFormat } from '@cloudbeaver/core-sdk';
import { DatabaseDataAction } from '../DatabaseDataAction';
@@ -20,11 +20,11 @@ export abstract class DatabaseSelectAction<TKey, TResult extends IDatabaseDataRe
extends DatabaseDataAction<any, TResult>
implements IDatabaseDataSelectAction<TKey, TResult> {
static dataFormat: ResultDataFormat | null = null;
readonly actions: IExecutor<DatabaseDataSelectActionsData<TKey>>;
readonly actions: ISyncExecutor<DatabaseDataSelectActionsData<TKey>>;
constructor(source: IDatabaseDataSource<any, TResult>, result: TResult) {
super(source, result);
this.actions = new Executor();
this.actions = new SyncExecutor();
}
abstract isSelected(): boolean;
@@ -6,7 +6,7 @@
* you may not use this file except in compliance with the License.
*/
import type { IExecutor } from '@cloudbeaver/core-executor';
import type { ISyncExecutor } from '@cloudbeaver/core-executor';
import type { IDatabaseDataAction } from '../IDatabaseDataAction';
import type { IDatabaseDataResult } from '../IDatabaseDataResult';
@@ -25,6 +25,17 @@ export interface IDatabaseDataEditActionValue<TKey, TValue> {
prevValue?: TValue;
}
export interface IDatabaseDataEditApplyActionUpdate<TKey> {
type?: DatabaseEditChangeType;
row: TKey;
newRow: TKey;
}
export interface IDatabaseDataEditApplyActionData<TKey> {
resultId: string | null;
updates: Array<IDatabaseDataEditApplyActionUpdate<TKey>>;
}
export interface IDatabaseDataEditActionData<TKey, TValue> {
revert: boolean;
type?: DatabaseEditChangeType;
@@ -34,7 +45,8 @@ export interface IDatabaseDataEditActionData<TKey, TValue> {
export interface IDatabaseDataEditAction<TKey, TValue, TResult extends IDatabaseDataResult>
extends IDatabaseDataAction<any, TResult> {
readonly action: IExecutor<IDatabaseDataEditActionData<TKey, TValue>>;
readonly action: ISyncExecutor<IDatabaseDataEditActionData<TKey, TValue>>;
readonly applyAction: ISyncExecutor<IDatabaseDataEditApplyActionData<any>>;
isEdited: () => boolean;
isElementEdited: (key: TKey) => boolean;
hasFeature: (feature: keyof this) => boolean;
@@ -6,7 +6,7 @@
* you may not use this file except in compliance with the License.
*/
import type { IExecutor } from '@cloudbeaver/core-executor';
import type { ISyncExecutor } from '@cloudbeaver/core-executor';
import type { IDatabaseDataAction } from '../IDatabaseDataAction';
import type { IDatabaseDataResult } from '../IDatabaseDataResult';
@@ -27,7 +27,7 @@ export type DatabaseDataSelectActionsData<TKey> = {
export interface IDatabaseDataSelectAction<TKey, TResult extends IDatabaseDataResult>
extends IDatabaseDataAction<any, TResult> {
readonly actions: IExecutor<DatabaseDataSelectActionsData<TKey>>;
readonly actions: ISyncExecutor<DatabaseDataSelectActionsData<TKey>>;
isSelected: () => boolean;
isElementSelected: (key: TKey) => boolean;
getFocusedElement: () => TKey | null;
@@ -52,16 +52,25 @@ export class ResultSetDataAction extends DatabaseDataAction<any, IDatabaseResult
};
}
insertRow(row: IResultSetRowKey, value: IResultSetValue[], shift = 0): void {
insertRow(row: IResultSetRowKey, value: IResultSetValue[], shift = 0): IResultSetRowKey | undefined {
if (this.result.data?.rows) {
this.result.data.rows.splice(row.index + shift, 0, value);
const index = row.index + shift;
this.result.data.rows.splice(index, 0, value);
return { index };
}
return undefined;
}
removeRow(row: IResultSetRowKey, shift = 0): void {
removeRow(row: IResultSetRowKey, shift = 0): IResultSetRowKey | undefined {
if (this.result.data?.rows) {
this.result.data.rows.splice(row.index + shift, 1);
const index = row.index + shift;
this.result.data.rows.splice(index, 1);
return { index: index - 1 };
}
return undefined;
}
setRowValue(row: IResultSetRowKey, value: IResultSetValue[], shift = 0): void {
@@ -8,6 +8,7 @@
import { action, computed, makeObservable, observable } from 'mobx';
import { ISyncExecutor, SyncExecutor } from '@cloudbeaver/core-executor';
import { ResultDataFormat, SqlResultRow, UpdateResultsDataBatchMutationVariables } from '@cloudbeaver/core-sdk';
import { uuid } from '@cloudbeaver/core-utils';
@@ -15,7 +16,7 @@ import type { IDatabaseDataSource } from '../../IDatabaseDataSource';
import type { IDatabaseResultSet } from '../../IDatabaseResultSet';
import { databaseDataAction } from '../DatabaseDataActionDecorator';
import { DatabaseEditAction } from '../DatabaseEditAction';
import { DatabaseEditChangeType, IDatabaseDataEditActionData, IDatabaseDataEditActionValue } from '../IDatabaseDataEditAction';
import { DatabaseEditChangeType, IDatabaseDataEditActionData, IDatabaseDataEditActionValue, IDatabaseDataEditApplyActionData, IDatabaseDataEditApplyActionUpdate } from '../IDatabaseDataEditAction';
import type { IResultSetColumnKey, IResultSetElementKey, IResultSetRowKey } from './IResultSetDataKey';
import { isResultSetContentValue } from './isResultSetContentValue';
import { ResultSetDataAction } from './ResultSetDataAction';
@@ -36,6 +37,7 @@ export class ResultSetEditAction
extends DatabaseEditAction<IResultSetElementKey, IResultSetValue, IDatabaseResultSet> {
static dataFormat = ResultDataFormat.Resultset;
readonly applyAction: ISyncExecutor<IDatabaseDataEditApplyActionData<IResultSetRowKey>>;
private editorData: Map<string, IResultSetUpdate>;
private data: ResultSetDataAction;
@@ -45,6 +47,7 @@ export class ResultSetEditAction
data: ResultSetDataAction
) {
super(source, result);
this.applyAction = new SyncExecutor();
this.editorData = new Map();
this.data = data;
this.features = ['add', 'delete'];
@@ -286,6 +289,7 @@ export class ResultSetEditAction
}
applyUpdate(result: IDatabaseResultSet): void {
const applyUpdate: Array<IDatabaseDataEditApplyActionUpdate<IResultSetRowKey>> = [];
let rowIndex = 0;
let addShift = 0;
let deleteShift = 0;
@@ -303,6 +307,11 @@ export class ResultSetEditAction
if (value !== undefined) {
this.data.setRowValue(update.row, value);
applyUpdate.push({
type: DatabaseEditChangeType.update,
row: update.row,
newRow: update.row,
});
}
rowIndex++;
@@ -313,7 +322,15 @@ export class ResultSetEditAction
const value = result.data?.rows?.[rowIndex];
if (value !== undefined) {
this.data.insertRow(update.row, value, addShift);
const newRow = this.data.insertRow(update.row, value, addShift);
if (newRow) {
applyUpdate.push({
type: DatabaseEditChangeType.add,
row: update.row,
newRow,
});
}
}
insertedRows.push(update.row);
@@ -324,12 +341,29 @@ export class ResultSetEditAction
case DatabaseEditChangeType.delete: {
const insertShift = insertedRows.filter(row => row.index < update.row.index).length;
this.data.removeRow(update.row, deleteShift + insertShift);
const newRow = this.data.removeRow(update.row, deleteShift + insertShift);
if (newRow) {
applyUpdate.push({
type: DatabaseEditChangeType.delete,
row: update.row,
newRow,
});
}
deleteShift--;
break;
}
}
}
if (applyUpdate.length > 0) {
this.applyAction.execute({
resultId: result.id,
updates: applyUpdate,
});
}
this.clear();
}
@@ -8,16 +8,17 @@
import { action, computed, IReactionDisposer, makeObservable, observable, reaction } from 'mobx';
import { Executor, IExecutor } from '@cloudbeaver/core-executor';
import { ISyncExecutor, SyncExecutor } from '@cloudbeaver/core-executor';
import { ResultDataFormat } from '@cloudbeaver/core-sdk';
import type { IDatabaseDataSource } from '../../IDatabaseDataSource';
import type { IDatabaseResultSet } from '../../IDatabaseResultSet';
import { databaseDataAction } from '../DatabaseDataActionDecorator';
import { DatabaseSelectAction } from '../DatabaseSelectAction';
import { DatabaseEditChangeType, IDatabaseDataEditActionData } from '../IDatabaseDataEditAction';
import { DatabaseEditChangeType, IDatabaseDataEditActionData, IDatabaseDataEditApplyActionData } from '../IDatabaseDataEditAction';
import type { DatabaseDataSelectActionsData } from '../IDatabaseDataSelectAction';
import type { IResultSetColumnKey, IResultSetElementKey, IResultSetPartialKey, IResultSetRowKey } from './IResultSetDataKey';
import { ResultSetDataAction } from './ResultSetDataAction';
import { ResultSetDataKeysUtils } from './ResultSetDataKeysUtils';
import { ResultSetEditAction } from './ResultSetEditAction';
import type { IResultSetValue } from './ResultSetFormatAction';
@@ -31,24 +32,27 @@ export class ResultSetSelectAction extends DatabaseSelectAction<any, IDatabaseRe
return Array.from(this.selectedElements.values()).flat();
}
readonly actions: IExecutor<DatabaseDataSelectActionsData<IResultSetPartialKey>>;
readonly actions: ISyncExecutor<DatabaseDataSelectActionsData<IResultSetPartialKey>>;
readonly selectedElements: Map<string, IResultSetElementKey[]>;
private focusedElement: IResultSetElementKey | null;
private view: ResultSetViewAction;
private edit: ResultSetEditAction;
private data: ResultSetDataAction;
private validationDisposer: IReactionDisposer;
constructor(
source: IDatabaseDataSource<any, IDatabaseResultSet>,
result: IDatabaseResultSet,
view: ResultSetViewAction,
edit: ResultSetEditAction
edit: ResultSetEditAction,
data: ResultSetDataAction
) {
super(source, result);
this.view = view;
this.edit = edit;
this.actions = new Executor();
this.data = data;
this.actions = new SyncExecutor();
this.selectedElements = new Map();
this.focusedElement = null;
@@ -64,8 +68,14 @@ export class ResultSetSelectAction extends DatabaseSelectAction<any, IDatabaseRe
this.validationDisposer = reaction(() => this.view.rowKeys, (current, previous) => {
if (this.focusedElement) {
const focus = this.focusedElement;
const currentIndex = current.findIndex(key => ResultSetDataKeysUtils.isEqual(key, focus.row));
const focusIndex = previous.findIndex(key => ResultSetDataKeysUtils.isEqual(key, focus.row));
if (currentIndex >= 0 && focusIndex === -1) {
return;
}
if (focusIndex === -1 || current.length === 0) {
this.focus(null);
return;
@@ -97,6 +107,7 @@ export class ResultSetSelectAction extends DatabaseSelectAction<any, IDatabaseRe
});
this.edit.action.addHandler(this.syncFocus.bind(this));
this.edit.applyAction.addHandler(this.syncFocusOnUpdate.bind(this));
}
isSelected(): boolean {
@@ -238,7 +249,7 @@ export class ResultSetSelectAction extends DatabaseSelectAction<any, IDatabaseRe
});
}
updateResult(): void {
afterResultUpdate(): void {
this.validateSelection();
}
@@ -270,6 +281,32 @@ export class ResultSetSelectAction extends DatabaseSelectAction<any, IDatabaseRe
}
}
private syncFocusOnUpdate(data: IDatabaseDataEditApplyActionData<IResultSetRowKey>) {
let nextFocus = {
...this.data.getDefaultKey(),
...this.focusedElement,
};
for (const update of data.updates) {
switch (update.type) {
case DatabaseEditChangeType.add:
if (nextFocus === null || ResultSetDataKeysUtils.isEqual(update.row, nextFocus.row)) {
nextFocus = { ...nextFocus, row: update.newRow };
}
break;
case DatabaseEditChangeType.delete:
if (nextFocus === null || ResultSetDataKeysUtils.isEqual(update.row, nextFocus.row)) {
nextFocus = { ...nextFocus, row: update.newRow };
}
this.set({ row: update.row }, false, true);
break;
}
}
this.focus(nextFocus);
}
private syncFocus(data: IDatabaseDataEditActionData<IResultSetElementKey, IResultSetValue>) {
switch (data.type) {
case DatabaseEditChangeType.add:
@@ -73,7 +73,7 @@ export class ResultSetViewAction extends DatabaseDataAction<any, IDatabaseResult
return false;
}
return !this.hasRow(cell.row);
return this.hasRow(cell.row);
}
hasRow(key: IResultSetRowKey): boolean {
@@ -35,6 +35,8 @@ implements IDatabaseDataAction<TOptions, TResult> {
this.result = result;
}
afterResultUpdate(): void { }
tryGetAction<T extends IDatabaseDataAction<TOptions, TResult>>(
action: IDatabaseDataActionClass<TOptions, TResult, T>
): T | undefined {
@@ -87,7 +87,7 @@ implements IDatabaseDataActions<TOptions, TResult> {
}
updateResults(results: TResult[]): void {
const actionsMap = Array.from(this.actions.entries());
let actionsMap = Array.from(this.actions.entries());
for (const [key, actions] of actionsMap) {
const result = results.find(result => result.uniqueResultId === key);
@@ -103,6 +103,14 @@ implements IDatabaseDataActions<TOptions, TResult> {
}
}
}
actionsMap = Array.from(this.actions.entries());
for (const [, actions] of actionsMap) {
for (const action of actions) {
action.afterResultUpdate();
}
}
}
private addActionToList(
@@ -18,7 +18,7 @@ import type { IDatabaseDataResult } from './IDatabaseDataResult';
import { DatabaseDataAccessMode, IDatabaseDataSource, IRequestInfo } from './IDatabaseDataSource';
export abstract class DatabaseDataSource<TOptions, TResult extends IDatabaseDataResult>
implements IDatabaseDataSource<TOptions, TResult> {
implements IDatabaseDataSource<TOptions, TResult> {
access: DatabaseDataAccessMode;
dataFormat: ResultDataFormat;
supportedDataFormats: ResultDataFormat[];
@@ -162,8 +162,8 @@ export abstract class DatabaseDataSource<TOptions, TResult extends IDatabaseData
}
setResults(results: TResult[]): this {
this.actions.updateResults(results);
this.results = results;
this.actions.updateResults(results);
return this;
}
@@ -54,6 +54,7 @@ export interface IDatabaseDataAction<TOptions, TResult extends IDatabaseDataResu
result: TResult;
resultIndex: number;
updateResult: (result: TResult) => void;
afterResultUpdate: () => void;
tryGetAction: <T extends IDatabaseDataAction<TOptions, TResult>>(
action: IDatabaseDataActionClass<TOptions, TResult, T>
) => T | undefined;
@@ -96,6 +96,13 @@ export class QueryDataSource extends DatabaseDataSource<IDataQueryOptions, IData
const response = await this.graphQLService.sdk.updateResultsDataBatch(updateVariables);
this.requestInfo = {
...this.requestInfo,
requestDuration: response.result.duration,
requestMessage: 'Saved successfully',
source: this.options.query,
};
if (editor) {
const responseResult = this.transformResults(executionContextInfo, response.result.results, 0)
.find(newResult => newResult.id === result.id);
@@ -103,13 +110,6 @@ export class QueryDataSource extends DatabaseDataSource<IDataQueryOptions, IData
if (responseResult) {
editor.applyUpdate(responseResult);
}
this.requestInfo = {
...this.requestInfo,
requestDuration: response.result.duration,
requestMessage: 'Saved successfully',
source: this.options.query,
};
}
}
this.clearError();