From d4b5296aa0fada5a8fb554a3bd360547829f49c1 Mon Sep 17 00:00:00 2001 From: sergeyteleshev Date: Wed, 10 Apr 2024 17:58:28 +0200 Subject: [PATCH 01/36] CB-4270 adds cancel option for load total count of rows in table --- .../DatabaseDataModel/DatabaseDataSource.ts | 1 + .../DatabaseDataModel/IDatabaseDataSource.ts | 1 + .../src/ResultSetDataSource.ts | 60 +++++++++++++++---- 3 files changed, 50 insertions(+), 12 deletions(-) diff --git a/webapp/packages/plugin-data-viewer/src/DatabaseDataModel/DatabaseDataSource.ts b/webapp/packages/plugin-data-viewer/src/DatabaseDataModel/DatabaseDataSource.ts index 07629988be..9a54f18f9c 100644 --- a/webapp/packages/plugin-data-viewer/src/DatabaseDataModel/DatabaseDataSource.ts +++ b/webapp/packages/plugin-data-viewer/src/DatabaseDataModel/DatabaseDataSource.ts @@ -374,6 +374,7 @@ export abstract class DatabaseDataSource; abstract loadTotalCount(resultIndex: number): Promise; + abstract cancelLoadTotalCount(resultIndex: number): Promise; async requestDataAction(): Promise { this.prevOptions = toJS(this.options); diff --git a/webapp/packages/plugin-data-viewer/src/DatabaseDataModel/IDatabaseDataSource.ts b/webapp/packages/plugin-data-viewer/src/DatabaseDataModel/IDatabaseDataSource.ts index bf6745f95f..07f70db247 100644 --- a/webapp/packages/plugin-data-viewer/src/DatabaseDataModel/IDatabaseDataSource.ts +++ b/webapp/packages/plugin-data-viewer/src/DatabaseDataModel/IDatabaseDataSource.ts @@ -83,6 +83,7 @@ export interface IDatabaseDataSource this; setTotalCount: (resultIndex: number, count: number) => this; loadTotalCount: (resultIndex: number) => Promise; + cancelLoadTotalCount: (resultIndex: number) => Promise; retry: () => Promise; /** Allows to perform an asynchronous action on the data source, this action will wait previous action to finish and save or load requests. diff --git a/webapp/packages/plugin-data-viewer/src/ResultSetDataSource.ts b/webapp/packages/plugin-data-viewer/src/ResultSetDataSource.ts index be89670a59..9c5859d842 100644 --- a/webapp/packages/plugin-data-viewer/src/ResultSetDataSource.ts +++ b/webapp/packages/plugin-data-viewer/src/ResultSetDataSource.ts @@ -5,19 +5,42 @@ * Licensed under the Apache License, Version 2.0. * you may not use this file except in compliance with the License. */ +import { makeObservable, observable } from 'mobx'; + import type { IServiceInjector } from '@cloudbeaver/core-di'; -import type { AsyncTaskInfoService, GraphQLService } from '@cloudbeaver/core-sdk'; +import type { AsyncTask, AsyncTaskInfoService, GraphQLService } from '@cloudbeaver/core-sdk'; import { DatabaseDataSource } from './DatabaseDataModel/DatabaseDataSource'; import type { IDatabaseResultSet } from './DatabaseDataModel/IDatabaseResultSet'; +interface ResultSetDataSourceState { + totalCountTasks: Map; // Map +} + export abstract class ResultSetDataSource extends DatabaseDataSource { + readonly totalCountTasks: Map; + constructor( readonly serviceInjector: IServiceInjector, protected graphQLService: GraphQLService, protected asyncTaskInfoService: AsyncTaskInfoService, ) { super(serviceInjector); + + this.totalCountTasks = new Map(); + + makeObservable(this, { + totalCountTasks: observable.shallow, + }); + } + + async cancelLoadTotalCount(resultIndex: number) { + const task = this.totalCountTasks.get(resultIndex); + + if (task && !task.cancelled) { + await this.asyncTaskInfoService.cancel(task.id); + this.totalCountTasks.delete(resultIndex); + } } async loadTotalCount(resultIndex: number) { @@ -45,16 +68,29 @@ export abstract class ResultSetDataSource extends DatabaseDataSource { - const info = await this.asyncTaskInfoService.run(task); - const { count } = await this.graphQLService.sdk.getSqlRowDataCountResult({ taskId: info.id }); - return count; - }, - () => this.asyncTaskInfoService.cancel(task.id), - () => this.asyncTaskInfoService.remove(task.id), - ); - - this.setTotalCount(resultIndex, count); + this.totalCountTasks.set(resultIndex, task); + + try { + const count = await executionContext.run( + async () => { + const info = await this.asyncTaskInfoService.run(task); + + if (!task.cancelled && !info.running) { + const { count } = await this.graphQLService.sdk.getSqlRowDataCountResult({ taskId: info.id }); + return count; + } + + return; + }, + () => this.asyncTaskInfoService.cancel(task.id), + () => this.asyncTaskInfoService.remove(task.id), + ); + + if (count !== undefined) { + this.setTotalCount(resultIndex, count); + } + } finally { + this.totalCountTasks.delete(resultIndex); + } } } From a6da7c5d3f3fc690443f65939438edd28c97277a Mon Sep 17 00:00:00 2001 From: sergeyteleshev Date: Thu, 11 Apr 2024 08:32:05 +0200 Subject: [PATCH 02/36] CB-4270 adds ui for load total count of rows in table --- .../src/ToolsPanel/ToolsAction.tsx | 19 ++++++++++++++++--- .../public/icons/data_cancel.svg | 10 ++++++++++ .../TableFooter/TableFooterRowCount.tsx | 19 +++++++++++++++++++ .../plugin-data-viewer/src/locales/en.ts | 8 ++++++++ .../plugin-data-viewer/src/locales/it.ts | 8 ++++++++ .../plugin-data-viewer/src/locales/ru.ts | 8 ++++++++ .../plugin-data-viewer/src/locales/zh.ts | 8 ++++++++ 7 files changed, 77 insertions(+), 3 deletions(-) create mode 100644 webapp/packages/plugin-data-viewer/public/icons/data_cancel.svg diff --git a/webapp/packages/core-blocks/src/ToolsPanel/ToolsAction.tsx b/webapp/packages/core-blocks/src/ToolsPanel/ToolsAction.tsx index 325e2a659b..a771005f9e 100644 --- a/webapp/packages/core-blocks/src/ToolsPanel/ToolsAction.tsx +++ b/webapp/packages/core-blocks/src/ToolsPanel/ToolsAction.tsx @@ -19,10 +19,23 @@ interface Props extends Omit, 'onClick'> { viewBox?: string; loading?: boolean; className?: string; + disableLoading?: boolean; + disableDisabled?: boolean; onClick?: (event: React.MouseEvent) => Promise | any; } -export const ToolsAction: React.FC = function ToolsAction({ icon, viewBox, disabled, loading, children, className, onClick, ...rest }) { +export const ToolsAction: React.FC = function ToolsAction({ + icon, + viewBox, + disabled, + loading, + children, + className, + onClick, + disableLoading = false, + disableDisabled = false, + ...rest +}) { const styles = useS(style); const [loadingState, setLoadingState] = useState(false); @@ -35,8 +48,8 @@ export const ToolsAction: React.FC = function ToolsAction({ icon, viewBox } } - loading = useStateDelay(loading || loadingState, 300); - disabled = disabled || loadingState; + loading = useStateDelay(!disableLoading && (loading || loadingState), 300); + disabled = !disableDisabled && (disabled || loadingState); return (