From ffea761a5c6ef25b918f9b58f350aaa7554bb1dd Mon Sep 17 00:00:00 2001 From: Sychev Andrey Date: Wed, 20 May 2026 17:27:00 +0200 Subject: [PATCH 1/2] dbeaver/pro#8486 feat: add DataReadonlyReason API for data sources MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously TableStatusIndicator relied on model.isReadonly() which lost reasons. This caused the "Read-only connection" tooltip to show in grouping panel even on editable connections — the connection wasn't read-only, the presentation was. Each data source now declares its specific reason via getReadonlyReason(). UI maps the typed reason to an accurate message --- .../plugin-data-spreadsheet-new/package.json | 1 + .../TableStatusIndicator.tsx | 35 +++++++++++++++---- .../src/locales/de.ts | 1 + .../src/locales/en.ts | 1 + .../src/locales/fr.ts | 1 + .../src/locales/it.ts | 1 + .../src/locales/ru.ts | 1 + .../src/locales/vi.ts | 1 + .../src/locales/zh.ts | 1 + .../plugin-data-spreadsheet-new/tsconfig.json | 3 ++ .../src/GroupingDataSource.ts | 6 +++- .../DatabaseDataModel/DatabaseDataModel.ts | 6 +++- .../DatabaseDataModel/DatabaseDataSource.ts | 5 +++ .../DatabaseDataModel/IDatabaseDataModel.ts | 9 ++++- .../DatabaseDataModel/IDatabaseDataSource.ts | 7 ++++ .../src/ResultSet/ResultSetDataSource.ts | 16 ++++++--- webapp/yarn.lock | 1 + 17 files changed, 82 insertions(+), 14 deletions(-) diff --git a/webapp/packages/plugin-data-spreadsheet-new/package.json b/webapp/packages/plugin-data-spreadsheet-new/package.json index bca6cf863ac..2b1e55e2cd8 100644 --- a/webapp/packages/plugin-data-spreadsheet-new/package.json +++ b/webapp/packages/plugin-data-spreadsheet-new/package.json @@ -25,6 +25,7 @@ "dependencies": { "@cloudbeaver/core-blocks": "workspace:*", "@cloudbeaver/core-browser": "workspace:*", + "@cloudbeaver/core-connections": "workspace:*", "@cloudbeaver/core-data-context": "workspace:*", "@cloudbeaver/core-di": "workspace:*", "@cloudbeaver/core-dialogs": "workspace:*", diff --git a/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/TableColumnHeader/TableStatusIndicator.tsx b/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/TableColumnHeader/TableStatusIndicator.tsx index e4a5357cb86..32e4654ddc2 100644 --- a/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/TableColumnHeader/TableStatusIndicator.tsx +++ b/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/TableColumnHeader/TableStatusIndicator.tsx @@ -9,8 +9,9 @@ import { SqlRowIdentifierState, type SqlResultColumn } from '@cloudbeaver/core-s import { observer } from 'mobx-react-lite'; import { useContext } from 'react'; -import { IconOrImage, s, useS, useTranslate } from '@cloudbeaver/core-blocks'; -import { isResultSetDataSource } from '@cloudbeaver/plugin-data-viewer'; +import { IconOrImage, s, useResource, useS, useTranslate } from '@cloudbeaver/core-blocks'; +import { ConnectionInfoResource, createConnectionParam } from '@cloudbeaver/core-connections'; +import { DataReadonlyReason, isResultSetDataSource } from '@cloudbeaver/plugin-data-viewer'; import { DataGridContext } from '../DataGridContext.js'; import { TableDataContext } from '../TableDataContext.js'; @@ -20,16 +21,24 @@ import styles from './TableStatusIndicator.module.css'; export const TableStatusIndicator = observer(function TableStatusIndicator() { const dataGridContext = useContext(DataGridContext); const tableDataContext = useContext(TableDataContext); - const readOnlyConnection = dataGridContext.model.isReadonly(dataGridContext.resultIndex); const translate = useTranslate(); + + const source = dataGridContext.model.source; + const resultSetSource = isResultSetDataSource(source) ? source : null; + + // We intentionally do NOT use `model.isReadonly()` for this — that method aggregates several + // unrelated reasons and loses information about WHY editing isn't allowed. + const contextInfo = resultSetSource?.executionContext?.context; + const connectionKey = contextInfo ? createConnectionParam(contextInfo.projectId, contextInfo.connectionId) : null; + const connectionInfoLoader = useResource(TableStatusIndicator, ConnectionInfoResource, connectionKey); + const readOnlyConnection = connectionInfoLoader.data?.readOnly ?? false; + const readonlyReason = source.getReadonlyReason(dataGridContext.resultIndex); const style = useS(styles); if (!tableDataContext || !dataGridContext) { return null; } - const source = dataGridContext.model.source; - const resultSetSource = isResultSetDataSource(source) ? source : null; const rowIdentifierInfo = resultSetSource?.getRowIdentifierInfo(dataGridContext.resultIndex); const hasRowIdentifier = resultSetSource?.hasElementIdentifier(dataGridContext.resultIndex); @@ -43,7 +52,10 @@ export const TableStatusIndicator = observer(function TableStatusIndicator() { const isPrimaryKey = rowIdentifierInfo?.state === SqlRowIdentifierState.PrimaryKey; const tooltipParts: string[] = []; - if (readOnlyConnection) { + // Presentation-level read-only takes precedence over connection-level read-only. + if (readonlyReason === DataReadonlyReason.Presentation) { + tooltipParts.push(translate('data_grid_table_readonly_presentation_tooltip')); + } else if (readOnlyConnection) { tooltipParts.push(translate('data_grid_table_readonly_connection_tooltip')); } @@ -59,6 +71,15 @@ export const TableStatusIndicator = observer(function TableStatusIndicator() { tooltipParts.push(translate('data_grid_table_virtual_key_tooltip')); } + const showLockIcon = readOnlyConnection || readonlyReason === DataReadonlyReason.Presentation; + + // Hide the entire indicator when there's nothing meaningful to display (Session Manager) + const hasInfo = showLockIcon || !!readOnlyStatus || hasRowIdentifier || isVirtualKey || isPrimaryKey; + + if (!hasInfo) { + return null; + } + const tooltip = tooltipParts.join('\n'); return ( @@ -66,7 +87,7 @@ export const TableStatusIndicator = observer(function TableStatusIndicator() { title={tooltip} className="tw:absolute tw:top-1/2 tw:left-1 tw:-translate-y-1/2 tw:z-1 tw:pointer-events-auto tw:flex tw:items-center tw:gap-1 tw:cursor-help" > - {readOnlyConnection && } + {showLockIcon && }
{ this.setFeature(DatabaseDataFeature.Grouping); } + override getReadonlyReason(_resultIndex: number): DataReadonlyReason | null { + return DataReadonlyReason.Presentation; + } + protected override async executeQuery( executionContextInfo: IConnectionExecutionContextInfo, options: IDataGroupingOptions, diff --git a/webapp/packages/plugin-data-viewer/src/DatabaseDataModel/DatabaseDataModel.ts b/webapp/packages/plugin-data-viewer/src/DatabaseDataModel/DatabaseDataModel.ts index d3f4d5a0291..1296a4616ad 100644 --- a/webapp/packages/plugin-data-viewer/src/DatabaseDataModel/DatabaseDataModel.ts +++ b/webapp/packages/plugin-data-viewer/src/DatabaseDataModel/DatabaseDataModel.ts @@ -12,7 +12,7 @@ import type { ResultDataFormat } from '@cloudbeaver/core-sdk'; import { uuid } from '@cloudbeaver/core-utils'; import type { IDatabaseDataModel, IRequestEventData } from './IDatabaseDataModel.js'; -import type { DatabaseDataAccessMode, IDatabaseDataSource, IRequestInfo } from './IDatabaseDataSource.js'; +import type { DatabaseDataAccessMode, DataReadonlyReason, IDatabaseDataSource, IRequestInfo } from './IDatabaseDataSource.js'; export class DatabaseDataModel = IDatabaseDataSource> implements IDatabaseDataModel { id: string; @@ -59,6 +59,10 @@ export class DatabaseDataModel = I return this.source.isReadonly(resultIndex); } + getReadonlyReason(resultIndex: number): DataReadonlyReason | null { + return this.source.getReadonlyReason(resultIndex); + } + isDataAvailable(offset: number, count: number): boolean { return this.source.isDataAvailable(offset, count); } diff --git a/webapp/packages/plugin-data-viewer/src/DatabaseDataModel/DatabaseDataSource.ts b/webapp/packages/plugin-data-viewer/src/DatabaseDataModel/DatabaseDataSource.ts index 8c49420192f..a826d1cf382 100644 --- a/webapp/packages/plugin-data-viewer/src/DatabaseDataModel/DatabaseDataSource.ts +++ b/webapp/packages/plugin-data-viewer/src/DatabaseDataModel/DatabaseDataSource.ts @@ -18,6 +18,7 @@ import { DatabaseDataAccessMode, DatabaseDataFeature, DatabaseDataSourceOperation, + type DataReadonlyReason, IDatabaseDataSource, type IDatabaseDataSourceOperationEvent, type IRequestInfo, @@ -213,6 +214,10 @@ export abstract class DatabaseDataSource 1 || this.disabled; } + getReadonlyReason(resultIndex: number): DataReadonlyReason | null { + return null; + } + isLoading(): boolean { return !!this.activeOperation; } diff --git a/webapp/packages/plugin-data-viewer/src/DatabaseDataModel/IDatabaseDataModel.ts b/webapp/packages/plugin-data-viewer/src/DatabaseDataModel/IDatabaseDataModel.ts index 4179acb7920..92050b31a26 100644 --- a/webapp/packages/plugin-data-viewer/src/DatabaseDataModel/IDatabaseDataModel.ts +++ b/webapp/packages/plugin-data-viewer/src/DatabaseDataModel/IDatabaseDataModel.ts @@ -8,7 +8,13 @@ import type { IExecutor } from '@cloudbeaver/core-executor'; import type { ResultDataFormat } from '@cloudbeaver/core-sdk'; -import type { DatabaseDataAccessMode, IDatabaseDataSource, IDatabaseDataSourceOperationEvent, IRequestInfo } from './IDatabaseDataSource.js'; +import type { + DatabaseDataAccessMode, + DataReadonlyReason, + IDatabaseDataSource, + IDatabaseDataSourceOperationEvent, + IRequestInfo, +} from './IDatabaseDataSource.js'; export interface IRequestEventData = IDatabaseDataSource> extends IDatabaseDataSourceOperationEvent { model: IDatabaseDataModel; @@ -31,6 +37,7 @@ export interface IDatabaseDataModel this; isReadonly: (resultIndex: number) => boolean; + getReadonlyReason: (resultIndex: number) => DataReadonlyReason | null; isDisabled: (resultIndex?: number) => boolean; isLoading: () => boolean; isDataAvailable: (offset: number, count: number) => boolean; diff --git a/webapp/packages/plugin-data-viewer/src/DatabaseDataModel/IDatabaseDataSource.ts b/webapp/packages/plugin-data-viewer/src/DatabaseDataModel/IDatabaseDataSource.ts index 0e9366d0186..337033926f1 100644 --- a/webapp/packages/plugin-data-viewer/src/DatabaseDataModel/IDatabaseDataSource.ts +++ b/webapp/packages/plugin-data-viewer/src/DatabaseDataModel/IDatabaseDataSource.ts @@ -43,6 +43,12 @@ export enum DatabaseDataAccessMode { Default, Readonly, } +export enum DataReadonlyReason { + /** The data source does not support editing (grouping panel). */ + Presentation = 'presentation', + /** The result data itself is marked read-only by the server (computed columns, missing row identifier). */ + Result = 'result', +} /** * Feature flags for database data sources. @@ -94,6 +100,7 @@ export interface IDatabaseDataSource boolean; isLoadable: () => boolean; isReadonly: (resultIndex: number) => boolean; + getReadonlyReason: (resultIndex: number) => DataReadonlyReason | null; isDataAvailable: (offset: number, count: number) => boolean; isLoading: () => boolean; isDisabled: (resultIndex?: number) => boolean; diff --git a/webapp/packages/plugin-data-viewer/src/ResultSet/ResultSetDataSource.ts b/webapp/packages/plugin-data-viewer/src/ResultSet/ResultSetDataSource.ts index d78b52961c0..0a4622a3419 100644 --- a/webapp/packages/plugin-data-viewer/src/ResultSet/ResultSetDataSource.ts +++ b/webapp/packages/plugin-data-viewer/src/ResultSet/ResultSetDataSource.ts @@ -36,16 +36,17 @@ import { ResultSetFormatAction } from '../DatabaseDataModel/Actions/ResultSet/Re import { ResultSetSelectAction } from '../DatabaseDataModel/Actions/ResultSet/ResultSetSelectAction.js'; import { ResultSetViewAction } from '../DatabaseDataModel/Actions/ResultSet/ResultSetViewAction.js'; import { IDatabaseDataSelectAction } from '../DatabaseDataModel/Actions/IDatabaseDataSelectAction.js'; -import { DatabaseDataFeature } from '../DatabaseDataModel/IDatabaseDataSource.js'; +import { DatabaseDataFeature, DataReadonlyReason } from '../DatabaseDataModel/IDatabaseDataSource.js'; export interface IRowIdentifierInfo { state: SqlRowIdentifierState | null; identifier: SqlRowIdentifier | null; } -export abstract class ResultSetDataSource - extends DatabaseDataSource -{ +export abstract class ResultSetDataSource extends DatabaseDataSource< + TOptions, + IDatabaseResultSet +> { executionContext: IConnectionExecutionContext | null; totalCountRequestTask: ITask | null; private keepExecutionContextOnDispose: boolean; @@ -90,6 +91,13 @@ export abstract class ResultSetDataSource { await super.cancel(); await this.cancelLoadTotalCount(); diff --git a/webapp/yarn.lock b/webapp/yarn.lock index ea9b67f8390..42de34c336d 100644 --- a/webapp/yarn.lock +++ b/webapp/yarn.lock @@ -2956,6 +2956,7 @@ __metadata: "@cloudbeaver/core-blocks": "workspace:*" "@cloudbeaver/core-browser": "workspace:*" "@cloudbeaver/core-cli": "workspace:*" + "@cloudbeaver/core-connections": "workspace:*" "@cloudbeaver/core-data-context": "workspace:*" "@cloudbeaver/core-di": "workspace:*" "@cloudbeaver/core-dialogs": "workspace:*" From 9cfec7ec8e584a7a7d4046f4ccce23b770d1fefb Mon Sep 17 00:00:00 2001 From: Sychev Andrey Date: Fri, 22 May 2026 17:06:39 +0200 Subject: [PATCH 2/2] dbeaver/pro#8486 refactor: remove DataReadonlyReason references and use hasFeature flag --- .../TableColumnHeader/TableStatusIndicator.tsx | 15 +++++++++------ .../plugin-data-spreadsheet-new/src/locales/en.ts | 2 +- .../src/GroupingDataSource.ts | 6 +----- .../src/DatabaseDataModel/DatabaseDataModel.ts | 6 +----- .../src/DatabaseDataModel/DatabaseDataSource.ts | 5 ----- .../src/DatabaseDataModel/IDatabaseDataModel.ts | 9 +-------- .../src/DatabaseDataModel/IDatabaseDataSource.ts | 7 ------- .../src/ResultSet/ResultSetDataSource.ts | 9 +-------- 8 files changed, 14 insertions(+), 45 deletions(-) diff --git a/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/TableColumnHeader/TableStatusIndicator.tsx b/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/TableColumnHeader/TableStatusIndicator.tsx index 32e4654ddc2..9422a9db0bf 100644 --- a/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/TableColumnHeader/TableStatusIndicator.tsx +++ b/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/TableColumnHeader/TableStatusIndicator.tsx @@ -11,7 +11,7 @@ import { useContext } from 'react'; import { IconOrImage, s, useResource, useS, useTranslate } from '@cloudbeaver/core-blocks'; import { ConnectionInfoResource, createConnectionParam } from '@cloudbeaver/core-connections'; -import { DataReadonlyReason, isResultSetDataSource } from '@cloudbeaver/plugin-data-viewer'; +import { DatabaseDataFeature, isResultSetDataSource } from '@cloudbeaver/plugin-data-viewer'; import { DataGridContext } from '../DataGridContext.js'; import { TableDataContext } from '../TableDataContext.js'; @@ -26,13 +26,16 @@ export const TableStatusIndicator = observer(function TableStatusIndicator() { const source = dataGridContext.model.source; const resultSetSource = isResultSetDataSource(source) ? source : null; - // We intentionally do NOT use `model.isReadonly()` for this — that method aggregates several - // unrelated reasons and loses information about WHY editing isn't allowed. + /* We do NOT use `model.isReadonly()` here — + that method aggregates several unrelated reasons + and loses information about WHY editing isn't allowed. */ const contextInfo = resultSetSource?.executionContext?.context; const connectionKey = contextInfo ? createConnectionParam(contextInfo.projectId, contextInfo.connectionId) : null; const connectionInfoLoader = useResource(TableStatusIndicator, ConnectionInfoResource, connectionKey); const readOnlyConnection = connectionInfoLoader.data?.readOnly ?? false; - const readonlyReason = source.getReadonlyReason(dataGridContext.resultIndex); + + const readOnlyPresentation = source.hasFeature(DatabaseDataFeature.Grouping); + const style = useS(styles); if (!tableDataContext || !dataGridContext) { @@ -53,7 +56,7 @@ export const TableStatusIndicator = observer(function TableStatusIndicator() { const tooltipParts: string[] = []; // Presentation-level read-only takes precedence over connection-level read-only. - if (readonlyReason === DataReadonlyReason.Presentation) { + if (readOnlyPresentation) { tooltipParts.push(translate('data_grid_table_readonly_presentation_tooltip')); } else if (readOnlyConnection) { tooltipParts.push(translate('data_grid_table_readonly_connection_tooltip')); @@ -71,7 +74,7 @@ export const TableStatusIndicator = observer(function TableStatusIndicator() { tooltipParts.push(translate('data_grid_table_virtual_key_tooltip')); } - const showLockIcon = readOnlyConnection || readonlyReason === DataReadonlyReason.Presentation; + const showLockIcon = readOnlyConnection || readOnlyPresentation; // Hide the entire indicator when there's nothing meaningful to display (Session Manager) const hasInfo = showLockIcon || !!readOnlyStatus || hasRowIdentifier || isVirtualKey || isPrimaryKey; diff --git a/webapp/packages/plugin-data-spreadsheet-new/src/locales/en.ts b/webapp/packages/plugin-data-spreadsheet-new/src/locales/en.ts index ca9e11267c1..5e5c844ec22 100644 --- a/webapp/packages/plugin-data-spreadsheet-new/src/locales/en.ts +++ b/webapp/packages/plugin-data-spreadsheet-new/src/locales/en.ts @@ -31,7 +31,7 @@ export default [ ['data_grid_table_context_menu_save_value_error', 'Failed to save value'], ['data_grid_table_index_column_tooltip', 'Select whole table'], ['data_grid_table_readonly_connection_tooltip', 'Read-only connection'], - ['data_grid_table_readonly_presentation_tooltip', 'Active presentation does not support data editing'], + ['data_grid_table_readonly_presentation_tooltip', 'Read-only: Active presentation does not support data editing'], ['data_grid_table_no_key_found_tooltip', 'No unique key was found. Data modification is not possible.'], ['data_grid_table_virtual_key_tooltip', 'Virtual key'], ['data_grid_table_key_column_tooltip', 'Key column'], diff --git a/webapp/packages/plugin-data-viewer-result-set-grouping/src/GroupingDataSource.ts b/webapp/packages/plugin-data-viewer-result-set-grouping/src/GroupingDataSource.ts index 3b4fe503998..f784e61afa3 100644 --- a/webapp/packages/plugin-data-viewer-result-set-grouping/src/GroupingDataSource.ts +++ b/webapp/packages/plugin-data-viewer-result-set-grouping/src/GroupingDataSource.ts @@ -10,7 +10,7 @@ import type { IServiceProvider } from '@cloudbeaver/core-di'; import { CommonDialogService } from '@cloudbeaver/core-dialogs'; import { AsyncTaskInfoEventHandler, AsyncTaskInfoService } from '@cloudbeaver/core-root'; import { type AsyncTaskInfo, GraphQLService } from '@cloudbeaver/core-sdk'; -import { DatabaseDataFeature, DataReadonlyReason } from '@cloudbeaver/plugin-data-viewer'; +import { DatabaseDataFeature } from '@cloudbeaver/plugin-data-viewer'; import { type IDataQueryOptions, QueryDataSource } from '@cloudbeaver/plugin-sql-editor'; export interface IDataGroupingOptions extends IDataQueryOptions { @@ -33,10 +33,6 @@ export class GroupingDataSource extends QueryDataSource { this.setFeature(DatabaseDataFeature.Grouping); } - override getReadonlyReason(_resultIndex: number): DataReadonlyReason | null { - return DataReadonlyReason.Presentation; - } - protected override async executeQuery( executionContextInfo: IConnectionExecutionContextInfo, options: IDataGroupingOptions, diff --git a/webapp/packages/plugin-data-viewer/src/DatabaseDataModel/DatabaseDataModel.ts b/webapp/packages/plugin-data-viewer/src/DatabaseDataModel/DatabaseDataModel.ts index 1296a4616ad..d3f4d5a0291 100644 --- a/webapp/packages/plugin-data-viewer/src/DatabaseDataModel/DatabaseDataModel.ts +++ b/webapp/packages/plugin-data-viewer/src/DatabaseDataModel/DatabaseDataModel.ts @@ -12,7 +12,7 @@ import type { ResultDataFormat } from '@cloudbeaver/core-sdk'; import { uuid } from '@cloudbeaver/core-utils'; import type { IDatabaseDataModel, IRequestEventData } from './IDatabaseDataModel.js'; -import type { DatabaseDataAccessMode, DataReadonlyReason, IDatabaseDataSource, IRequestInfo } from './IDatabaseDataSource.js'; +import type { DatabaseDataAccessMode, IDatabaseDataSource, IRequestInfo } from './IDatabaseDataSource.js'; export class DatabaseDataModel = IDatabaseDataSource> implements IDatabaseDataModel { id: string; @@ -59,10 +59,6 @@ export class DatabaseDataModel = I return this.source.isReadonly(resultIndex); } - getReadonlyReason(resultIndex: number): DataReadonlyReason | null { - return this.source.getReadonlyReason(resultIndex); - } - isDataAvailable(offset: number, count: number): boolean { return this.source.isDataAvailable(offset, count); } diff --git a/webapp/packages/plugin-data-viewer/src/DatabaseDataModel/DatabaseDataSource.ts b/webapp/packages/plugin-data-viewer/src/DatabaseDataModel/DatabaseDataSource.ts index a826d1cf382..8c49420192f 100644 --- a/webapp/packages/plugin-data-viewer/src/DatabaseDataModel/DatabaseDataSource.ts +++ b/webapp/packages/plugin-data-viewer/src/DatabaseDataModel/DatabaseDataSource.ts @@ -18,7 +18,6 @@ import { DatabaseDataAccessMode, DatabaseDataFeature, DatabaseDataSourceOperation, - type DataReadonlyReason, IDatabaseDataSource, type IDatabaseDataSourceOperationEvent, type IRequestInfo, @@ -214,10 +213,6 @@ export abstract class DatabaseDataSource 1 || this.disabled; } - getReadonlyReason(resultIndex: number): DataReadonlyReason | null { - return null; - } - isLoading(): boolean { return !!this.activeOperation; } diff --git a/webapp/packages/plugin-data-viewer/src/DatabaseDataModel/IDatabaseDataModel.ts b/webapp/packages/plugin-data-viewer/src/DatabaseDataModel/IDatabaseDataModel.ts index 92050b31a26..4179acb7920 100644 --- a/webapp/packages/plugin-data-viewer/src/DatabaseDataModel/IDatabaseDataModel.ts +++ b/webapp/packages/plugin-data-viewer/src/DatabaseDataModel/IDatabaseDataModel.ts @@ -8,13 +8,7 @@ import type { IExecutor } from '@cloudbeaver/core-executor'; import type { ResultDataFormat } from '@cloudbeaver/core-sdk'; -import type { - DatabaseDataAccessMode, - DataReadonlyReason, - IDatabaseDataSource, - IDatabaseDataSourceOperationEvent, - IRequestInfo, -} from './IDatabaseDataSource.js'; +import type { DatabaseDataAccessMode, IDatabaseDataSource, IDatabaseDataSourceOperationEvent, IRequestInfo } from './IDatabaseDataSource.js'; export interface IRequestEventData = IDatabaseDataSource> extends IDatabaseDataSourceOperationEvent { model: IDatabaseDataModel; @@ -37,7 +31,6 @@ export interface IDatabaseDataModel this; isReadonly: (resultIndex: number) => boolean; - getReadonlyReason: (resultIndex: number) => DataReadonlyReason | null; isDisabled: (resultIndex?: number) => boolean; isLoading: () => boolean; isDataAvailable: (offset: number, count: number) => boolean; diff --git a/webapp/packages/plugin-data-viewer/src/DatabaseDataModel/IDatabaseDataSource.ts b/webapp/packages/plugin-data-viewer/src/DatabaseDataModel/IDatabaseDataSource.ts index 337033926f1..0e9366d0186 100644 --- a/webapp/packages/plugin-data-viewer/src/DatabaseDataModel/IDatabaseDataSource.ts +++ b/webapp/packages/plugin-data-viewer/src/DatabaseDataModel/IDatabaseDataSource.ts @@ -43,12 +43,6 @@ export enum DatabaseDataAccessMode { Default, Readonly, } -export enum DataReadonlyReason { - /** The data source does not support editing (grouping panel). */ - Presentation = 'presentation', - /** The result data itself is marked read-only by the server (computed columns, missing row identifier). */ - Result = 'result', -} /** * Feature flags for database data sources. @@ -100,7 +94,6 @@ export interface IDatabaseDataSource boolean; isLoadable: () => boolean; isReadonly: (resultIndex: number) => boolean; - getReadonlyReason: (resultIndex: number) => DataReadonlyReason | null; isDataAvailable: (offset: number, count: number) => boolean; isLoading: () => boolean; isDisabled: (resultIndex?: number) => boolean; diff --git a/webapp/packages/plugin-data-viewer/src/ResultSet/ResultSetDataSource.ts b/webapp/packages/plugin-data-viewer/src/ResultSet/ResultSetDataSource.ts index 0a4622a3419..12c7fd30d68 100644 --- a/webapp/packages/plugin-data-viewer/src/ResultSet/ResultSetDataSource.ts +++ b/webapp/packages/plugin-data-viewer/src/ResultSet/ResultSetDataSource.ts @@ -36,7 +36,7 @@ import { ResultSetFormatAction } from '../DatabaseDataModel/Actions/ResultSet/Re import { ResultSetSelectAction } from '../DatabaseDataModel/Actions/ResultSet/ResultSetSelectAction.js'; import { ResultSetViewAction } from '../DatabaseDataModel/Actions/ResultSet/ResultSetViewAction.js'; import { IDatabaseDataSelectAction } from '../DatabaseDataModel/Actions/IDatabaseDataSelectAction.js'; -import { DatabaseDataFeature, DataReadonlyReason } from '../DatabaseDataModel/IDatabaseDataSource.js'; +import { DatabaseDataFeature } from '../DatabaseDataModel/IDatabaseDataSource.js'; export interface IRowIdentifierInfo { state: SqlRowIdentifierState | null; @@ -91,13 +91,6 @@ export abstract class ResultSetDataSource { await super.cancel(); await this.cancelLoadTotalCount();