From ce81eb41f5a549eef15340448dc163b6f87f7c30 Mon Sep 17 00:00:00 2001 From: Wroud Date: Sun, 8 Nov 2020 22:44:18 +0300 Subject: [PATCH] fix(plugin-data-viewer): CB-407 multiple request while sorting --- .../src/AgGridTable/AgGridTableController.ts | 15 ++++++- .../TableColumnHeader/TableColumnHeader.tsx | 2 +- .../src/TableViewer/TableViewerModel.ts | 44 ++++++++++++++++--- 3 files changed, 54 insertions(+), 7 deletions(-) diff --git a/webapp/packages/plugin-data-spreadsheet/src/AgGridTable/AgGridTableController.ts b/webapp/packages/plugin-data-spreadsheet/src/AgGridTable/AgGridTableController.ts index b80ba754b8..a8478ba41b 100644 --- a/webapp/packages/plugin-data-spreadsheet/src/AgGridTable/AgGridTableController.ts +++ b/webapp/packages/plugin-data-spreadsheet/src/AgGridTable/AgGridTableController.ts @@ -63,6 +63,7 @@ export class AgGridTableController implements IInitializableController, IDestruc headerHeight: 28, rowModelType: 'infinite', infiniteInitialRowCount: 0, + maxConcurrentDatasourceRequests: 1, cacheBlockSize: undefined, // to be set during init phase datasource: this.datasource, @@ -216,7 +217,19 @@ export class AgGridTableController implements IInitializableController, IDestruc private handleSortChanged(event: SortChangedEvent) { const sortModel = event.api.getSortModel() as SortModel; - this.gridModel.onSortChanged(sortModel); + const newModel = this.gridModel.onSortChanged(sortModel); + + if (sortModel.length !== newModel.length) { + event.api.setSortModel(newModel); + } else { + for (let i = 0; i < sortModel.length; i++) { + if (sortModel[i].colId !== newModel[i].colId + || sortModel[i].sort !== newModel[i].sort) { + event.api.setSortModel(newModel); + return; + } + } + } } /* Actions */ diff --git a/webapp/packages/plugin-data-spreadsheet/src/AgGridTable/TableColumnHeader/TableColumnHeader.tsx b/webapp/packages/plugin-data-spreadsheet/src/AgGridTable/TableColumnHeader/TableColumnHeader.tsx index 4c62ba744e..e072738e1e 100644 --- a/webapp/packages/plugin-data-spreadsheet/src/AgGridTable/TableColumnHeader/TableColumnHeader.tsx +++ b/webapp/packages/plugin-data-spreadsheet/src/AgGridTable/TableColumnHeader/TableColumnHeader.tsx @@ -105,7 +105,7 @@ export function TableColumnHeader(props: HeaderProps) { return function cleanup() { props.column.removeEventListener('sortChanged', onSortChanged); }; - }); + }, [props.column]); const handleSort = useCallback( (e: React.MouseEvent) => { diff --git a/webapp/packages/plugin-data-viewer/src/TableViewer/TableViewerModel.ts b/webapp/packages/plugin-data-viewer/src/TableViewer/TableViewerModel.ts index 0186b4bd01..d33d33087b 100644 --- a/webapp/packages/plugin-data-viewer/src/TableViewer/TableViewerModel.ts +++ b/webapp/packages/plugin-data-viewer/src/TableViewer/TableViewerModel.ts @@ -133,6 +133,8 @@ export class TableViewerModel { private resetSubject: Subject; private chunkChangeSubject: Subject; + private updating = false; + private loading = false; @observable private _hasMoreRows = true; @observable private _isLoaderVisible = false; @@ -166,10 +168,18 @@ export class TableViewerModel { cancelFetch = (): void => { }; - refresh = async (): Promise => { + refresh = async (skipResetUpdate = false): Promise => { + if (!skipResetUpdate && this.isUpdateLocked()) { + return; + } + this.resetData(); - await this.onRequestData(0, this.getChunkSize()); - this.resetSubject.next(); + // if (skipDataLoad) { + // await this.onRequestData(0, this.getChunkSize()); + // } + if (!skipResetUpdate) { + this.resetSubject.next(); + } }; onShowDetails = (): void => { @@ -294,6 +304,7 @@ export class TableViewerModel { } this._isLoaderVisible = !this.noLoaderWhileRequestingDataAsync; + this.loading = true; try { const response = await this.requestDataAsync(this, rowOffset, count); @@ -314,6 +325,7 @@ export class TableViewerModel { this.showError(e); throw e; } finally { + this.loading = false; this._isLoaderVisible = false; } } @@ -326,12 +338,34 @@ export class TableViewerModel { this.tableEditor.editCellValue(rowNumber, column, value, editing); } - onSortChanged(sorting: SortModel): void { + onSortChanged(sorting: SortModel): SortModel { + if (this.isUpdateLocked()) { + return this.getSortModel(); + } + this.sortedColumns.clear(); for (const sort of sorting) { this.setColumnSorting(sort.colId, sort.sort === 'asc', true); } - this.refresh(); + this.refresh(true); + return sorting; + } + + getSortModel(): SortModel { + return Array.from(this.sortedColumns.values()).map(v => ({ + colId: v.attribute, + sort: v.orderAsc ? 'asc' : 'desc', + })); + } + + private isUpdateLocked(): boolean { + if (this.updating || this.loading) { + return true; + } + + this.updating = true; + setTimeout(() => { this.updating = false; }, 1000); + return false; } @action