diff --git a/webapp/packages/core-app/src/shared/ConnectionsManager/ConnectionInfoResource.ts b/webapp/packages/core-app/src/shared/ConnectionsManager/ConnectionInfoResource.ts index 072aa63d6a..0840271a96 100644 --- a/webapp/packages/core-app/src/shared/ConnectionsManager/ConnectionInfoResource.ts +++ b/webapp/packages/core-app/src/shared/ConnectionsManager/ConnectionInfoResource.ts @@ -14,7 +14,7 @@ import { ObjectPropertyInfo } from '@cloudbeaver/core-sdk'; -export type Connection = Pick & { authProperties?: ObjectPropertyInfo[] } +export type Connection = Pick & { authProperties?: ObjectPropertyInfo[] } @injectable() export class ConnectionInfoResource extends CachedMapResource { diff --git a/webapp/packages/core-sdk/src/queries/connections/closeConnection.gql b/webapp/packages/core-sdk/src/queries/connections/closeConnection.gql index a116480f34..d2a2e7037b 100644 --- a/webapp/packages/core-sdk/src/queries/connections/closeConnection.gql +++ b/webapp/packages/core-sdk/src/queries/connections/closeConnection.gql @@ -5,6 +5,8 @@ mutation closeConnection($id: ID!) { description driverId connected + readOnly + features authNeeded diff --git a/webapp/packages/core-sdk/src/queries/connections/connectionState.gql b/webapp/packages/core-sdk/src/queries/connections/connectionState.gql index 030cc32e88..1868cd6087 100644 --- a/webapp/packages/core-sdk/src/queries/connections/connectionState.gql +++ b/webapp/packages/core-sdk/src/queries/connections/connectionState.gql @@ -5,6 +5,8 @@ query connectionState($id: ID!) { description driverId connected + readOnly + features authNeeded diff --git a/webapp/packages/core-sdk/src/queries/connections/createConnection.gql b/webapp/packages/core-sdk/src/queries/connections/createConnection.gql index 0dfb8d3fee..deb70d897d 100644 --- a/webapp/packages/core-sdk/src/queries/connections/createConnection.gql +++ b/webapp/packages/core-sdk/src/queries/connections/createConnection.gql @@ -5,6 +5,8 @@ mutation createConnection($config: ConnectionConfig!) { description driverId connected + readOnly + features authNeeded diff --git a/webapp/packages/core-sdk/src/queries/connections/initConnection.gql b/webapp/packages/core-sdk/src/queries/connections/initConnection.gql index bf94edba5d..bad3eb3671 100644 --- a/webapp/packages/core-sdk/src/queries/connections/initConnection.gql +++ b/webapp/packages/core-sdk/src/queries/connections/initConnection.gql @@ -5,6 +5,8 @@ mutation initConnection($id: ID!, $credentials: Object) { description driverId connected + readOnly + features authNeeded diff --git a/webapp/packages/core-sdk/src/queries/connections/openConnection.gql b/webapp/packages/core-sdk/src/queries/connections/openConnection.gql index 618cfac0fc..8c58130a77 100644 --- a/webapp/packages/core-sdk/src/queries/connections/openConnection.gql +++ b/webapp/packages/core-sdk/src/queries/connections/openConnection.gql @@ -5,6 +5,8 @@ mutation openConnection($config: ConnectionConfig!) { description driverId connected + readOnly + features authNeeded diff --git a/webapp/packages/core-sdk/src/queries/connections/templateDataSourceList.gql b/webapp/packages/core-sdk/src/queries/connections/templateDataSourceList.gql index 353cb4294d..19b4e0bea0 100644 --- a/webapp/packages/core-sdk/src/queries/connections/templateDataSourceList.gql +++ b/webapp/packages/core-sdk/src/queries/connections/templateDataSourceList.gql @@ -5,6 +5,8 @@ query getTemplateConnections { description driverId connected + readOnly + features authNeeded diff --git a/webapp/packages/core-sdk/src/queries/grid/getSqlExecuteTaskResults.gql b/webapp/packages/core-sdk/src/queries/grid/getSqlExecuteTaskResults.gql index c21a079bac..45c72d3c24 100644 --- a/webapp/packages/core-sdk/src/queries/grid/getSqlExecuteTaskResults.gql +++ b/webapp/packages/core-sdk/src/queries/grid/getSqlExecuteTaskResults.gql @@ -22,6 +22,7 @@ mutation getSqlExecuteTaskResults( name position precision + readOnly scale typeName } diff --git a/webapp/packages/core-sdk/src/queries/grid/readDataFromContainer.gql b/webapp/packages/core-sdk/src/queries/grid/readDataFromContainer.gql index 21271e729c..0af58e44f8 100644 --- a/webapp/packages/core-sdk/src/queries/grid/readDataFromContainer.gql +++ b/webapp/packages/core-sdk/src/queries/grid/readDataFromContainer.gql @@ -29,6 +29,7 @@ mutation readDataFromContainer( name position precision + readOnly scale typeName } diff --git a/webapp/packages/core-sdk/src/sdk.ts b/webapp/packages/core-sdk/src/sdk.ts index bcd2a12e0e..5fa9c09074 100644 --- a/webapp/packages/core-sdk/src/sdk.ts +++ b/webapp/packages/core-sdk/src/sdk.ts @@ -655,6 +655,7 @@ export type SqlResultColumn = { maxLength?: Maybe; scale?: Maybe; precision?: Maybe; + readOnly: Scalars['Boolean']; }; export type SqlResultSet = { @@ -834,7 +835,7 @@ export type CloseConnectionMutationVariables = Exact<{ id: Scalars['ID']; }>; -export type CloseConnectionMutation = { connection: Pick }; +export type CloseConnectionMutation = { connection: Pick }; export type ConnectionAuthPropertiesQueryVariables = Exact<{ id: Scalars['ID']; @@ -846,13 +847,13 @@ export type ConnectionStateQueryVariables = Exact<{ id: Scalars['ID']; }>; -export type ConnectionStateQuery = { connection: Pick }; +export type ConnectionStateQuery = { connection: Pick }; export type CreateConnectionMutationVariables = Exact<{ config: ConnectionConfig; }>; -export type CreateConnectionMutation = { createConnection: Pick }; +export type CreateConnectionMutation = { createConnection: Pick }; export type DeleteConnectionMutationVariables = Exact<{ id: Scalars['ID']; @@ -891,17 +892,17 @@ export type InitConnectionMutationVariables = Exact<{ credentials?: Maybe; }>; -export type InitConnectionMutation = { connection: Pick }; +export type InitConnectionMutation = { connection: Pick }; export type OpenConnectionMutationVariables = Exact<{ config: ConnectionConfig; }>; -export type OpenConnectionMutation = { connection: Pick }; +export type OpenConnectionMutation = { connection: Pick }; export type GetTemplateConnectionsQueryVariables = Exact<{ [key: string]: never }>; -export type GetTemplateConnectionsQuery = { connections: Array> }; +export type GetTemplateConnectionsQuery = { connections: Array> }; export type TestConnectionMutationVariables = Exact<{ config: ConnectionConfig; @@ -984,7 +985,7 @@ export type GetSqlExecuteTaskResultsMutation = { result: ( Pick & { resultSet?: Maybe<( Pick - & { columns?: Maybe>>> } + & { columns?: Maybe>>> } )>; } )>; } ); }; @@ -1002,7 +1003,7 @@ export type ReadDataFromContainerMutation = { readDataFromContainer?: Maybe<( Pick & { resultSet?: Maybe<( Pick - & { columns?: Maybe>>> } + & { columns?: Maybe>>> } )>; } )>; } )>; }; @@ -1296,6 +1297,7 @@ export const CloseConnectionDocument = ` description driverId connected + readOnly features authNeeded authModel @@ -1327,6 +1329,7 @@ export const ConnectionStateDocument = ` description driverId connected + readOnly features authNeeded authModel @@ -1341,6 +1344,7 @@ export const CreateConnectionDocument = ` description driverId connected + readOnly features authNeeded authModel @@ -1422,6 +1426,7 @@ export const InitConnectionDocument = ` description driverId connected + readOnly features authNeeded authModel @@ -1436,6 +1441,7 @@ export const OpenConnectionDocument = ` description driverId connected + readOnly features authNeeded authModel @@ -1450,6 +1456,7 @@ export const GetTemplateConnectionsDocument = ` description driverId connected + readOnly features authNeeded authModel @@ -1593,6 +1600,7 @@ export const GetSqlExecuteTaskResultsDocument = ` name position precision + readOnly scale typeName } @@ -1623,6 +1631,7 @@ export const ReadDataFromContainerDocument = ` name position precision + readOnly scale typeName } diff --git a/webapp/packages/plugin-data-spreadsheet/src/AgGridTable/AgGridTableController.ts b/webapp/packages/plugin-data-spreadsheet/src/AgGridTable/AgGridTableController.ts index 0eea56d6ce..fd1ccf7871 100644 --- a/webapp/packages/plugin-data-spreadsheet/src/AgGridTable/AgGridTableController.ts +++ b/webapp/packages/plugin-data-spreadsheet/src/AgGridTable/AgGridTableController.ts @@ -268,7 +268,7 @@ function mapDataToColumns(columns?: IAgGridCol[]): ColDef[] { type: v.dataKind, editable: (params: any) => { const context: AgGridContext = params.context; - return !context.isReadonly(); + return !(context.isReadonly() || v.readOnly); }, valueGetter: (params: ValueGetterParams) => { if (!params.data) { diff --git a/webapp/packages/plugin-data-viewer/src/DataViewerTabService.ts b/webapp/packages/plugin-data-viewer/src/DataViewerTabService.ts index a4ac107835..18550bbfed 100644 --- a/webapp/packages/plugin-data-viewer/src/DataViewerTabService.ts +++ b/webapp/packages/plugin-data-viewer/src/DataViewerTabService.ts @@ -103,7 +103,7 @@ export class DataViewerTabService { return; } - this.dataViewerTableService.create( + await this.dataViewerTableService.create( tab.id, NodeManagerUtils.connectionNodeIdToConnectionId(nodeInfo.connectionId), tab.handlerState.objectId diff --git a/webapp/packages/plugin-data-viewer/src/DataViewerTableService.ts b/webapp/packages/plugin-data-viewer/src/DataViewerTableService.ts index 54f4b67ce6..0c638887fc 100644 --- a/webapp/packages/plugin-data-viewer/src/DataViewerTableService.ts +++ b/webapp/packages/plugin-data-viewer/src/DataViewerTableService.ts @@ -6,17 +6,19 @@ * you may not use this file except in compliance with the License. */ +import { ConnectionInfoResource } from '@cloudbeaver/core-app'; import { injectable } from '@cloudbeaver/core-di'; import { GraphQLService } from '@cloudbeaver/core-sdk'; import { IExecutionContext } from './IExecutionContext'; import { RowDiff } from './TableViewer/TableDataModel/EditedRow'; -import { IRequestDataResult, TableViewerModel } from './TableViewer/TableViewerModel'; +import { IRequestDataResult, TableViewerModel, AccessMode } from './TableViewer/TableViewerModel'; import { TableViewerStorageService } from './TableViewer/TableViewerStorageService'; @injectable() export class DataViewerTableService { constructor(private tableViewerStorageService: TableViewerStorageService, + private connectionInfoResource: ConnectionInfoResource, private graphQLService: GraphQLService) { } @@ -28,16 +30,19 @@ export class DataViewerTableService { this.tableViewerStorageService.remove(tableId); } - create( + async create( tabId: string, connectionId: string, containerNodePath?: string, - ): TableViewerModel { + ): Promise { + const connectionInfo = await this.connectionInfoResource.load(connectionId); + return this.tableViewerStorageService.create( { tableId: tabId, connectionId, containerNodePath, + access: connectionInfo.readOnly ? AccessMode.Readonly : AccessMode.Default, requestDataAsync: this.requestDataAsync.bind(this), saveChanges: this.saveChanges.bind(this), } diff --git a/webapp/packages/plugin-data-viewer/src/TableViewer/TableDataModel/TableColumn.ts b/webapp/packages/plugin-data-viewer/src/TableViewer/TableDataModel/TableColumn.ts index 203d1b423d..3d1390fd77 100644 --- a/webapp/packages/plugin-data-viewer/src/TableViewer/TableDataModel/TableColumn.ts +++ b/webapp/packages/plugin-data-viewer/src/TableViewer/TableDataModel/TableColumn.ts @@ -19,6 +19,7 @@ export type TableColumn = Pick< | 'name' | 'position' | 'precision' + | 'readOnly' | 'scale' | 'typeName' > diff --git a/webapp/packages/plugin-data-viewer/src/TableViewer/TableViewerModel.ts b/webapp/packages/plugin-data-viewer/src/TableViewer/TableViewerModel.ts index 605ed38c02..6c442dd761 100644 --- a/webapp/packages/plugin-data-viewer/src/TableViewer/TableViewerModel.ts +++ b/webapp/packages/plugin-data-viewer/src/TableViewer/TableViewerModel.ts @@ -52,6 +52,7 @@ export interface IAgGridCol { name?: string; position?: number; dataKind?: string; + readOnly: boolean; } export interface IRequestedData { diff --git a/webapp/packages/plugin-sql-editor/src/SqlResultTabs/SqlResultPanel/SqlResultPanelController.ts b/webapp/packages/plugin-sql-editor/src/SqlResultTabs/SqlResultPanel/SqlResultPanelController.ts index e7127e5d02..56102181e6 100644 --- a/webapp/packages/plugin-sql-editor/src/SqlResultTabs/SqlResultPanel/SqlResultPanelController.ts +++ b/webapp/packages/plugin-sql-editor/src/SqlResultTabs/SqlResultPanel/SqlResultPanelController.ts @@ -8,7 +8,7 @@ import { observable } from 'mobx'; -import { ErrorDetailsDialog } from '@cloudbeaver/core-app'; +import { ErrorDetailsDialog, ConnectionInfoResource } from '@cloudbeaver/core-app'; import { IDestructibleController, IInitializableController, injectable } from '@cloudbeaver/core-di'; import { CommonDialogService } from '@cloudbeaver/core-dialogs'; import { NotificationService } from '@cloudbeaver/core-events'; @@ -20,6 +20,7 @@ import { RowDiff, TableViewerStorageService, TableViewerModel, + AccessMode, } from '@cloudbeaver/plugin-data-viewer'; import { ISqlResultPanelParams } from '../../ISqlEditorTabState'; @@ -47,6 +48,7 @@ implements IInitializableController, IDestructibleController { constructor(private sqlResultService: SqlResultService, private tableViewerStorageService: TableViewerStorageService, + private connectionInfoResource: ConnectionInfoResource, private commonDialogService: CommonDialogService, private notificationService: NotificationService) { } @@ -71,12 +73,15 @@ implements IInitializableController, IDestructibleController { const initialState = this.sqlResultService .sqlExecuteInfoToData(response, this.panelInit.indexInResultSet, fetchingSettings.fetchDefault); + const connectionInfo = await this.connectionInfoResource.load(panelInit.sqlQueryParams.connectionId); + const tableModel = this.tableViewerStorageService.create({ tableId: this.getTableId(), connectionId: panelInit.sqlQueryParams.connectionId, executionContext: panelInit.sqlQueryParams, resultId: dataSet.resultSet.id, sourceName: panelInit.sqlQueryParams.query, + access: connectionInfo.readOnly ? AccessMode.Readonly : AccessMode.Default, requestDataAsync: this.requestDataAsync.bind(this, panelInit.sqlExecutionState), noLoaderWhileRequestingDataAsync: true, saveChanges: this.saveChanges.bind(this),