From 3965f1633057a54a134f4ed9674aa27eae02c74e Mon Sep 17 00:00:00 2001 From: Alexander Skoblikov Date: Fri, 9 Feb 2024 18:52:59 +0400 Subject: [PATCH 1/5] CB-4498 secrets cleanup (#2352) Co-authored-by: kseniaguzeeva <112612526+kseniaguzeeva@users.noreply.github.com> --- .../src/io/cloudbeaver/DBWConstants.java | 18 ++++++++++-------- .../service/admin/impl/WebServiceAdmin.java | 9 +++++++++ .../service/rm/impl/WebServiceRM.java | 9 +++++++++ 3 files changed, 28 insertions(+), 8 deletions(-) diff --git a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/DBWConstants.java b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/DBWConstants.java index 2bc9aa5a37..cce8a6d406 100644 --- a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/DBWConstants.java +++ b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/DBWConstants.java @@ -22,19 +22,21 @@ /** * General constants */ -public class DBWConstants { +public interface DBWConstants { - public static final String PERMISSION_ADMIN = DBAPermissionRealm.PERMISSION_ADMIN; + String PERMISSION_ADMIN = DBAPermissionRealm.PERMISSION_ADMIN; - public static final String PERMISSION_CONFIGURATION_MANAGER = RMConstants.PERMISSION_CONFIGURATION_MANAGER; - public static final String PERMISSION_PRIVATE_PROJECT_ACCESS = "private-project-access"; + String PERMISSION_CONFIGURATION_MANAGER = RMConstants.PERMISSION_CONFIGURATION_MANAGER; + String PERMISSION_PRIVATE_PROJECT_ACCESS = "private-project-access"; + String PERMISSION_SECRET_MANAGER = "secret-manager"; - public static final String PERMISSION_EDIT_STRUCTURE = "edit-meta"; - public static final String PERMISSION_EDIT_DATA = "edit-data"; - public static final String STATE_ATTR_SIGN_IN_STATE = "state.signin"; + String PERMISSION_EDIT_STRUCTURE = "edit-meta"; + String PERMISSION_EDIT_DATA = "edit-data"; - public enum SignInState { + String STATE_ATTR_SIGN_IN_STATE = "state.signin"; + + enum SignInState { GLOBAL, EMBEDDED } diff --git a/server/bundles/io.cloudbeaver.service.admin/src/io/cloudbeaver/service/admin/impl/WebServiceAdmin.java b/server/bundles/io.cloudbeaver.service.admin/src/io/cloudbeaver/service/admin/impl/WebServiceAdmin.java index 748734679f..af94e9a4e9 100644 --- a/server/bundles/io.cloudbeaver.service.admin/src/io/cloudbeaver/service/admin/impl/WebServiceAdmin.java +++ b/server/bundles/io.cloudbeaver.service.admin/src/io/cloudbeaver/service/admin/impl/WebServiceAdmin.java @@ -44,6 +44,7 @@ import org.jkiss.dbeaver.model.navigator.DBNBrowseSettings; import org.jkiss.dbeaver.model.preferences.DBPPropertyDescriptor; import org.jkiss.dbeaver.model.rm.RMProjectType; +import org.jkiss.dbeaver.model.secret.DBSSecretController; import org.jkiss.dbeaver.model.security.*; import org.jkiss.dbeaver.model.security.user.SMTeam; import org.jkiss.dbeaver.model.security.user.SMUser; @@ -178,6 +179,10 @@ public boolean deleteUser(@NotNull WebSession webSession, String userName) throw } webSession.addInfoMessage("Delete user - " + userName); try { + var secretController = DBSSecretController.getSessionSecretControllerOrNull(webSession); + if (secretController != null) { + secretController.deleteSubjectSecrets(userName); + } webSession.getAdminSecurityController().deleteUser(userName); } catch (Exception e) { throw new DBWebException("Error deleting user", e); @@ -235,6 +240,10 @@ public boolean deleteTeam(@NotNull WebSession webSession, String teamId, boolean if (Arrays.stream(userTeams).anyMatch(team -> team.getTeamId().equals(teamId))) { throw new DBWebException("You can not delete your own team"); } + var secretController = DBSSecretController.getSessionSecretControllerOrNull(webSession); + if (secretController != null) { + secretController.deleteSubjectSecrets(teamId); + } adminSecurityController.deleteTeam(teamId, force); return true; } catch (Exception e) { diff --git a/server/bundles/io.cloudbeaver.service.rm/src/io/cloudbeaver/service/rm/impl/WebServiceRM.java b/server/bundles/io.cloudbeaver.service.rm/src/io/cloudbeaver/service/rm/impl/WebServiceRM.java index 826152f83d..19d73fd036 100644 --- a/server/bundles/io.cloudbeaver.service.rm/src/io/cloudbeaver/service/rm/impl/WebServiceRM.java +++ b/server/bundles/io.cloudbeaver.service.rm/src/io/cloudbeaver/service/rm/impl/WebServiceRM.java @@ -31,6 +31,7 @@ import org.jkiss.dbeaver.model.rm.RMController; import org.jkiss.dbeaver.model.rm.RMProject; import org.jkiss.dbeaver.model.rm.RMResource; +import org.jkiss.dbeaver.model.secret.DBSSecretController; import org.jkiss.dbeaver.model.security.*; import org.jkiss.dbeaver.model.websocket.WSConstants; import org.jkiss.dbeaver.model.websocket.event.WSProjectUpdateEvent; @@ -265,6 +266,14 @@ public RMProject createProject( @Override public boolean deleteProject(@NotNull WebSession session, @NotNull String projectId) throws DBWebException { try { + var project = session.getProjectById(projectId); + if (project == null) { + throw new DBException("Project not found: " + projectId); + } + if (project.isUseSecretStorage()) { + var secretController = DBSSecretController.getProjectSecretController(project); + secretController.deleteProjectSecrets(project.getId()); + } getResourceController(session).deleteProject(projectId); session.removeSessionProject(projectId); WebAppUtils.getWebApplication().getEventController().addEvent( From 1d497fe14f023f2b8ef834c00ae5586d213c02e0 Mon Sep 17 00:00:00 2001 From: alex <48489896+devnaumov@users.noreply.github.com> Date: Fri, 9 Feb 2024 17:08:36 +0100 Subject: [PATCH 2/5] CB-4628 remove unused logic (#2367) * CB-4628 remove unused logic * CB-4628 remove onClean callback * CB-4628 add applyDisabled prop * CB-4628 check if apply is enabled on enter * CB-4628 add disable actions prop --------- Co-authored-by: Daria Marutkina <125263541+dariamarutkina@users.noreply.github.com> --- .../core-blocks/src/FormControls/Filter.m.css | 27 +++---- .../core-blocks/src/FormControls/Filter.tsx | 76 ++++++++++--------- 2 files changed, 51 insertions(+), 52 deletions(-) diff --git a/webapp/packages/core-blocks/src/FormControls/Filter.m.css b/webapp/packages/core-blocks/src/FormControls/Filter.m.css index 7a3483d9cf..a890afe555 100644 --- a/webapp/packages/core-blocks/src/FormControls/Filter.m.css +++ b/webapp/packages/core-blocks/src/FormControls/Filter.m.css @@ -4,43 +4,36 @@ min-height: 24px; } .inputField { - display: none; + display: block; width: 300px; &.max { width: 100%; } - &.toggled { - display: block; - } - & .input { + & input { padding-right: 40px !important; } - } .iconButton { position: absolute; - right: 0; - top: 0; + right: 4px; + top: 4px; margin: 0; width: 24px; height: 24px; border-radius: 2px; cursor: auto; - &.toggled { - right: 4px; - top: 4px; - } - &.cross { + &.cross svg { width: 16px; - height: 16px; - top: 8px; - right: 8px; + } + + &.cross.manualMode { + right: 32px; } } -.toggleMode { +.manualMode { composes: theme-background-primary theme-text-on-primary from global; cursor: pointer; } diff --git a/webapp/packages/core-blocks/src/FormControls/Filter.tsx b/webapp/packages/core-blocks/src/FormControls/Filter.tsx index 7b4668c36c..eb0501ce21 100644 --- a/webapp/packages/core-blocks/src/FormControls/Filter.tsx +++ b/webapp/packages/core-blocks/src/FormControls/Filter.tsx @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. */ import { observer } from 'mobx-react-lite'; -import { useCallback, useEffect, useState } from 'react'; +import { useCallback } from 'react'; import { IconButton } from '../IconButton'; import { s } from '../s'; @@ -16,12 +16,13 @@ import filterStyle from './Filter.m.css'; import { InputField } from './InputField'; interface BaseProps { - toggleMode?: boolean; placeholder?: string; disabled?: boolean; + disableActions?: boolean; + applyDisabled?: boolean; max?: boolean; className?: string; - onToggle?: (status: boolean) => void; + onApply?: (value: string) => void; onKeyDown?: (event: React.KeyboardEvent) => void; onClick?: (event: React.MouseEvent) => void; } @@ -44,19 +45,19 @@ export const Filter = observer>(functio state, name, value: valueControlled, - toggleMode, placeholder, disabled, + disableActions, + applyDisabled, max, className, + onApply, onChange, - onToggle, onKeyDown, onClick, }) { const styles = useS(filterStyle); - const [inputRef, ref] = useFocus({}); - const [toggled, setToggled] = useState(!toggleMode); + const [inputRef] = useFocus({}); const filter = useCallback( (value: string | number, name?: string) => { @@ -73,55 +74,60 @@ export const Filter = observer>(functio [onChange, state], ); - const toggle = useCallback(() => { - if (!toggleMode) { - return; - } - - if (toggled) { - filter(''); - } + let value: any = valueControlled; - setToggled(!toggled); + if (state && name !== undefined && name in state) { + value = state[name]; + } - if (onToggle) { - onToggle(!toggled); + function handleKeyDown(event: React.KeyboardEvent) { + if (event.key === 'Enter' && onApply && !applyDisabled) { + onApply(value); } - }, [toggleMode, toggled, onToggle, filter]); - useEffect(() => { - if (toggled && toggleMode) { - ref.reference?.focus(); - } - }, [toggled, toggleMode, ref.reference]); + onKeyDown?.(event); + } - let value: any = valueControlled; + function clean() { + filter('', name); - if (state && name !== undefined && name in state) { - value = state[name]; + if (onApply) { + onApply(''); + } } + const manualMode = !!onApply; + const edited = !!String(value); + return (
- {String(value) ? ( + + {edited && ( filter('', name)} + disabled={disabled || disableActions} + onClick={clean} + /> + )} + + {(!edited || manualMode) && ( + onApply(value) : undefined} /> - ) : ( - )}
); From 898e7d9b9d5616a8a2fdca2ad79b6effce4b30b3 Mon Sep 17 00:00:00 2001 From: sergeyteleshev Date: Fri, 9 Feb 2024 17:31:56 +0100 Subject: [PATCH 3/5] 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 d86b35e47ac11053c332d977d2af4e0b13827eff. * 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 d5df008e890d1eaec2f79cb54c22ca6fae7675b6. * CB-4570 code clean * CB-4570 chore: dataContent has no image mentions --------- Co-authored-by: s.teleshev Co-authored-by: Evgenia Bezborodova <139753579+EvgeniaBzzz@users.noreply.github.com> --- .../core-localization/src/locales/en.ts | 1 + .../core-localization/src/locales/it.ts | 1 + .../core-localization/src/locales/ru.ts | 1 + .../core-localization/src/locales/zh.ts | 1 + ...yFileValue.ts => IResultSetBinaryValue.ts} | 2 +- .../ResultSet/IResultSetDataContentAction.ts | 4 +- .../ResultSet/ResultSetDataContentAction.ts | 52 +++++++++++- .../ResultSet/ResultSetFormatAction.ts | 10 +++ .../ResultSet/isResultSetBinaryFileValue.ts | 5 -- .../ResultSet/isResultSetBinaryValue.ts | 13 +++ ...esultActions.ts => useResultSetActions.ts} | 2 +- .../ImageValue/ImageValuePresentation.tsx | 69 +++++++--------- .../QuotaPlaceholder.m.css | 7 ++ .../QuotaPlaceholder.tsx | 82 +++++++++---------- .../TextValue/TextValuePresentation.tsx | 39 ++++----- .../isTextValuePresentationAvailable.ts | 4 +- .../TextValue/useTextValue.ts | 45 ++++------ .../packages/plugin-data-viewer/src/index.ts | 4 +- .../plugin-data-viewer/src/locales/en.ts | 2 - .../plugin-data-viewer/src/locales/it.ts | 2 - .../plugin-data-viewer/src/locales/ru.ts | 2 - .../plugin-data-viewer/src/locales/zh.ts | 2 - 22 files changed, 196 insertions(+), 154 deletions(-) rename webapp/packages/plugin-data-viewer/src/DatabaseDataModel/Actions/ResultSet/{IResultSetBinaryFileValue.ts => IResultSetBinaryValue.ts} (55%) delete mode 100644 webapp/packages/plugin-data-viewer/src/DatabaseDataModel/Actions/ResultSet/isResultSetBinaryFileValue.ts create mode 100644 webapp/packages/plugin-data-viewer/src/DatabaseDataModel/Actions/ResultSet/isResultSetBinaryValue.ts rename webapp/packages/plugin-data-viewer/src/DatabaseDataModel/Actions/ResultSet/{useResultActions.ts => useResultSetActions.ts} (96%) create mode 100644 webapp/packages/plugin-data-viewer/src/ValuePanelPresentation/QuotaPlaceholder.m.css diff --git a/webapp/packages/core-localization/src/locales/en.ts b/webapp/packages/core-localization/src/locales/en.ts index ba648f7bcb..579789ec34 100644 --- a/webapp/packages/core-localization/src/locales/en.ts +++ b/webapp/packages/core-localization/src/locales/en.ts @@ -98,6 +98,7 @@ export default [ ['ui_upload', 'Upload'], ['ui_import', 'Import'], ['ui_view', 'View'], + ['ui_show_more', 'Show more'], ['ui_limit', 'Limit'], ['ui_file_size', 'File size'], ['ui_processing_synchronization', 'Synchronization...'], diff --git a/webapp/packages/core-localization/src/locales/it.ts b/webapp/packages/core-localization/src/locales/it.ts index 300505612f..a25238f52a 100644 --- a/webapp/packages/core-localization/src/locales/it.ts +++ b/webapp/packages/core-localization/src/locales/it.ts @@ -82,6 +82,7 @@ export default [ ['ui_upload', 'Upload'], ['ui_import', 'Import'], ['ui_view', 'View'], + ['ui_show_more', 'Show more'], ['ui_limit', 'Limit'], ['ui_file_size', 'File size'], ['ui_processing_synchronization', 'Synchronization...'], diff --git a/webapp/packages/core-localization/src/locales/ru.ts b/webapp/packages/core-localization/src/locales/ru.ts index 88fc70484f..d72791ff8e 100644 --- a/webapp/packages/core-localization/src/locales/ru.ts +++ b/webapp/packages/core-localization/src/locales/ru.ts @@ -94,6 +94,7 @@ export default [ ['ui_upload', 'Загрузить'], ['ui_import', 'Импортировать'], ['ui_view', 'Смотреть'], + ['ui_show_more', 'Показать больше'], ['ui_limit', 'Лимит'], ['ui_file_size', 'Размер файла'], ['ui_processing_synchronization', 'Синхронизация...'], diff --git a/webapp/packages/core-localization/src/locales/zh.ts b/webapp/packages/core-localization/src/locales/zh.ts index c7b5d28e39..86042dae8d 100644 --- a/webapp/packages/core-localization/src/locales/zh.ts +++ b/webapp/packages/core-localization/src/locales/zh.ts @@ -95,6 +95,7 @@ export default [ ['ui_upload', 'Upload'], ['ui_import', 'Import'], ['ui_view', 'View'], + ['ui_show_more', 'Show more'], ['ui_limit', 'Limit'], ['ui_file_size', 'File size'], ['ui_processing_synchronization', 'Synchronization...'], diff --git a/webapp/packages/plugin-data-viewer/src/DatabaseDataModel/Actions/ResultSet/IResultSetBinaryFileValue.ts b/webapp/packages/plugin-data-viewer/src/DatabaseDataModel/Actions/ResultSet/IResultSetBinaryValue.ts similarity index 55% rename from webapp/packages/plugin-data-viewer/src/DatabaseDataModel/Actions/ResultSet/IResultSetBinaryFileValue.ts rename to webapp/packages/plugin-data-viewer/src/DatabaseDataModel/Actions/ResultSet/IResultSetBinaryValue.ts index 84d282ac20..1cf8f3888a 100644 --- a/webapp/packages/plugin-data-viewer/src/DatabaseDataModel/Actions/ResultSet/IResultSetBinaryFileValue.ts +++ b/webapp/packages/plugin-data-viewer/src/DatabaseDataModel/Actions/ResultSet/IResultSetBinaryValue.ts @@ -1,5 +1,5 @@ import type { IResultSetContentValue } from './IResultSetContentValue'; -export interface IResultSetBinaryFileValue extends IResultSetContentValue { +export interface IResultSetBinaryValue extends IResultSetContentValue { binary: string; } diff --git a/webapp/packages/plugin-data-viewer/src/DatabaseDataModel/Actions/ResultSet/IResultSetDataContentAction.ts b/webapp/packages/plugin-data-viewer/src/DatabaseDataModel/Actions/ResultSet/IResultSetDataContentAction.ts index 3f7d069e99..6a6c53cbca 100644 --- a/webapp/packages/plugin-data-viewer/src/DatabaseDataModel/Actions/ResultSet/IResultSetDataContentAction.ts +++ b/webapp/packages/plugin-data-viewer/src/DatabaseDataModel/Actions/ResultSet/IResultSetDataContentAction.ts @@ -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; resolveFileDataUrl: (element: IResultSetElementKey) => Promise; diff --git a/webapp/packages/plugin-data-viewer/src/DatabaseDataModel/Actions/ResultSet/ResultSetDataContentAction.ts b/webapp/packages/plugin-data-viewer/src/DatabaseDataModel/Actions/ResultSet/ResultSetDataContentAction.ts index 3d254d940e..b59d45de85 100644 --- a/webapp/packages/plugin-data-viewer/src/DatabaseDataModel/Actions/ResultSet/ResultSetDataContentAction.ts +++ b/webapp/packages/plugin-data-viewer/src/DatabaseDataModel/Actions/ResultSet/ResultSetDataContentAction.ts @@ -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 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) { diff --git a/webapp/packages/plugin-data-viewer/src/DatabaseDataModel/Actions/ResultSet/ResultSetFormatAction.ts b/webapp/packages/plugin-data-viewer/src/DatabaseDataModel/Actions/ResultSet/ResultSetFormatAction.ts index 6f3f31c87e..4c819c2c09 100644 --- a/webapp/packages/plugin-data-viewer/src/DatabaseDataModel/Actions/ResultSet/ResultSetFormatAction.ts +++ b/webapp/packages/plugin-data-viewer/src/DatabaseDataModel/Actions/ResultSet/ResultSetFormatAction.ts @@ -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); } diff --git a/webapp/packages/plugin-data-viewer/src/DatabaseDataModel/Actions/ResultSet/isResultSetBinaryFileValue.ts b/webapp/packages/plugin-data-viewer/src/DatabaseDataModel/Actions/ResultSet/isResultSetBinaryFileValue.ts deleted file mode 100644 index ae85c5deba..0000000000 --- a/webapp/packages/plugin-data-viewer/src/DatabaseDataModel/Actions/ResultSet/isResultSetBinaryFileValue.ts +++ /dev/null @@ -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); -} diff --git a/webapp/packages/plugin-data-viewer/src/DatabaseDataModel/Actions/ResultSet/isResultSetBinaryValue.ts b/webapp/packages/plugin-data-viewer/src/DatabaseDataModel/Actions/ResultSet/isResultSetBinaryValue.ts new file mode 100644 index 0000000000..2301c3eea5 --- /dev/null +++ b/webapp/packages/plugin-data-viewer/src/DatabaseDataModel/Actions/ResultSet/isResultSetBinaryValue.ts @@ -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; +} diff --git a/webapp/packages/plugin-data-viewer/src/DatabaseDataModel/Actions/ResultSet/useResultActions.ts b/webapp/packages/plugin-data-viewer/src/DatabaseDataModel/Actions/ResultSet/useResultSetActions.ts similarity index 96% rename from webapp/packages/plugin-data-viewer/src/DatabaseDataModel/Actions/ResultSet/useResultActions.ts rename to webapp/packages/plugin-data-viewer/src/DatabaseDataModel/Actions/ResultSet/useResultSetActions.ts index 0126441793..36da10e1dc 100644 --- a/webapp/packages/plugin-data-viewer/src/DatabaseDataModel/Actions/ResultSet/useResultActions.ts +++ b/webapp/packages/plugin-data-viewer/src/DatabaseDataModel/Actions/ResultSet/useResultSetActions.ts @@ -17,7 +17,7 @@ interface IResultActionsArgs { model: IDatabaseDataModel; } -export function useResultActions({ model, resultIndex }: IResultActionsArgs) { +export function useResultSetActions({ model, resultIndex }: IResultActionsArgs) { return useObservableRef( () => ({ get dataAction(): ResultSetDataAction { diff --git a/webapp/packages/plugin-data-viewer/src/ValuePanelPresentation/ImageValue/ImageValuePresentation.tsx b/webapp/packages/plugin-data-viewer/src/ValuePanelPresentation/ImageValue/ImageValuePresentation.tsx index 93cc494403..f92f970dfc 100644 --- a/webapp/packages/plugin-data-viewer/src/ValuePanelPresentation/ImageValue/ImageValuePresentation.tsx +++ b/webapp/packages/plugin-data-viewer/src/ValuePanelPresentation/ImageValue/ImageValuePresentation.tsx @@ -12,12 +12,12 @@ import { ActionIconButton, Button, Container, Fill, s, useObservableRef, useS, u import { selectFiles } from '@cloudbeaver/core-browser'; import { useService } from '@cloudbeaver/core-di'; import { NotificationService } from '@cloudbeaver/core-events'; -import { QuotasService } from '@cloudbeaver/core-root'; import { type TabContainerPanelComponent, useTabLocalState } from '@cloudbeaver/core-ui'; import { bytesToSize, download, getMIME, isImageFormat, isValidUrl } from '@cloudbeaver/core-utils'; import { createResultSetBlobValue } from '../../DatabaseDataModel/Actions/ResultSet/createResultSetBlobValue'; import type { IResultSetElementKey } from '../../DatabaseDataModel/Actions/ResultSet/IResultSetDataKey'; +import { isResultSetBinaryValue } from '../../DatabaseDataModel/Actions/ResultSet/isResultSetBinaryValue'; import { isResultSetBlobValue } from '../../DatabaseDataModel/Actions/ResultSet/isResultSetBlobValue'; import { isResultSetContentValue } from '../../DatabaseDataModel/Actions/ResultSet/isResultSetContentValue'; import { isResultSetFileValue } from '../../DatabaseDataModel/Actions/ResultSet/isResultSetFileValue'; @@ -66,7 +66,6 @@ export const ImageValuePresentation: TabContainerPanelComponent @@ -123,7 +122,7 @@ export const ImageValuePresentation: TabContainerPanelComponent { + if (!data.selectedCell) { + return; + } - const load = async () => { - if (!data.selectedCell) { - return; - } + try { + await data.contentAction.resolveFileDataUrl(data.selectedCell); + } catch (exception: any) { + notificationService.logException(exception, 'data_viewer_presentation_value_content_download_error'); + } + }; - try { - await data.contentAction.resolveFileDataUrl(data.selectedCell); - } catch (exception: any) { - notificationService.logException(exception, 'data_viewer_presentation_value_content_download_error'); - } - }; + const valueSize = bytesToSize(isResultSetContentValue(value) ? value.contentLength ?? 0 : 0); + const isDownloadable = data.selectedCell && data.contentAction.isDownloadable(data.selectedCell); - return ( - - - - {data.selectedCell && data.contentAction.isDownloadable(data.selectedCell) && ( + return ( + + + {data.shouldShowImage && } + {data.truncated ? ( + + {isDownloadable && ( )} - - - - ); - } - - return ( - - - + ) : null} diff --git a/webapp/packages/plugin-data-viewer/src/ValuePanelPresentation/QuotaPlaceholder.m.css b/webapp/packages/plugin-data-viewer/src/ValuePanelPresentation/QuotaPlaceholder.m.css new file mode 100644 index 0000000000..6b0da42e73 --- /dev/null +++ b/webapp/packages/plugin-data-viewer/src/ValuePanelPresentation/QuotaPlaceholder.m.css @@ -0,0 +1,7 @@ +.link { + margin-left: 4px; +} + +.limitWord { + text-transform: lowercase; +} diff --git a/webapp/packages/plugin-data-viewer/src/ValuePanelPresentation/QuotaPlaceholder.tsx b/webapp/packages/plugin-data-viewer/src/ValuePanelPresentation/QuotaPlaceholder.tsx index dd95cf78a4..88c39b8b8a 100644 --- a/webapp/packages/plugin-data-viewer/src/ValuePanelPresentation/QuotaPlaceholder.tsx +++ b/webapp/packages/plugin-data-viewer/src/ValuePanelPresentation/QuotaPlaceholder.tsx @@ -6,64 +6,62 @@ * you may not use this file except in compliance with the License. */ import { observer } from 'mobx-react-lite'; -import styled, { css } from 'reshadow'; -import { Link, usePermission, useTranslate } from '@cloudbeaver/core-blocks'; +import { Container, Link, s, usePermission, useS, useTranslate } from '@cloudbeaver/core-blocks'; import { EAdminPermission } from '@cloudbeaver/core-root'; +import type { IResultSetElementKey } from '../DatabaseDataModel/Actions/ResultSet/IResultSetDataKey'; +import { useResultSetActions } from '../DatabaseDataModel/Actions/ResultSet/useResultSetActions'; +import type { IDatabaseDataModel } from '../DatabaseDataModel/IDatabaseDataModel'; +import type { IDatabaseResultSet } from '../DatabaseDataModel/IDatabaseResultSet'; +import styles from './QuotaPlaceholder.m.css'; + interface Props { - limit?: string; - size?: string; className?: string; + elementKey: IResultSetElementKey | undefined; + model: IDatabaseDataModel; + resultIndex: number; + keepSize?: boolean; } -const style = css` - container { - margin: auto; - display: flex; - align-items: center; - justify-content: center; - flex-direction: column; - } - p { - composes: theme-typography--body2 from global; - text-align: center; - margin: 0; - } - reason { - display: flex; - white-space: pre; - } - limit-word { - text-transform: lowercase; - } -`; - -export const QuotaPlaceholder: React.FC> = observer(function QuotaPlaceholder({ limit, size, className, children }) { +export const QuotaPlaceholder: React.FC> = observer(function QuotaPlaceholder({ + className, + children, + keepSize = false, + elementKey, + model, + resultIndex, +}) { const translate = useTranslate(); const admin = usePermission(EAdminPermission.admin); + const style = useS(styles); + const { contentAction } = useResultSetActions({ model, resultIndex }); + const limitInfo = elementKey ? contentAction.getLimitInfo(elementKey) : null; - return styled(style)( - -

+ return ( + + {translate('data_viewer_presentation_value_content_was_truncated')} - - {translate('data_viewer_presentation_value_content_truncated_placeholder') + ' '} - + + {translate('data_viewer_presentation_value_content_truncated_placeholder')} + {admin ? ( - + {translate('ui_limit')} ) : ( translate('ui_limit') )} - - - {limit && `${translate('ui_limit')}: ${limit}`} -
- {size && `${translate('data_viewer_presentation_value_content_value_size')}: ${size}`} -

- {children} -
, +
+
+ + {children} + ); }); diff --git a/webapp/packages/plugin-data-viewer/src/ValuePanelPresentation/TextValue/TextValuePresentation.tsx b/webapp/packages/plugin-data-viewer/src/ValuePanelPresentation/TextValue/TextValuePresentation.tsx index 7d261c020e..739402f509 100644 --- a/webapp/packages/plugin-data-viewer/src/ValuePanelPresentation/TextValue/TextValuePresentation.tsx +++ b/webapp/packages/plugin-data-viewer/src/ValuePanelPresentation/TextValue/TextValuePresentation.tsx @@ -13,14 +13,13 @@ import styled, { css } from 'reshadow'; import { ActionIconButton, Button, Container, Fill, Group, useStyles, useTranslate } from '@cloudbeaver/core-blocks'; import { useService } from '@cloudbeaver/core-di'; import { NotificationService } from '@cloudbeaver/core-events'; -import { QuotasService } from '@cloudbeaver/core-root'; import { BASE_TAB_STYLES, TabContainerPanelComponent, TabList, TabsState, UNDERLINE_TAB_STYLES, useTabLocalState } from '@cloudbeaver/core-ui'; import { bytesToSize, isNotNullDefined } from '@cloudbeaver/core-utils'; import { EditorLoader, useCodemirrorExtensions } from '@cloudbeaver/plugin-codemirror6'; import { isResultSetContentValue } from '../../DatabaseDataModel/Actions/ResultSet/isResultSetContentValue'; import { ResultSetSelectAction } from '../../DatabaseDataModel/Actions/ResultSet/ResultSetSelectAction'; -import { useResultActions } from '../../DatabaseDataModel/Actions/ResultSet/useResultActions'; +import { useResultSetActions } from '../../DatabaseDataModel/Actions/ResultSet/useResultSetActions'; import type { IDatabaseResultSet } from '../../DatabaseDataModel/IDatabaseResultSet'; import type { IDataValuePanelProps } from '../../TableViewer/ValuePanel/DataValuePanelService'; import { QuotaPlaceholder } from '../QuotaPlaceholder'; @@ -55,18 +54,17 @@ export const TextValuePresentation: TabContainerPanelComponent getTypeExtension(contentType!) ?? [], [contentType]); const extensions = useCodemirrorExtensions(undefined, typeExtension); @@ -180,18 +178,24 @@ export const TextValuePresentation: TabContainerPanelComponent - {isTruncated && ( - - - - )} + {firstSelectedCell && contentAction.isTextTruncated(firstSelectedCell) ? ( + + {shouldShowPasteButton && ( + + + + )} + + ) : null} {canSave && ( @@ -204,13 +208,6 @@ export const TextValuePresentation: TabContainerPanelComponent - {shouldShowPasteButton && ( - - - - )} , ); diff --git a/webapp/packages/plugin-data-viewer/src/ValuePanelPresentation/TextValue/isTextValuePresentationAvailable.ts b/webapp/packages/plugin-data-viewer/src/ValuePanelPresentation/TextValue/isTextValuePresentationAvailable.ts index 00fa9e9bc8..578bacb05e 100644 --- a/webapp/packages/plugin-data-viewer/src/ValuePanelPresentation/TextValue/isTextValuePresentationAvailable.ts +++ b/webapp/packages/plugin-data-viewer/src/ValuePanelPresentation/TextValue/isTextValuePresentationAvailable.ts @@ -5,7 +5,7 @@ * Licensed under the Apache License, Version 2.0. * you may not use this file except in compliance with the License. */ -import { isResultSetBinaryFileValue } from '../../DatabaseDataModel/Actions/ResultSet/isResultSetBinaryFileValue'; +import { isResultSetBinaryValue } from '../../DatabaseDataModel/Actions/ResultSet/isResultSetBinaryValue'; import { isResultSetContentValue } from '../../DatabaseDataModel/Actions/ResultSet/isResultSetContentValue'; import { ResultSetSelectAction } from '../../DatabaseDataModel/Actions/ResultSet/ResultSetSelectAction'; import { ResultSetViewAction } from '../../DatabaseDataModel/Actions/ResultSet/ResultSetViewAction'; @@ -28,7 +28,7 @@ export function isBlobPresentationAvailable(context: IDataValuePanelProps; currentContentType: string; + elementKey?: IResultSetElementKey; } interface IUseTextValue { textValue: string; - isTruncated: boolean; isTextColumn: boolean; pasteFullText(): Promise; } -export function useTextValue({ model, resultIndex, currentContentType }: IUseTextValueArgs): IUseTextValue { - const { formatAction, editAction, contentAction, dataAction } = useResultActions({ model, resultIndex }); - const selection = model.source.getAction(resultIndex, ResultSetSelectAction); - const activeElements = selection.getActiveElements(); - const firstSelectedCell = activeElements?.[0]; +export function useTextValue({ model, resultIndex, currentContentType, elementKey }: IUseTextValueArgs): IUseTextValue { + const { formatAction, editAction, contentAction } = useResultSetActions({ model, resultIndex }); const formatter = useAutoFormat(); - const columnType = firstSelectedCell ? dataAction.getColumn(firstSelectedCell.column)?.dataKind : ''; - const isTextColumn = columnType?.toLocaleLowerCase() === 'string'; - const contentValue = firstSelectedCell ? formatAction.get(firstSelectedCell) : null; - const cachedFullText = firstSelectedCell ? contentAction.retrieveFileFullTextFromCache(firstSelectedCell) : ''; - const blob = firstSelectedCell ? formatAction.get(firstSelectedCell) : null; + const isTextColumn = elementKey ? formatAction.isText(elementKey) : false; + const contentValue = elementKey ? formatAction.get(elementKey) : null; + const isBinary = elementKey ? formatAction.isBinary(elementKey) : false; + const cachedFullText = elementKey ? contentAction.retrieveFileFullTextFromCache(elementKey) : ''; const notificationService = useService(NotificationService); const result: IUseTextValue = { textValue: '', - isTruncated: false, isTextColumn, async pasteFullText() { - if (!firstSelectedCell) { + if (!elementKey) { return; } try { - await contentAction.getFileFullText(firstSelectedCell); + await contentAction.getFileFullText(elementKey); } catch (exception) { notificationService.logException(exception as any, 'data_viewer_presentation_value_content_paste_error'); } }, }; - if (!isNotNullDefined(firstSelectedCell)) { + if (!isNotNullDefined(elementKey)) { return result; } - if (isResultSetContentValue(contentValue)) { - result.isTruncated = contentAction.isContentTruncated(contentValue); - } - if (isTextColumn && cachedFullText) { result.textValue = cachedFullText; - result.isTruncated = false; } - if (editAction.isElementEdited(firstSelectedCell)) { - result.textValue = formatAction.getText(firstSelectedCell); + if (editAction.isElementEdited(elementKey)) { + result.textValue = formatAction.getText(elementKey); } - if (isResultSetBinaryFileValue(blob)) { - const value = formatter.formatBlob(currentContentType, blob); + if (isBinary && isResultSetContentValue(contentValue)) { + const value = formatter.formatBlob(currentContentType, contentValue); if (value) { result.textValue = value; @@ -86,7 +75,7 @@ export function useTextValue({ model, resultIndex, currentContentType }: IUseTex } if (!result.textValue) { - result.textValue = formatter.format(currentContentType, formatAction.getText(firstSelectedCell)); + result.textValue = formatter.format(currentContentType, formatAction.getText(elementKey)); } return result; diff --git a/webapp/packages/plugin-data-viewer/src/index.ts b/webapp/packages/plugin-data-viewer/src/index.ts index cd93e62665..f42d855e6c 100644 --- a/webapp/packages/plugin-data-viewer/src/index.ts +++ b/webapp/packages/plugin-data-viewer/src/index.ts @@ -17,8 +17,8 @@ export * from './DatabaseDataModel/Actions/ResultSet/IResultSetComplexValue'; export * from './DatabaseDataModel/Actions/ResultSet/IResultSetFileValue'; export * from './DatabaseDataModel/Actions/ResultSet/IResultSetContentValue'; export * from './DatabaseDataModel/Actions/ResultSet/IResultSetGeometryValue'; -export * from './DatabaseDataModel/Actions/ResultSet/IResultSetBinaryFileValue'; -export * from './DatabaseDataModel/Actions/ResultSet/isResultSetBinaryFileValue'; +export * from './DatabaseDataModel/Actions/ResultSet/IResultSetBinaryValue'; +export * from './DatabaseDataModel/Actions/ResultSet/isResultSetBinaryValue'; export * from './DatabaseDataModel/Actions/ResultSet/isResultSetBlobValue'; export * from './DatabaseDataModel/Actions/ResultSet/isResultSetComplexValue'; export * from './DatabaseDataModel/Actions/ResultSet/isResultSetContentValue'; diff --git a/webapp/packages/plugin-data-viewer/src/locales/en.ts b/webapp/packages/plugin-data-viewer/src/locales/en.ts index 32151dc4ec..c60ea5c054 100644 --- a/webapp/packages/plugin-data-viewer/src/locales/en.ts +++ b/webapp/packages/plugin-data-viewer/src/locales/en.ts @@ -39,10 +39,8 @@ export default [ ['data_viewer_presentation_value_boolean_placeholder', "Can't show current value as boolean"], ['data_viewer_presentation_value_content_truncated_placeholder', 'The size of the value exceeds the'], ['data_viewer_presentation_value_content_was_truncated', 'The value was truncated'], - ['data_viewer_presentation_value_content_value_size', 'Value size'], ['data_viewer_presentation_value_content_download_error', 'Download failed'], ['data_viewer_presentation_value_content_paste_error', 'Cannot load full text'], - ['data_viewer_presentation_value_content_full_text_button', 'View full text'], ['data_viewer_script_preview', 'Script'], ['data_viewer_script_preview_dialog_title', 'Preview changes'], ['data_viewer_script_preview_error_title', "Can't get the script"], diff --git a/webapp/packages/plugin-data-viewer/src/locales/it.ts b/webapp/packages/plugin-data-viewer/src/locales/it.ts index f6fe83d731..a3c3507d82 100644 --- a/webapp/packages/plugin-data-viewer/src/locales/it.ts +++ b/webapp/packages/plugin-data-viewer/src/locales/it.ts @@ -35,10 +35,8 @@ export default [ ['data_viewer_presentation_value_boolean_placeholder', 'Non posso rappresentare il valore corrente come booleano'], ['data_viewer_presentation_value_content_truncated_placeholder', 'The size of the value exceeds the'], ['data_viewer_presentation_value_content_was_truncated', 'The value was truncated'], - ['data_viewer_presentation_value_content_value_size', 'Value size'], ['data_viewer_presentation_value_content_download_error', 'Download failed'], ['data_viewer_presentation_value_content_paste_error', 'Cannot load full text'], - ['data_viewer_presentation_value_content_full_text_button', 'View full text'], ['data_viewer_refresh_result_set', 'Refresh result set'], ['data_viewer_total_count_tooltip', 'Get total count'], ['data_viewer_total_count_failed', 'Failed to get total count'], diff --git a/webapp/packages/plugin-data-viewer/src/locales/ru.ts b/webapp/packages/plugin-data-viewer/src/locales/ru.ts index 14fd9bfed4..ee4b0ae5f3 100644 --- a/webapp/packages/plugin-data-viewer/src/locales/ru.ts +++ b/webapp/packages/plugin-data-viewer/src/locales/ru.ts @@ -33,10 +33,8 @@ export default [ ['data_viewer_presentation_value_boolean_placeholder', 'Не удалось отобразить текущее значение как boolean'], ['data_viewer_presentation_value_content_truncated_placeholder', 'Размер значения превышает'], ['data_viewer_presentation_value_content_was_truncated', 'Значение было обрезано'], - ['data_viewer_presentation_value_content_value_size', 'Размер значения'], ['data_viewer_presentation_value_content_download_error', 'Не удалось загрузить файл'], ['data_viewer_presentation_value_content_paste_error', 'Не удалось загрузить весь текст'], - ['data_viewer_presentation_value_content_full_text_button', 'Посмотреть весь текст'], ['data_viewer_script_preview', 'Скрипт'], ['data_viewer_script_preview_dialog_title', 'Предпросмотр изменений'], ['data_viewer_script_preview_error_title', 'Не удалось получить скрипт'], diff --git a/webapp/packages/plugin-data-viewer/src/locales/zh.ts b/webapp/packages/plugin-data-viewer/src/locales/zh.ts index 7a54e578aa..f069ac67db 100644 --- a/webapp/packages/plugin-data-viewer/src/locales/zh.ts +++ b/webapp/packages/plugin-data-viewer/src/locales/zh.ts @@ -39,10 +39,8 @@ export default [ ['data_viewer_presentation_value_boolean_placeholder', '无法将当前值显示为布尔值'], ['data_viewer_presentation_value_content_truncated_placeholder', 'The size of the value exceeds the'], ['data_viewer_presentation_value_content_was_truncated', 'The value was truncated'], - ['data_viewer_presentation_value_content_value_size', 'Value size'], ['data_viewer_presentation_value_content_download_error', 'Download failed'], ['data_viewer_presentation_value_content_paste_error', 'Cannot load full text'], - ['data_viewer_presentation_value_content_full_text_button', 'View full text'], ['data_viewer_script_preview', '脚本'], ['data_viewer_script_preview_dialog_title', '预览更改'], ['data_viewer_script_preview_error_title', '无法获取脚本'], From 426ab15bfc6b82a91fb44b781e92222f9078e9f2 Mon Sep 17 00:00:00 2001 From: alex <48489896+devnaumov@users.noreply.github.com> Date: Mon, 12 Feb 2024 11:06:40 +0100 Subject: [PATCH 4/5] CB-4651 change wrap lines icons (#2371) * CB-4651 change wrap lines icons * CB-4651 remove icons from icons.svg * CB-4651 add different size of icons --------- Co-authored-by: Daria Marutkina <125263541+dariamarutkina@users.noreply.github.com> --- .../public/icons/plugin_data_viewer_no_wrap_lines.svg | 1 + .../public/icons/plugin_data_viewer_no_wrap_lines_m.svg | 1 + .../public/icons/plugin_data_viewer_no_wrap_lines_sm.svg | 1 + .../public/icons/plugin_data_viewer_wrap_lines.svg | 1 + .../public/icons/plugin_data_viewer_wrap_lines_m.svg | 1 + .../public/icons/plugin_data_viewer_wrap_lines_sm.svg | 1 + .../ValuePanelPresentation/TextValue/TextValuePresentation.tsx | 3 ++- 7 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 webapp/packages/plugin-data-viewer/public/icons/plugin_data_viewer_no_wrap_lines.svg create mode 100644 webapp/packages/plugin-data-viewer/public/icons/plugin_data_viewer_no_wrap_lines_m.svg create mode 100644 webapp/packages/plugin-data-viewer/public/icons/plugin_data_viewer_no_wrap_lines_sm.svg create mode 100644 webapp/packages/plugin-data-viewer/public/icons/plugin_data_viewer_wrap_lines.svg create mode 100644 webapp/packages/plugin-data-viewer/public/icons/plugin_data_viewer_wrap_lines_m.svg create mode 100644 webapp/packages/plugin-data-viewer/public/icons/plugin_data_viewer_wrap_lines_sm.svg diff --git a/webapp/packages/plugin-data-viewer/public/icons/plugin_data_viewer_no_wrap_lines.svg b/webapp/packages/plugin-data-viewer/public/icons/plugin_data_viewer_no_wrap_lines.svg new file mode 100644 index 0000000000..a77c6a1842 --- /dev/null +++ b/webapp/packages/plugin-data-viewer/public/icons/plugin_data_viewer_no_wrap_lines.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/webapp/packages/plugin-data-viewer/public/icons/plugin_data_viewer_no_wrap_lines_m.svg b/webapp/packages/plugin-data-viewer/public/icons/plugin_data_viewer_no_wrap_lines_m.svg new file mode 100644 index 0000000000..2ec1cb24fc --- /dev/null +++ b/webapp/packages/plugin-data-viewer/public/icons/plugin_data_viewer_no_wrap_lines_m.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/webapp/packages/plugin-data-viewer/public/icons/plugin_data_viewer_no_wrap_lines_sm.svg b/webapp/packages/plugin-data-viewer/public/icons/plugin_data_viewer_no_wrap_lines_sm.svg new file mode 100644 index 0000000000..4fcbcc1ca0 --- /dev/null +++ b/webapp/packages/plugin-data-viewer/public/icons/plugin_data_viewer_no_wrap_lines_sm.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/webapp/packages/plugin-data-viewer/public/icons/plugin_data_viewer_wrap_lines.svg b/webapp/packages/plugin-data-viewer/public/icons/plugin_data_viewer_wrap_lines.svg new file mode 100644 index 0000000000..41d9b8da64 --- /dev/null +++ b/webapp/packages/plugin-data-viewer/public/icons/plugin_data_viewer_wrap_lines.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/webapp/packages/plugin-data-viewer/public/icons/plugin_data_viewer_wrap_lines_m.svg b/webapp/packages/plugin-data-viewer/public/icons/plugin_data_viewer_wrap_lines_m.svg new file mode 100644 index 0000000000..9e2189fbd0 --- /dev/null +++ b/webapp/packages/plugin-data-viewer/public/icons/plugin_data_viewer_wrap_lines_m.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/webapp/packages/plugin-data-viewer/public/icons/plugin_data_viewer_wrap_lines_sm.svg b/webapp/packages/plugin-data-viewer/public/icons/plugin_data_viewer_wrap_lines_sm.svg new file mode 100644 index 0000000000..cfa247bac6 --- /dev/null +++ b/webapp/packages/plugin-data-viewer/public/icons/plugin_data_viewer_wrap_lines_sm.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/webapp/packages/plugin-data-viewer/src/ValuePanelPresentation/TextValue/TextValuePresentation.tsx b/webapp/packages/plugin-data-viewer/src/ValuePanelPresentation/TextValue/TextValuePresentation.tsx index 739402f509..187e35475b 100644 --- a/webapp/packages/plugin-data-viewer/src/ValuePanelPresentation/TextValue/TextValuePresentation.tsx +++ b/webapp/packages/plugin-data-viewer/src/ValuePanelPresentation/TextValue/TextValuePresentation.tsx @@ -204,7 +204,8 @@ export const TextValuePresentation: TabContainerPanelComponent From 78cbc6d3f24123dd3864c3cc1fd302022cea94fd Mon Sep 17 00:00:00 2001 From: naumov Date: Mon, 12 Feb 2024 13:55:05 +0100 Subject: [PATCH 5/5] CB-4457 remove extra check --- .../DatabaseDataModel/Actions/Document/DocumentDataAction.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webapp/packages/plugin-data-viewer/src/DatabaseDataModel/Actions/Document/DocumentDataAction.ts b/webapp/packages/plugin-data-viewer/src/DatabaseDataModel/Actions/Document/DocumentDataAction.ts index c580623465..515b013c27 100644 --- a/webapp/packages/plugin-data-viewer/src/DatabaseDataModel/Actions/Document/DocumentDataAction.ts +++ b/webapp/packages/plugin-data-viewer/src/DatabaseDataModel/Actions/Document/DocumentDataAction.ts @@ -21,7 +21,7 @@ export class DocumentDataAction extends DatabaseDataResultAction row.data?.[0]) || []; + return this.result.data?.rowsWithMetaData?.map(row => row.data[0]) || []; } get count(): number {