From 46e44ad317137f6a281910c7a9892cf6e795da50 Mon Sep 17 00:00:00 2001 From: Vladimir Lewandowski Date: Thu, 29 Feb 2024 15:36:57 +0100 Subject: [PATCH 1/7] feat: add binary data in plain text display --- src/containers/UserSettings/Setting.tsx | 3 +++ src/containers/UserSettings/i18n/en.json | 3 +++ src/containers/UserSettings/i18n/ru.json | 3 +++ src/containers/UserSettings/settings.ts | 13 ++++++++++++- src/services/api.ts | 11 ++++++++++- src/services/settings.ts | 2 ++ src/utils/constants.ts | 1 + 7 files changed, 34 insertions(+), 2 deletions(-) diff --git a/src/containers/UserSettings/Setting.tsx b/src/containers/UserSettings/Setting.tsx index 7518ccf08b..a2d2327ace 100644 --- a/src/containers/UserSettings/Setting.tsx +++ b/src/containers/UserSettings/Setting.tsx @@ -14,6 +14,7 @@ export type SettingsElementType = 'switch' | 'radio'; export interface SettingProps { type?: SettingsElementType; title: string; + description?: ReactNode; settingKey: string; helpPopoverContent?: ReactNode; options?: {value: string; content: string}[]; @@ -25,6 +26,7 @@ export const Setting = ({ type = 'switch', settingKey, title, + description, helpPopoverContent, options, defaultValue, @@ -85,6 +87,7 @@ export const Setting = ({ {getSettingsElement(type)} diff --git a/src/containers/UserSettings/i18n/en.json b/src/containers/UserSettings/i18n/en.json index c4b534e68a..15e92ee57f 100644 --- a/src/containers/UserSettings/i18n/en.json +++ b/src/containers/UserSettings/i18n/en.json @@ -14,6 +14,9 @@ "settings.language.option-russian": "Russian", "settings.language.option-english": "English", + "settings.binaryDataInPlainTextDisplay.title": "Display binary data in plain text", + "settings.binaryDataInPlainTextDisplay.description": "Available starting from version 24.1", + "settings.invertedDisks.title": "Inverted disks space indicators", "settings.useNodesEndpoint.title": "Break the Nodes tab in Diagnostics", diff --git a/src/containers/UserSettings/i18n/ru.json b/src/containers/UserSettings/i18n/ru.json index 1e5666d953..f7dee33071 100644 --- a/src/containers/UserSettings/i18n/ru.json +++ b/src/containers/UserSettings/i18n/ru.json @@ -14,6 +14,9 @@ "settings.language.option-russian": "Русский", "settings.language.option-english": "English", + "settings.binaryDataInPlainTextDisplay.title": "Отображение двоичных данных в виде обычного текста", + "settings.binaryDataInPlainTextDisplay.description": "Доступно, начиная с версии 24.1", + "settings.invertedDisks.title": "Инвертированные индикаторы места на дисках", "settings.useNodesEndpoint.title": "Сломать вкладку Nodes в диагностике", diff --git a/src/containers/UserSettings/settings.ts b/src/containers/UserSettings/settings.ts index aeddfbf5c6..d7cf455842 100644 --- a/src/containers/UserSettings/settings.ts +++ b/src/containers/UserSettings/settings.ts @@ -10,6 +10,7 @@ import { USE_BACKEND_PARAMS_FOR_TABLES_KEY, USE_NODES_ENDPOINT_IN_DIAGNOSTICS_KEY, QUERY_USE_MULTI_SCHEMA_KEY, + BINARY_DATA_IN_PLAIN_TEXT_DISPLAY, } from '../../utils/constants'; import {Lang, defaultLang} from '../../utils/i18n'; @@ -75,6 +76,16 @@ export const languageSetting: SettingProps = { }, }; +export const binaryDataInPlainTextDisplay: SettingProps = { + settingKey: BINARY_DATA_IN_PLAIN_TEXT_DISPLAY, + title: i18n('settings.binaryDataInPlainTextDisplay.title'), + description: + process.env.REACT_APP_META_BACKEND === undefined || + process.env.REACT_APP_META_BACKEND === 'undefined' + ? undefined + : i18n('settings.binaryDataInPlainTextDisplay.description'), +}; + export const invertedDisksSetting: SettingProps = { settingKey: INVERTED_DISKS_KEY, title: i18n('settings.invertedDisks.title'), @@ -98,7 +109,7 @@ export const queryUseMultiSchemaSetting: SettingProps = { export const appearanceSection: SettingsSection = { id: 'appearanceSection', title: i18n('section.appearance'), - settings: [themeSetting, invertedDisksSetting], + settings: [themeSetting, invertedDisksSetting, binaryDataInPlainTextDisplay], }; export const experimentsSection: SettingsSection = { id: 'experimentsSection', diff --git a/src/services/api.ts b/src/services/api.ts index 7645b36d20..4d0080b77d 100644 --- a/src/services/api.ts +++ b/src/services/api.ts @@ -40,6 +40,8 @@ import {backend as BACKEND, metaBackend as META_BACKEND} from '../store'; import {prepareSortValue} from '../utils/filters'; import {parseMetaCluster} from './parsers/parseMetaCluster'; import {parseMetaTenants} from './parsers/parseMetaTenants'; +import {settingsManager} from './settings'; +import {BINARY_DATA_IN_PLAIN_TEXT_DISPLAY} from '../lib'; type AxiosOptions = { concurrentId?: string; @@ -305,9 +307,16 @@ export class YdbEmbeddedAPI extends AxiosWrapper { const uiTimeout = 9 * 60 * 1000; const backendTimeout = 10 * 60 * 1000; + const base64 = !settingsManager.readUserSettingsValue( + BINARY_DATA_IN_PLAIN_TEXT_DISPLAY, + true, + ); + return this.post>( this.getPath( - `/viewer/json/query?timeout=${backendTimeout}${schema ? `&schema=${schema}` : ''}`, + `/viewer/json/query?timeout=${backendTimeout}&base64=${base64}${ + schema ? `&schema=${schema}` : '' + }`, ), params, {}, diff --git a/src/services/settings.ts b/src/services/settings.ts index 4c6ac4007e..824e0ffce0 100644 --- a/src/services/settings.ts +++ b/src/services/settings.ts @@ -14,6 +14,7 @@ import { USE_BACKEND_PARAMS_FOR_TABLES_KEY, USE_NODES_ENDPOINT_IN_DIAGNOSTICS_KEY, USE_CLUSTER_BALANCER_AS_BACKEND_KEY, + BINARY_DATA_IN_PLAIN_TEXT_DISPLAY, } from '../utils/constants'; import {QUERY_ACTIONS, QUERY_MODES} from '../utils/query'; import {parseJson} from '../utils/utils'; @@ -27,6 +28,7 @@ export const DEFAULT_USER_SETTINGS: SettingsObject = { [INVERTED_DISKS_KEY]: false, [USE_NODES_ENDPOINT_IN_DIAGNOSTICS_KEY]: false, [QUERY_USE_MULTI_SCHEMA_KEY]: false, + [BINARY_DATA_IN_PLAIN_TEXT_DISPLAY]: true, [SAVED_QUERIES_KEY]: [], [TENANT_INITIAL_PAGE_KEY]: TENANT_PAGES_IDS.query, [QUERY_INITIAL_MODE_KEY]: QUERY_MODES.script, diff --git a/src/utils/constants.ts b/src/utils/constants.ts index c851be7b60..bb7e31f955 100644 --- a/src/utils/constants.ts +++ b/src/utils/constants.ts @@ -87,6 +87,7 @@ export const SAVED_QUERIES_KEY = 'saved_queries'; export const ASIDE_HEADER_COMPACT_KEY = 'asideHeaderCompact'; export const QUERIES_HISTORY_KEY = 'queries_history'; export const DATA_QA_TUNE_COLUMNS_POPUP = 'tune-columns-popup'; +export const BINARY_DATA_IN_PLAIN_TEXT_DISPLAY = 'binaryDataInPlainTextDisplay'; export const DEFAULT_SIZE_RESULT_PANE_KEY = 'default-size-result-pane'; export const DEFAULT_SIZE_TENANT_SUMMARY_KEY = 'default-size-tenant-summary-pane'; From c43a4f9e27fb1e3bbcf1d2c6b338fce744dfad7f Mon Sep 17 00:00:00 2001 From: Vladimir Lewandowski Date: Mon, 4 Mar 2024 12:01:30 +0100 Subject: [PATCH 2/7] fix: import path --- src/services/api.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/services/api.ts b/src/services/api.ts index 4d0080b77d..9fc4dfae9b 100644 --- a/src/services/api.ts +++ b/src/services/api.ts @@ -38,10 +38,10 @@ import type {JsonHotKeysResponse} from '../types/api/hotkeys'; import {backend as BACKEND, metaBackend as META_BACKEND} from '../store'; import {prepareSortValue} from '../utils/filters'; +import {BINARY_DATA_IN_PLAIN_TEXT_DISPLAY} from '../utils/constants'; import {parseMetaCluster} from './parsers/parseMetaCluster'; import {parseMetaTenants} from './parsers/parseMetaTenants'; import {settingsManager} from './settings'; -import {BINARY_DATA_IN_PLAIN_TEXT_DISPLAY} from '../lib'; type AxiosOptions = { concurrentId?: string; From 711688c6fcc7d9d3e972cc61ae54bd3665b5360a Mon Sep 17 00:00:00 2001 From: Vladimir Lewandowski Date: Mon, 4 Mar 2024 12:13:57 +0100 Subject: [PATCH 3/7] feat: add `ClusterModeGuard` to hide/show elements depending on cluster mode --- .../ClusterModeGuard/ClusterModeGuard.tsx | 14 ++++++++++++++ src/containers/ClusterModeGuard/index.ts | 1 + .../UserSettings/{settings.ts => settings.tsx} | 11 ++++++----- 3 files changed, 21 insertions(+), 5 deletions(-) create mode 100644 src/containers/ClusterModeGuard/ClusterModeGuard.tsx create mode 100644 src/containers/ClusterModeGuard/index.ts rename src/containers/UserSettings/{settings.ts => settings.tsx} (94%) diff --git a/src/containers/ClusterModeGuard/ClusterModeGuard.tsx b/src/containers/ClusterModeGuard/ClusterModeGuard.tsx new file mode 100644 index 0000000000..bbde293c64 --- /dev/null +++ b/src/containers/ClusterModeGuard/ClusterModeGuard.tsx @@ -0,0 +1,14 @@ +import {ReactNode, FC, ReactElement} from 'react'; +import {useTypedSelector} from '../../lib'; + +export interface ClusterModeGuardProps { + children: ReactNode; + mode: 'single' | 'multi'; +} + +export const ClusterModeGuard: FC = ({children, mode}) => + useTypedSelector((state) => + mode === 'single' ? state.singleClusterMode : !state.singleClusterMode, + ) + ? (children as ReactElement) + : null; diff --git a/src/containers/ClusterModeGuard/index.ts b/src/containers/ClusterModeGuard/index.ts new file mode 100644 index 0000000000..87ad7750c3 --- /dev/null +++ b/src/containers/ClusterModeGuard/index.ts @@ -0,0 +1 @@ +export * from './ClusterModeGuard'; diff --git a/src/containers/UserSettings/settings.ts b/src/containers/UserSettings/settings.tsx similarity index 94% rename from src/containers/UserSettings/settings.ts rename to src/containers/UserSettings/settings.tsx index d7cf455842..7ee510d241 100644 --- a/src/containers/UserSettings/settings.ts +++ b/src/containers/UserSettings/settings.tsx @@ -16,6 +16,7 @@ import {Lang, defaultLang} from '../../utils/i18n'; import type {SettingProps} from './Setting'; import i18n from './i18n'; +import {ClusterModeGuard} from '../ClusterModeGuard'; export interface SettingsSection { id: string; @@ -79,11 +80,11 @@ export const languageSetting: SettingProps = { export const binaryDataInPlainTextDisplay: SettingProps = { settingKey: BINARY_DATA_IN_PLAIN_TEXT_DISPLAY, title: i18n('settings.binaryDataInPlainTextDisplay.title'), - description: - process.env.REACT_APP_META_BACKEND === undefined || - process.env.REACT_APP_META_BACKEND === 'undefined' - ? undefined - : i18n('settings.binaryDataInPlainTextDisplay.description'), + description: ( + + {i18n('settings.binaryDataInPlainTextDisplay.description')} + + ), }; export const invertedDisksSetting: SettingProps = { From fe4df0cec41596550a0cc83ad68ee60856a447ff Mon Sep 17 00:00:00 2001 From: Vladimir Lewandowski Date: Mon, 4 Mar 2024 12:19:51 +0100 Subject: [PATCH 4/7] feat: remove `ru` language in settings --- src/containers/UserSettings/i18n/index.ts | 10 ++------ src/containers/UserSettings/i18n/ru.json | 30 ----------------------- 2 files changed, 2 insertions(+), 38 deletions(-) delete mode 100644 src/containers/UserSettings/i18n/ru.json diff --git a/src/containers/UserSettings/i18n/index.ts b/src/containers/UserSettings/i18n/index.ts index 80be0ac86c..a40f2e749f 100644 --- a/src/containers/UserSettings/i18n/index.ts +++ b/src/containers/UserSettings/i18n/index.ts @@ -1,11 +1,5 @@ -import {i18n, Lang} from '../../../utils/i18n'; +import {registerKeysets} from '../../../utils/i18n'; import en from './en.json'; -import ru from './ru.json'; -const COMPONENT = 'ydb-user-settings'; - -i18n.registerKeyset(Lang.En, COMPONENT, en); -i18n.registerKeyset(Lang.Ru, COMPONENT, ru); - -export default i18n.keyset(COMPONENT); +export default registerKeysets('ydb-user-settings', {en}); diff --git a/src/containers/UserSettings/i18n/ru.json b/src/containers/UserSettings/i18n/ru.json deleted file mode 100644 index f7dee33071..0000000000 --- a/src/containers/UserSettings/i18n/ru.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "page.general": "Общие", - "section.appearance": "Внешний вид", - - "page.experiments": "Эксперименты", - "section.experiments": "Эксперименты", - - "settings.theme.title": "Тема", - "settings.theme.option-dark": "Тёмная", - "settings.theme.option-light": "Светлая", - "settings.theme.option-system": "Системная", - - "settings.language.title": "Язык интерфейса", - "settings.language.option-russian": "Русский", - "settings.language.option-english": "English", - - "settings.binaryDataInPlainTextDisplay.title": "Отображение двоичных данных в виде обычного текста", - "settings.binaryDataInPlainTextDisplay.description": "Доступно, начиная с версии 24.1", - - "settings.invertedDisks.title": "Инвертированные индикаторы места на дисках", - - "settings.useNodesEndpoint.title": "Сломать вкладку Nodes в диагностике", - "settings.useNodesEndpoint.popover": "Использовать эндпоинт /viewer/json/nodes для вкладки Nodes в диагностике. Может возвращать некорректные данные на некоторых версиях", - - "settings.useVirtualTables.title": "Использовать таблицу с загрузкой данных по скроллу для вкладок Nodes и Storage", - "settings.useVirtualTables.popover": "Это улучшит производительность, но может работать нестабильно", - - "settings.queryUseMultiSchema.title": "Разрешить запросы с несколькими результатами", - "settings.queryUseMultiSchema.popover": "Использовать для запросов схему 'multi', которая позволяет выполнять запросы с несколькими результатами. На версиях 23-3 и старше результат не возвращается вообще" -} From 43c21b7e1e28a02e4769d72c134bb89ea17dab4b Mon Sep 17 00:00:00 2001 From: Vladimir Lewandowski Date: Mon, 4 Mar 2024 12:24:41 +0100 Subject: [PATCH 5/7] fix: add comment to `base64` param --- src/services/api.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/services/api.ts b/src/services/api.ts index 9fc4dfae9b..3ebe39088d 100644 --- a/src/services/api.ts +++ b/src/services/api.ts @@ -307,6 +307,10 @@ export class YdbEmbeddedAPI extends AxiosWrapper { const uiTimeout = 9 * 60 * 1000; const backendTimeout = 10 * 60 * 1000; + /** + * Return strings using base64 encoding. + * @link https://github.com/ydb-platform/ydb/pull/647 + */ const base64 = !settingsManager.readUserSettingsValue( BINARY_DATA_IN_PLAIN_TEXT_DISPLAY, true, From 3c62d54e8971c1dcb1e2f63a98b4c608742d22e5 Mon Sep 17 00:00:00 2001 From: Vladimir Lewandowski Date: Mon, 4 Mar 2024 15:43:35 +0100 Subject: [PATCH 6/7] fix: import path Co-authored-by: Valerii Sidorenko --- src/containers/ClusterModeGuard/ClusterModeGuard.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/containers/ClusterModeGuard/ClusterModeGuard.tsx b/src/containers/ClusterModeGuard/ClusterModeGuard.tsx index bbde293c64..fd3909f446 100644 --- a/src/containers/ClusterModeGuard/ClusterModeGuard.tsx +++ b/src/containers/ClusterModeGuard/ClusterModeGuard.tsx @@ -1,5 +1,5 @@ import {ReactNode, FC, ReactElement} from 'react'; -import {useTypedSelector} from '../../lib'; +import {useTypedSelector} from '../../utils/hooks'; export interface ClusterModeGuardProps { children: ReactNode; From 66eade8f99cbe31941d8f187ef57842e6df76d4f Mon Sep 17 00:00:00 2001 From: Vladimir Lewandowski Date: Mon, 4 Mar 2024 15:48:07 +0100 Subject: [PATCH 7/7] style: fix code style in `ClusterModeGuard` to make Valera feel good --- .../ClusterModeGuard/ClusterModeGuard.tsx | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/containers/ClusterModeGuard/ClusterModeGuard.tsx b/src/containers/ClusterModeGuard/ClusterModeGuard.tsx index fd3909f446..f3cd9ca613 100644 --- a/src/containers/ClusterModeGuard/ClusterModeGuard.tsx +++ b/src/containers/ClusterModeGuard/ClusterModeGuard.tsx @@ -1,14 +1,15 @@ -import {ReactNode, FC, ReactElement} from 'react'; -import {useTypedSelector} from '../../utils/hooks'; +import {ReactNode} from 'react'; +import {useTypedSelector} from '../../lib'; export interface ClusterModeGuardProps { children: ReactNode; mode: 'single' | 'multi'; } -export const ClusterModeGuard: FC = ({children, mode}) => - useTypedSelector((state) => +export function ClusterModeGuard({children, mode}: ClusterModeGuardProps) { + const shouldRender = useTypedSelector((state) => mode === 'single' ? state.singleClusterMode : !state.singleClusterMode, - ) - ? (children as ReactElement) - : null; + ); + + return shouldRender ? <>{children} : null; +}