CB-4570 add correct limits for text and blob columns in value panel (#2351)

* CB-4570 add correct limits for text and blob columns in value panel

* CB-4570 pr fixes

* CB-4570 adds shorter versions of limit messages

* CB-4570 pr fixes

* CB-4570 pr fixes

* CB-4570 code cleanup

* CB-4570 show more button moved to quota container

* CB-4570 code cleanup

* CB-4570 code cleanup

* CB-4570 quota placeholder to module css

* CB-4570 refactor: limit info in content action

* CB-4570 cleanup

* CB-4570 refactor: result set binary file implementation

* CB-4570 code clean

* CB-4570 adds QuotaPlaceholder getLimitInfo logic

* CB-4570 adds quota placeholder logic to not render when size is not truncated

* CB-4570 fix: shouldShowPasteButton reverted

* CB-4570 fix: show quota placeholder correctly

* CB-4570 code clean

* Revert "CB-4570 fix: show quota placeholder correctly"

This reverts commit d86b35e47a.

* CB-4570 fix: truncate image and text depending on current value panel presentation tab id

* Revert "Revert "CB-4570 fix: show quota placeholder correctly""

This reverts commit d5df008e89.

* CB-4570 code clean

* CB-4570 chore: dataContent has no image mentions

---------

Co-authored-by: s.teleshev <s.teleshev@mu.se>
Co-authored-by: Evgenia Bezborodova <139753579+EvgeniaBzzz@users.noreply.github.com>
This commit is contained in:
sergeyteleshev
2024-02-09 19:31:56 +03:00
committed by GitHub
co-authored by s.teleshev Evgenia Bezborodova
parent 1d497fe14f
commit 898e7d9b9d
22 changed files with 196 additions and 154 deletions
@@ -1,5 +1,5 @@
import type { IResultSetContentValue } from './IResultSetContentValue';
export interface IResultSetBinaryFileValue extends IResultSetContentValue {
export interface IResultSetBinaryValue extends IResultSetContentValue {
binary: string;
}
@@ -5,12 +5,12 @@
* Licensed under the Apache License, Version 2.0.
* you may not use this file except in compliance with the License.
*/
import type { IResultSetContentValue } from './IResultSetContentValue';
import type { IResultSetElementKey } from './IResultSetDataKey';
export interface IResultSetDataContentAction {
activeElement: IResultSetElementKey | null;
isContentTruncated: (content: IResultSetContentValue) => boolean;
isBlobTruncated: (element: IResultSetElementKey) => boolean;
isTextTruncated: (element: IResultSetElementKey) => boolean;
isDownloadable: (element: IResultSetElementKey) => boolean;
getFileDataUrl: (element: IResultSetElementKey) => Promise<string>;
resolveFileDataUrl: (element: IResultSetElementKey) => Promise<string>;
@@ -9,13 +9,12 @@ import { makeObservable, observable } from 'mobx';
import { QuotasService } from '@cloudbeaver/core-root';
import { GraphQLService, ResultDataFormat } from '@cloudbeaver/core-sdk';
import { download, GlobalConstants } from '@cloudbeaver/core-utils';
import { bytesToSize, download, GlobalConstants, isNotNullDefined } from '@cloudbeaver/core-utils';
import { DatabaseDataAction } from '../../DatabaseDataAction';
import type { IDatabaseDataSource } from '../../IDatabaseDataSource';
import type { IDatabaseResultSet } from '../../IDatabaseResultSet';
import { databaseDataAction } from '../DatabaseDataActionDecorator';
import type { IResultSetContentValue } from './IResultSetContentValue';
import type { IResultSetDataContentAction } from './IResultSetDataContentAction';
import type { IResultSetElementKey } from './IResultSetDataKey';
import { isResultSetContentValue } from './isResultSetContentValue';
@@ -57,8 +56,53 @@ export class ResultSetDataContentAction extends DatabaseDataAction<any, IDatabas
});
}
isContentTruncated(content: IResultSetContentValue) {
return (content.contentLength ?? 0) > this.quotasService.getQuota('sqlBinaryPreviewMaxLength');
getLimitInfo(elementKey: IResultSetElementKey) {
const isTextColumn = this.format.isText(elementKey);
const isBlob = this.format.isBinary(elementKey);
const result = {
limit: undefined as number | undefined,
limitWithSize: undefined as string | undefined,
};
if (isTextColumn) {
result.limit = this.quotasService.getQuota('sqlTextPreviewMaxLength');
}
if (isBlob) {
result.limit = this.quotasService.getQuota('sqlBinaryPreviewMaxLength');
}
if (result.limit) {
result.limitWithSize = bytesToSize(result.limit);
}
return result;
}
isBlobTruncated(elementKey: IResultSetElementKey) {
const limit = this.getLimitInfo(elementKey).limit;
const content = this.format.get(elementKey);
const cachedBlobUrl = this.retrieveFileDataUrlFromCache(elementKey);
const isLoadedFullBlob = Boolean(cachedBlobUrl) && this.format.isBinary(elementKey);
if (!isNotNullDefined(limit) || !isResultSetContentValue(content) || isLoadedFullBlob || !this.format.isBinary(elementKey)) {
return false;
}
return (content.contentLength ?? 0) > limit;
}
isTextTruncated(elementKey: IResultSetElementKey) {
const limit = this.getLimitInfo(elementKey).limit;
const content = this.format.get(elementKey);
const cachedFullText = this.retrieveFileFullTextFromCache(elementKey);
const isLoadedFullText = Boolean(cachedFullText) && this.format.isText(elementKey);
if (!isNotNullDefined(limit) || !isResultSetContentValue(content) || isLoadedFullText) {
return false;
}
return (content.contentLength ?? 0) > limit;
}
isDownloadable(element: IResultSetElementKey) {
@@ -102,6 +102,16 @@ export class ResultSetFormatAction
return false;
}
isText(key: IResultSetPartialKey): boolean {
if (!key?.column) {
return false;
}
const column = this.view.getColumn(key.column);
return column?.dataKind?.toLocaleLowerCase() === 'string';
}
getHeaders(): string[] {
return this.view.columns.map(column => column.name!).filter(name => name !== undefined);
}
@@ -1,5 +0,0 @@
import type { IResultSetBinaryFileValue } from './IResultSetBinaryFileValue';
export function isResultSetBinaryFileValue(value: any): value is IResultSetBinaryFileValue {
return value?.contentType === 'application/octet-stream' && Boolean(value?.binary);
}
@@ -0,0 +1,13 @@
/*
* CloudBeaver - Cloud Database Manager
* Copyright (C) 2020-2024 DBeaver Corp and others
*
* Licensed under the Apache License, Version 2.0.
* you may not use this file except in compliance with the License.
*/
import type { IResultSetBinaryValue } from './IResultSetBinaryValue';
import { isResultSetContentValue } from './isResultSetContentValue';
export function isResultSetBinaryValue(value: any): value is IResultSetBinaryValue {
return isResultSetContentValue(value) && 'binary' in value;
}
@@ -17,7 +17,7 @@ interface IResultActionsArgs {
model: IDatabaseDataModel<any, IDatabaseResultSet>;
}
export function useResultActions({ model, resultIndex }: IResultActionsArgs) {
export function useResultSetActions({ model, resultIndex }: IResultActionsArgs) {
return useObservableRef(
() => ({
get dataAction(): ResultSetDataAction {