diff --git a/webapp/packages/plugin-log-viewer/src/LogViewer/LogViewerTable.module.css b/webapp/packages/plugin-log-viewer/src/LogViewer/LogViewerTable.module.css
index 3d000a41c9..f18e965c6f 100644
--- a/webapp/packages/plugin-log-viewer/src/LogViewer/LogViewerTable.module.css
+++ b/webapp/packages/plugin-log-viewer/src/LogViewer/LogViewerTable.module.css
@@ -42,11 +42,4 @@
.timestamp {
width: 116px;
min-width: 116px;
-}
-
-.clearButton {
- position: absolute !important;
- top: 4px;
- right: 16px;
- z-index: 100;
-}
+}
\ No newline at end of file
diff --git a/webapp/packages/plugin-log-viewer/src/LogViewer/LogViewerTable.tsx b/webapp/packages/plugin-log-viewer/src/LogViewer/LogViewerTable.tsx
index 587b7be20d..4fb754cdcb 100644
--- a/webapp/packages/plugin-log-viewer/src/LogViewer/LogViewerTable.tsx
+++ b/webapp/packages/plugin-log-viewer/src/LogViewer/LogViewerTable.tsx
@@ -7,7 +7,8 @@
*/
import { observer } from 'mobx-react-lite';
-import { Container, MenuBarSmallItem, s, Table, TableBody, TableColumnHeader, TableHeader, useS, useTranslate } from '@cloudbeaver/core-blocks';
+import { Container, Icon, s, Table, TableBody, TableColumnHeader, TableHeader, useS, useTranslate } from '@cloudbeaver/core-blocks';
+import { Button, ButtonIcon } from '@dbeaver/ui-kit';
import type { ILogEntry } from './ILogEntry.js';
import { LogEntry } from './LogEntry.js';
@@ -26,15 +27,18 @@ export const LogViewerTable = observer
(function LogViewerTable({ items, s
return (
-
+
+
+
{translate('ui_clear')}
-
+
diff --git a/webapp/packages/plugin-log-viewer/tsconfig.json b/webapp/packages/plugin-log-viewer/tsconfig.json
index 35f4c3fb84..f6812f382d 100644
--- a/webapp/packages/plugin-log-viewer/tsconfig.json
+++ b/webapp/packages/plugin-log-viewer/tsconfig.json
@@ -10,6 +10,9 @@
{
"path": "../../common-react/@dbeaver/react-tests"
},
+ {
+ "path": "../../common-react/@dbeaver/ui-kit"
+ },
{
"path": "../../common-typescript/@dbeaver/cli"
},
diff --git a/webapp/packages/plugin-object-viewer/package.json b/webapp/packages/plugin-object-viewer/package.json
index 14b8772d6c..30cddb3ba2 100644
--- a/webapp/packages/plugin-object-viewer/package.json
+++ b/webapp/packages/plugin-object-viewer/package.json
@@ -46,7 +46,6 @@
"mobx-react-lite": "^4",
"react": "^19",
"react-dom": "^19",
- "reakit": "^1",
"tslib": "^2"
},
"devDependencies": {
diff --git a/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/FolderContext.ts b/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/FolderContext.ts
deleted file mode 100644
index cb4f3f272a..0000000000
--- a/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/FolderContext.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-/*
- * 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 { createContext } from 'react';
-import type { TabStateReturn } from 'reakit';
-
-export const FolderContext = createContext(undefined);
diff --git a/webapp/packages/plugin-sql-editor-new/src/SQLEditor/SQLCodeEditorPanel/SQLCodeEditorPanel.tsx b/webapp/packages/plugin-sql-editor-new/src/SQLEditor/SQLCodeEditorPanel/SQLCodeEditorPanel.tsx
index 0e70e575ab..7d64688899 100644
--- a/webapp/packages/plugin-sql-editor-new/src/SQLEditor/SQLCodeEditorPanel/SQLCodeEditorPanel.tsx
+++ b/webapp/packages/plugin-sql-editor-new/src/SQLEditor/SQLCodeEditorPanel/SQLCodeEditorPanel.tsx
@@ -8,7 +8,7 @@
import { observer } from 'mobx-react-lite';
import { useState } from 'react';
-import { MenuBarSmallItem, useExecutor, useS, useTranslate } from '@cloudbeaver/core-blocks';
+import { Button, useExecutor, useS, useTranslate } from '@cloudbeaver/core-blocks';
import { useService } from '@cloudbeaver/core-di';
import { NotificationService } from '@cloudbeaver/core-events';
import { DATA_CONTEXT_NAV_NODE, getNodesFromContext, NavNodeManagerService } from '@cloudbeaver/core-navigation-tree';
@@ -129,14 +129,24 @@ export const SQLCodeEditorPanel: TabContainerPanelComponent
{data.isIncomingChanges && (
<>
-
+
+
-
+
+
>
)}
diff --git a/webapp/yarn.lock b/webapp/yarn.lock
index af485d524b..b2d82bef4e 100644
--- a/webapp/yarn.lock
+++ b/webapp/yarn.lock
@@ -1482,8 +1482,6 @@ __metadata:
react-dom: "npm:^19"
react-hotkeys-hook: "npm:5.1.0"
react-minisearch: "npm:^7"
- reakit: "npm:^1"
- reakit-utils: "npm:^0"
rimraf: "npm:^6"
subscript: "npm:^9"
tslib: "npm:^2"
@@ -1826,12 +1824,12 @@ __metadata:
"@cloudbeaver/core-di": "workspace:*"
"@cloudbeaver/core-events": "workspace:*"
"@cloudbeaver/tsconfig": "workspace:*"
+ "@dbeaver/ui-kit": "workspace:^"
"@types/react": "npm:^19"
mobx: "npm:^6"
mobx-react-lite: "npm:^4"
react: "npm:^19"
react-dom: "npm:^19"
- reakit: "npm:^1"
rimraf: "npm:^6"
tslib: "npm:^2"
typescript: "npm:^5"
@@ -2246,7 +2244,6 @@ __metadata:
react-dnd: "npm:^16"
react-dnd-html5-backend: "npm:^16"
react-dom: "npm:^19"
- reakit: "npm:^1"
rimraf: "npm:^6"
tslib: "npm:^2"
typescript: "npm:^5"
@@ -2519,7 +2516,6 @@ __metadata:
mobx-react-lite: "npm:^4"
react: "npm:^19"
react-dom: "npm:^19"
- reakit: "npm:^1"
rimraf: "npm:^6"
tslib: "npm:^2"
typescript: "npm:^5"
@@ -3076,6 +3072,7 @@ __metadata:
"@cloudbeaver/plugin-data-viewer": "workspace:*"
"@cloudbeaver/plugin-sql-editor": "workspace:*"
"@cloudbeaver/tsconfig": "workspace:*"
+ "@dbeaver/ui-kit": "workspace:*"
"@types/react": "npm:^19"
mobx: "npm:^6"
mobx-react-lite: "npm:^4"
@@ -3433,6 +3430,7 @@ __metadata:
"@cloudbeaver/tsconfig": "workspace:*"
"@dbeaver/cli": "workspace:*"
"@dbeaver/react-tests": "workspace:*"
+ "@dbeaver/ui-kit": "workspace:^"
"@types/react": "npm:^19"
mobx: "npm:^6"
mobx-react-lite: "npm:^4"
@@ -3636,7 +3634,6 @@ __metadata:
mobx-react-lite: "npm:^4"
react: "npm:^19"
react-dom: "npm:^19"
- reakit: "npm:^1"
rimraf: "npm:^6"
tslib: "npm:^2"
typescript: "npm:^5"
@@ -7460,13 +7457,6 @@ __metadata:
languageName: node
linkType: hard
-"@popperjs/core@npm:^2.5.4":
- version: 2.11.8
- resolution: "@popperjs/core@npm:2.11.8"
- checksum: 10c0/4681e682abc006d25eb380d0cf3efc7557043f53b6aea7a5057d0d1e7df849a00e281cd8ea79c902a35a414d7919621fc2ba293ecec05f413598e0b23d5a1e63
- languageName: node
- linkType: hard
-
"@react-dnd/asap@npm:^5.0.1":
version: 5.0.2
resolution: "@react-dnd/asap@npm:5.0.2"
@@ -10058,13 +10048,6 @@ __metadata:
languageName: node
linkType: hard
-"body-scroll-lock@npm:^3.1.5":
- version: 3.1.5
- resolution: "body-scroll-lock@npm:3.1.5"
- checksum: 10c0/657c948d64ffe17d2c89958f57c2c636203cf5216e3ba33ad76604bf1b5144fd8f4b5d832d09105f8782d5b8bc96f38780331ec55f3af5f27694dff38a0cc9d7
- languageName: node
- linkType: hard
-
"boolbase@npm:^1.0.0":
version: 1.0.0
resolution: "boolbase@npm:1.0.0"
@@ -10570,7 +10553,6 @@ __metadata:
prettier: "npm:^3.6.2"
react: "npm:^19"
react-dom: "npm:^19"
- reakit: "npm:^1"
rimraf: "npm:^6"
typescript: "npm:^5.8.3"
typescript-plugin-css-modules: "npm:^5"
@@ -17066,55 +17048,6 @@ __metadata:
languageName: node
linkType: hard
-"reakit-system@npm:^0.15.2":
- version: 0.15.2
- resolution: "reakit-system@npm:0.15.2"
- dependencies:
- reakit-utils: "npm:^0.15.2"
- peerDependencies:
- react: ^16.8.0 || ^17.0.0
- react-dom: ^16.8.0 || ^17.0.0
- checksum: 10c0/bd97e297b972e205656dd99a6955ed263d5102ab24212e55b90a86dd9a4eac056b63ba882af65705036922e9cb599d5903318d1202086a3e4ee45b5cc794d44e
- languageName: node
- linkType: hard
-
-"reakit-utils@npm:^0, reakit-utils@npm:^0.15.2":
- version: 0.15.2
- resolution: "reakit-utils@npm:0.15.2"
- peerDependencies:
- react: ^16.8.0 || ^17.0.0
- react-dom: ^16.8.0 || ^17.0.0
- checksum: 10c0/258654f9510fb7622fc03f81a63021721ace6c424bdff47a8f79e3b974501ef6b1b44fdb78ab01ed1a75d3fd6867d100e97ef74138c0d848c2aa5738477bf853
- languageName: node
- linkType: hard
-
-"reakit-warning@npm:^0.6.2":
- version: 0.6.2
- resolution: "reakit-warning@npm:0.6.2"
- dependencies:
- reakit-utils: "npm:^0.15.2"
- peerDependencies:
- react: ^16.8.0 || ^17.0.0
- checksum: 10c0/e93856e9dd4b56e7cd36cd654cb5688eb05fc8f75e3d89069352bc61ab6f6cf501892405dd1612442e45880562048af5c17b3e771fd6af79348bc90a20f8d930
- languageName: node
- linkType: hard
-
-"reakit@npm:^1":
- version: 1.3.11
- resolution: "reakit@npm:1.3.11"
- dependencies:
- "@popperjs/core": "npm:^2.5.4"
- body-scroll-lock: "npm:^3.1.5"
- reakit-system: "npm:^0.15.2"
- reakit-utils: "npm:^0.15.2"
- reakit-warning: "npm:^0.6.2"
- peerDependencies:
- react: ^16.8.0 || ^17.0.0
- react-dom: ^16.8.0 || ^17.0.0
- checksum: 10c0/ce5972b1242bd0704840c77faa6f687cc3bd0e66ac5f6fe84328408d2e624a4532c4bb1d82b6b6dcbc876dc0700c472b420acebf80603d59115a810ae8916e12
- languageName: node
- linkType: hard
-
"recast@npm:^0.23.5":
version: 0.23.11
resolution: "recast@npm:0.23.11"
From df676913a0c3044717d333073d216a0783bb2f55 Mon Sep 17 00:00:00 2001
From: Sychev Andrey <44414066+SychevAndrey@users.noreply.github.com>
Date: Fri, 27 Mar 2026 14:22:14 +0100
Subject: [PATCH 2/4] dbeaver/pro#8808 feat: add shortcut for search in data
viewer (#4239)
* dbeaver/pro#8808 feat: add shortcut for search in data viewer
* dbeaver/pro#8808 feat: update shortcut ID for search functionality
---
.../plugin-help/src/Shortcuts/SHORTCUTS_DATA.ts | 12 ++++++++----
webapp/packages/plugin-help/src/locales/en.ts | 5 +++--
webapp/packages/plugin-help/src/locales/fr.ts | 4 ++--
webapp/packages/plugin-help/src/locales/it.ts | 2 +-
webapp/packages/plugin-help/src/locales/ru.ts | 2 +-
webapp/packages/plugin-help/src/locales/vi.ts | 2 +-
webapp/packages/plugin-help/src/locales/zh.ts | 2 +-
7 files changed, 17 insertions(+), 12 deletions(-)
diff --git a/webapp/packages/plugin-help/src/Shortcuts/SHORTCUTS_DATA.ts b/webapp/packages/plugin-help/src/Shortcuts/SHORTCUTS_DATA.ts
index 043ec7b998..20fb2c74c7 100644
--- a/webapp/packages/plugin-help/src/Shortcuts/SHORTCUTS_DATA.ts
+++ b/webapp/packages/plugin-help/src/Shortcuts/SHORTCUTS_DATA.ts
@@ -33,8 +33,8 @@ const KEY_BINDING_SQL_EDITOR_COMMENT = createKeyBinding({
keys: ['mod+/'],
});
-const KEY_BINDING_SQL_EDITOR_FIND = createKeyBinding({
- id: 'sql-editor-find',
+const KEY_BINDING_FIND = createKeyBinding({
+ id: 'find',
keys: ['mod+f'],
});
@@ -57,6 +57,10 @@ export const DATA_VIEWER_SHORTCUTS: IShortcut[] = [
label: 'data_viewer_shortcut_delete_row',
code: transformKeys(KEY_BINDING_DELETE_ROW),
},
+ {
+ label: 'plugin_search_panel_find',
+ code: transformKeys(KEY_BINDING_FIND),
+ },
{
label: 'ui_processing_save',
code: transformKeys(KEY_BINDING_SAVE),
@@ -109,8 +113,8 @@ export const SQL_EDITOR_SHORTCUTS: IShortcut[] = [
code: transformKeys(KEY_BINDING_REDO),
},
{
- label: 'sql_editor_shortcut_find',
- code: transformKeys(KEY_BINDING_SQL_EDITOR_FIND),
+ label: 'plugin_search_panel_find',
+ code: transformKeys(KEY_BINDING_FIND),
},
{
label: 'sql_editor_shortcut_comment_uncomment_selection',
diff --git a/webapp/packages/plugin-help/src/locales/en.ts b/webapp/packages/plugin-help/src/locales/en.ts
index c6aa2b5af2..bbfd865412 100644
--- a/webapp/packages/plugin-help/src/locales/en.ts
+++ b/webapp/packages/plugin-help/src/locales/en.ts
@@ -18,12 +18,13 @@ export default [
['sql_editor_shortcut_show_execution_plan', 'Show Execution plan'],
['sql_editor_shortcut_format', 'Format script'],
['sql_editor_shortcut_open_editor_in_new_tab', 'Open SQL Editor in the separate browser Tab'],
- ['sql_editor_shortcut_find', 'Find'],
['sql_editor_shortcut_comment_uncomment_selection', 'Comment/Uncomment selection'],
['sql_editor_shortcut_start_completion', 'Show autocomplete suggestions'],
['sql_editor_shortcut_accept_completion', 'Accept autocompletion'],
['sql_editor_shortcut_escape', 'Escape editor'],
+ ['plugin_search_panel_find', 'Find'],
+
['navigation_tree_shortcut_enable_filter', 'Enable filtering'],
['plugin_help_multi_tab_support_title', 'Multi-tab is not supported'],
@@ -34,5 +35,5 @@ export default [
Your local application settings will be lost after the browser tab is closed.
You can load tabs and settings for this tab`,
],
- ['plugin_help_multi_tab_support_load_settings', 'Load tabs ans settings'],
+ ['plugin_help_multi_tab_support_load_settings', 'Load tabs and settings'],
];
diff --git a/webapp/packages/plugin-help/src/locales/fr.ts b/webapp/packages/plugin-help/src/locales/fr.ts
index ef26c8ae1e..23147abf82 100644
--- a/webapp/packages/plugin-help/src/locales/fr.ts
+++ b/webapp/packages/plugin-help/src/locales/fr.ts
@@ -17,16 +17,16 @@ export default [
['sql_editor_shortcut_show_execution_plan', "Afficher le plan d'exécution"],
['sql_editor_shortcut_format', 'Formater le script'],
['sql_editor_shortcut_open_editor_in_new_tab', "Ouvrir l'éditeur SQL dans un nouvel onglet"],
- ['sql_editor_shortcut_find', 'Rechercher'],
['sql_editor_shortcut_comment_uncomment_selection', 'Commenter/Décommenter la sélection'],
['sql_editor_shortcut_start_completion', 'Afficher les suggestions de saisie semi-automatique'],
['sql_editor_shortcut_accept_completion', 'Accepter la saisie semi-automatique'],
['sql_editor_shortcut_escape', "Échapper l'éditeur"],
+ ['plugin_search_panel_find', 'Rechercher'],
['navigation_tree_shortcut_enable_filter', 'Activer le filtrage'],
['plugin_help_multi_tab_support_title', "Le multi-onglet n'est pas supporté"],
[
'plugin_help_multi_tab_support_description',
"Les données ne sont pas connectées à d'autres onglets du navigateur. Tout onglet d'application ouvert ne sera pas sauvegardé et sera probablement perdu après la fermeture de l'onglet. Vos paramètres et données locaux seront perdus après la fermeture de l'onglet. Vous pouvez charger les onglets et les paramètres pour cet onglet.",
],
- ['plugin_help_multi_tab_support_load_settings', 'Charger les onglets comme paramètres'],
+ ['plugin_help_multi_tab_support_load_settings', 'Charger les onglets et les paramètres'],
];
diff --git a/webapp/packages/plugin-help/src/locales/it.ts b/webapp/packages/plugin-help/src/locales/it.ts
index bb84316ebd..35daa88e60 100644
--- a/webapp/packages/plugin-help/src/locales/it.ts
+++ b/webapp/packages/plugin-help/src/locales/it.ts
@@ -18,11 +18,11 @@ export default [
['sql_editor_shortcut_show_execution_plan', 'Show Execution plan'],
['sql_editor_shortcut_format', 'Format script'],
['sql_editor_shortcut_open_editor_in_new_tab', 'Open SQL Editor in the separate browser Tab'],
- ['sql_editor_shortcut_find', 'Find'],
['sql_editor_shortcut_comment_uncomment_selection', 'Comment/Uncomment selection'],
['sql_editor_shortcut_start_completion', 'Show autocomplete suggestions'],
['sql_editor_shortcut_accept_completion', 'Accept autocompletion'],
['sql_editor_shortcut_escape', 'Escape editor'],
+ ['plugin_search_panel_find', 'Find'],
['navigation_tree_shortcut_enable_filter', 'Enable filtering'],
];
diff --git a/webapp/packages/plugin-help/src/locales/ru.ts b/webapp/packages/plugin-help/src/locales/ru.ts
index f11ecee81f..93f64b7281 100644
--- a/webapp/packages/plugin-help/src/locales/ru.ts
+++ b/webapp/packages/plugin-help/src/locales/ru.ts
@@ -18,11 +18,11 @@ export default [
['sql_editor_shortcut_show_execution_plan', 'Показать план выполнения'],
['sql_editor_shortcut_format', 'Форматировать скрипт'],
['sql_editor_shortcut_open_editor_in_new_tab', 'Открыть SQL редактор в новой бразуерной вкладке'],
- ['sql_editor_shortcut_find', 'Найти'],
['sql_editor_shortcut_comment_uncomment_selection', 'Закомментировать/раскомментировать выделение'],
['sql_editor_shortcut_start_completion', 'Показать подсказки автодополнения'],
['sql_editor_shortcut_accept_completion', 'Принять автодополнение'],
['sql_editor_shortcut_escape', 'Выйти из редактора'],
+ ['plugin_search_panel_find', 'Найти'],
['navigation_tree_shortcut_enable_filter', 'Включить фильтрацию'],
];
diff --git a/webapp/packages/plugin-help/src/locales/vi.ts b/webapp/packages/plugin-help/src/locales/vi.ts
index 2e049fb8f6..ba36545b9e 100644
--- a/webapp/packages/plugin-help/src/locales/vi.ts
+++ b/webapp/packages/plugin-help/src/locales/vi.ts
@@ -18,11 +18,11 @@ export default [
['sql_editor_shortcut_show_execution_plan', 'Hiển thị kế hoạch thực thi'],
['sql_editor_shortcut_format', 'Định dạng kịch bản'],
['sql_editor_shortcut_open_editor_in_new_tab', 'Mở Trình chỉnh sửa SQL trong tab riêng biệt'],
- ['sql_editor_shortcut_find', 'Tìm kiếm'],
['sql_editor_shortcut_comment_uncomment_selection', 'Bình luận/Bỏ bình luận lựa chọn'],
['sql_editor_shortcut_start_completion', 'Hiển thị gợi ý tự động hoàn thành'],
['sql_editor_shortcut_accept_completion', 'Chấp nhận tự động hoàn thành'],
['sql_editor_shortcut_escape', 'Thoát khỏi trình chỉnh sửa'],
+ ['plugin_search_panel_find', 'Tìm kiếm'],
['navigation_tree_shortcut_enable_filter', 'Bật lọc'],
diff --git a/webapp/packages/plugin-help/src/locales/zh.ts b/webapp/packages/plugin-help/src/locales/zh.ts
index f8489b3088..642c60bba2 100644
--- a/webapp/packages/plugin-help/src/locales/zh.ts
+++ b/webapp/packages/plugin-help/src/locales/zh.ts
@@ -18,11 +18,11 @@ export default [
['sql_editor_shortcut_show_execution_plan', '显示执行计划'],
['sql_editor_shortcut_format', '格式化脚本'],
['sql_editor_shortcut_open_editor_in_new_tab', '在单独的浏览器标签下打开SQL编辑器'],
- ['sql_editor_shortcut_find', '查找'],
['sql_editor_shortcut_comment_uncomment_selection', '注释/取消注释所选内容'],
['sql_editor_shortcut_start_completion', '显示自动完成建议'],
['sql_editor_shortcut_accept_completion', '接受自动完成'],
['sql_editor_shortcut_escape', '退出编辑器'],
+ ['plugin_search_panel_find', '查找'],
['navigation_tree_shortcut_enable_filter', '启用过滤'],
];
From b779b9d8550f633500760eeb408a124333f162b0 Mon Sep 17 00:00:00 2001
From: sergeyteleshev
Date: Fri, 27 Mar 2026 14:24:43 +0100
Subject: [PATCH 3/4] [CB] Fix high CVE-2026-33671 in picomatch (#4244)
* dbeaver/pro#8836 fixes picomatch CVE
* fixes happy-dom CVE
---
webapp/common-react/package.json | 3 +++
webapp/package.json | 4 +++-
webapp/yarn.lock | 23 ++++++++---------------
3 files changed, 14 insertions(+), 16 deletions(-)
diff --git a/webapp/common-react/package.json b/webapp/common-react/package.json
index 3bbab6148d..56740aaaf1 100644
--- a/webapp/common-react/package.json
+++ b/webapp/common-react/package.json
@@ -11,6 +11,9 @@
"clear": "rimraf -g '@dbeaver/*/{dist,lib}'",
"test": "dbeaver-test"
},
+ "resolutions": {
+ "happy-dom": ">=20.8.8"
+ },
"devDependencies": {
"@dbeaver/cli": "workspace:^",
"@dbeaver/prettier-config": "workspace:^",
diff --git a/webapp/package.json b/webapp/package.json
index cd3c47d47e..59f95ce006 100644
--- a/webapp/package.json
+++ b/webapp/package.json
@@ -24,7 +24,9 @@
"koa": ">=2.16.4",
"immutable": ">=4.3.8",
"serialize-javascript": ">=7.0.3",
- "flatted": ">=3.4.2"
+ "flatted": ">=3.4.2",
+ "picomatch": ">=2.3.2",
+ "happy-dom": ">=20.8.8"
},
"scripts": {
"test": "dbeaver-test",
diff --git a/webapp/yarn.lock b/webapp/yarn.lock
index b2d82bef4e..eba0f28e25 100644
--- a/webapp/yarn.lock
+++ b/webapp/yarn.lock
@@ -13122,9 +13122,9 @@ __metadata:
languageName: node
linkType: hard
-"happy-dom@npm:^20":
- version: 20.8.3
- resolution: "happy-dom@npm:20.8.3"
+"happy-dom@npm:>=20.8.8":
+ version: 20.8.9
+ resolution: "happy-dom@npm:20.8.9"
dependencies:
"@types/node": "npm:>=20.0.0"
"@types/whatwg-mimetype": "npm:^3.0.2"
@@ -13132,7 +13132,7 @@ __metadata:
entities: "npm:^7.0.1"
whatwg-mimetype: "npm:^3.0.0"
ws: "npm:^8.18.3"
- checksum: 10c0/79a2b6d32e2f778b015511c9d2de7f7859954cbd27a30720736e60552a88e0345ffc8b2c5e77140c5f2f7fef95c563aea7ab0b2edba5d8c7edd5676b43ecef55
+ checksum: 10c0/12fe9b85891b1289935b2a4f726e2839e7c92e3f55401bd20cb5500763dd994364645acaab20a754fd90d5e1b2ffdf734b39a32ea02704c3e3ee0c4d30cf958e
languageName: node
linkType: hard
@@ -16559,17 +16559,10 @@ __metadata:
languageName: node
linkType: hard
-"picomatch@npm:^2.2.2, picomatch@npm:^2.3.1":
- version: 2.3.1
- resolution: "picomatch@npm:2.3.1"
- checksum: 10c0/26c02b8d06f03206fc2ab8d16f19960f2ff9e81a658f831ecb656d8f17d9edc799e8364b1f4a7873e89d9702dff96204be0fa26fe4181f6843f040f819dac4be
- languageName: node
- linkType: hard
-
-"picomatch@npm:^4.0.2, picomatch@npm:^4.0.3":
- version: 4.0.3
- resolution: "picomatch@npm:4.0.3"
- checksum: 10c0/9582c951e95eebee5434f59e426cddd228a7b97a0161a375aed4be244bd3fe8e3a31b846808ea14ef2c8a2527a6eeab7b3946a67d5979e81694654f939473ae2
+"picomatch@npm:>=2.3.2":
+ version: 4.0.4
+ resolution: "picomatch@npm:4.0.4"
+ checksum: 10c0/e2c6023372cc7b5764719a5ffb9da0f8e781212fa7ca4bd0562db929df8e117460f00dff3cb7509dacfc06b86de924b247f504d0ce1806a37fac4633081466b0
languageName: node
linkType: hard
From 1d5b475482e5d6e95b0f2b62be27e37b2a78ddca Mon Sep 17 00:00:00 2001
From: Sychev Andrey <44414066+SychevAndrey@users.noreply.github.com>
Date: Fri, 27 Mar 2026 16:07:31 +0100
Subject: [PATCH 4/4] dbeaver/pro#8553 sql execution plan diagram (#4218)
* dbeaver/pro#8553 feat: add execution plan diagram component
* dbeaver/pro#8553 feat: enhance ExecutionPlanDiagram component with selectedNodeId prop
* dbeaver/pro#8553 feat: add flex-shrink to metric value for better layout
* dbeaver/pro#8553 refactor: remove queryString from IPlanData interface
* dbeaver/pro#8553 feat: integrate execution plan diagram component
* dbeaver/pro#8553 refactor: execution plan diagram
separate state, add l10n, make toolbar composable
* dbeaver/pro#8553 feat: implement keyboard navigation for execution plan nodes
* dbeaver/pro#8553 feat: add translation support for execution plan diagram labels
* dbeaver/pro#8553 fix: execution plan node dimensions
* dbeaver/pro#8553 refactor: move formatNumber to helpers to use it
* dbeaver/pro#8553 feat: add translation support for execution plan diagram API
* dbeaver/pro#8553 docs: add README and API documentation for execution plan diagram component
* dbeaver/pro#8553 feat: adjust cost bar height and collapse indicator position
* dbeaver/pro#8553 feat: update PRIMARY_AXIS_WEIGHT for improved directional navigation
* dbeaver/pro#8553 feat: refactor diagram actions and add collapse state management
* dbeaver/pro#8553 refactor: move execution plan diagram to separate EE plugin
* dbeaver/pro#8553 docs: remove redundant comment
* dbeaver/pro#8553 docs: update comments for source and target anchors in ILayoutEdge interface
* dbeaver/pro#8553 docs: update comment in ILayoutNode interface
* dbeaver/pro#8553 refactor: simplify heavy route computation
* dbeaver/pro#8553 refactor: optimize node handling in computePlanLayout function
* dbeaver/pro#8553 refactor: improve tree structure handling in usePlanTree and buildTree functions
* dbeaver/pro#8553 refactor: simplify usePlanTree
* dbeaver/pro#8553 refactor: extract actions from useExecutionPlanDiagramState
* dbeaver/pro#8553 refactor: improve configuration in execution plan diagram
* dbeaver/pro#8553 refactor: simplify metric rendering in PlanNode component
* dbeaver/pro#8553 feat: collapse by hotkey, not an extra element
* dbeaver/pro#8553 feat: add tooltip hints for plan node interactions
* dbeaver/pro#8553 refactor: remove high cost calculation and add node kind attribute
* dbeaver/pro#8553 style: fix formatting in index.ts for ISqlExecutionPlanViewProps export
* dbeaver/pro#8553 ci: remove unused dependency on @dbeaver/ui-kit
* dbeaver/pro#8553 refactor: remove SQL execution plan diagram translations from locale files
* dbeaver/pro#8553 refactor: update translation keys for SQL execution plan components
* dbeaver/pro#8553 refactor: rename components
* dbeaver/pro#8553 style: const
* dbeaver/pro#8553 refactor: reset execution plan diagram state properties
* dbeaver/pro#8553 refactor: update component imports and extract a component
* dbeaver/pro#8553 refactor: rename PlanNodeKind to EPlanNodeKind and update references
* dbeaver/pro#8553 feat: add zoom icons and update action references
* dbeaver/pro#8553 refactor: enhance translation functionality by adding args interpolation
* dbeaver/pro#8553 fix: Polynomial regular expression used on uncontrolled data
* dbeaver/pro#8553 refactor: update ActionsCapture to use ref for toolbar actions
* dbeaver/pro#8553 refactor: use jsx
* dbeaver/pro#8553 refactor: simplify
* dbeaver/pro#8553 refactor: replace useContext with use in DiagramContext
* dbeaver/pro#8553 refactor: convert ExecutionPlanEdge to memoized component
* dbeaver/pro#8553 refactor: convert ExecutionPlanNode to memoized component
* dbeaver/pro#8553 refactor: unify ref prop in ExecutionPlanNode and ExecutionPlanViewport
* dbeaver/pro#8553 refactor: extract ExecutionPlanViewportContent component and clean up CSS
* dbeaver/pro#8553 refactor: convert ExecutionPlanNodeMetric to memoized component
* dbeaver/pro#8553 refactor: improve usePlanLayout hook by utilizing useEffectEvent for stable callback
* dbeaver/pro#8553 refactor: simplify diagram actions handling in createExecutionPlanDiagram
* dbeaver/pro#8553 refactor: move out execution plan diagram component from
---------
Co-authored-by: Evgenia <139753579+EvgeniaBzzz@users.noreply.github.com>
Co-authored-by: mr-anton-t <42037741+mr-anton-t@users.noreply.github.com>
Co-authored-by: alex <48489896+devnaumov@users.noreply.github.com>
---
.../react-translate/src/TranslateContext.ts | 30 +++++++++++---
.../@dbeaver/js-helpers/src/formatNumber.ts | 24 +++++++++++
.../@dbeaver/js-helpers/src/index.ts | 1 +
webapp/packages/core-utils/package.json | 1 +
.../packages/core-utils/src/formatNumber.ts | 19 +--------
webapp/packages/core-utils/tsconfig.json | 3 ++
.../core-view/public/icons/zoom-in.svg | 3 --
.../core-view/public/icons/zoom-out.svg | 3 --
.../packages/core-view/public/icons/zoom.svg | 11 +++++
.../core-view/public/icons/zoom_in.svg | 13 ++++++
.../core-view/public/icons/zoom_in_m.svg | 13 ++++++
.../core-view/public/icons/zoom_in_sm.svg | 18 ++++++++
.../core-view/public/icons/zoom_m.svg | 11 +++++
.../core-view/public/icons/zoom_out.svg | 12 ++++++
.../core-view/public/icons/zoom_out_m.svg | 12 ++++++
.../core-view/public/icons/zoom_out_sm.svg | 17 ++++++++
.../core-view/public/icons/zoom_sm.svg | 16 ++++++++
.../src/Action/Actions/ACTION_ZOOM_IN.ts | 4 +-
.../src/Action/Actions/ACTION_ZOOM_OUT.ts | 4 +-
.../ExecutionPlan/ExecutionPlanTreeBlock.tsx | 4 +-
.../ExecutionPlan/ExecutionPlanTreeView.tsx | 20 +++++++++
.../ISqlExecutionPlanViewProps.ts | 16 ++++++++
.../PropertiesPanel/PropertiesPanel.tsx | 16 +++++---
.../SqlExecutionPlanPanel.module.css | 41 ++++++++++++++++++-
.../ExecutionPlan/SqlExecutionPlanPanel.tsx | 20 +++++++--
.../SqlExecutionPlanViewBootstrap.ts | 30 ++++++++++++++
.../SqlExecutionPlanViewService.ts | 21 ++++++++++
.../packages/plugin-sql-editor/src/index.ts | 3 ++
.../plugin-sql-editor/src/locales/en.ts | 13 +++---
.../plugin-sql-editor/src/locales/fr.ts | 13 +++---
.../plugin-sql-editor/src/locales/it.ts | 13 +++---
.../plugin-sql-editor/src/locales/ru.ts | 13 +++---
.../plugin-sql-editor/src/locales/vi.ts | 13 +++---
.../plugin-sql-editor/src/locales/zh.ts | 13 +++---
.../packages/plugin-sql-editor/src/module.ts | 6 ++-
webapp/yarn.lock | 1 +
36 files changed, 389 insertions(+), 82 deletions(-)
create mode 100644 webapp/common-typescript/@dbeaver/js-helpers/src/formatNumber.ts
delete mode 100644 webapp/packages/core-view/public/icons/zoom-in.svg
delete mode 100644 webapp/packages/core-view/public/icons/zoom-out.svg
create mode 100644 webapp/packages/core-view/public/icons/zoom.svg
create mode 100644 webapp/packages/core-view/public/icons/zoom_in.svg
create mode 100644 webapp/packages/core-view/public/icons/zoom_in_m.svg
create mode 100644 webapp/packages/core-view/public/icons/zoom_in_sm.svg
create mode 100644 webapp/packages/core-view/public/icons/zoom_m.svg
create mode 100644 webapp/packages/core-view/public/icons/zoom_out.svg
create mode 100644 webapp/packages/core-view/public/icons/zoom_out_m.svg
create mode 100644 webapp/packages/core-view/public/icons/zoom_out_sm.svg
create mode 100644 webapp/packages/core-view/public/icons/zoom_sm.svg
create mode 100644 webapp/packages/plugin-sql-editor/src/SqlResultTabs/ExecutionPlan/ExecutionPlanTreeView.tsx
create mode 100644 webapp/packages/plugin-sql-editor/src/SqlResultTabs/ExecutionPlan/ISqlExecutionPlanViewProps.ts
create mode 100644 webapp/packages/plugin-sql-editor/src/SqlResultTabs/ExecutionPlan/SqlExecutionPlanViewBootstrap.ts
create mode 100644 webapp/packages/plugin-sql-editor/src/SqlResultTabs/ExecutionPlan/SqlExecutionPlanViewService.ts
diff --git a/webapp/common-react/@dbeaver/react-translate/src/TranslateContext.ts b/webapp/common-react/@dbeaver/react-translate/src/TranslateContext.ts
index f2605c4a63..eef5a781f9 100644
--- a/webapp/common-react/@dbeaver/react-translate/src/TranslateContext.ts
+++ b/webapp/common-react/@dbeaver/react-translate/src/TranslateContext.ts
@@ -1,6 +1,6 @@
/*
* CloudBeaver - Cloud Database Manager
- * Copyright (C) 2020-2025 DBeaver Corp and others
+ * Copyright (C) 2020-2026 DBeaver Corp and others
*
* Licensed under the Apache License, Version 2.0.
* you may not use this file except in compliance with the License.
@@ -9,11 +9,31 @@
import { createContext } from 'react';
import type { LocalizationToken } from './LocalizationToken.js';
-export function defaultTranslateFn(token: T, fallback?: T): T {
- return fallback || token;
+export function interpolateTranslation(template: string, args?: Record): string {
+ if (!args) {
+ return template;
+ }
+
+ let result = template;
+
+ for (const [key, value] of Object.entries(args)) {
+ if (value != null) {
+ result = result.split(`{arg:${key}}`).join(String(value));
+ }
+ }
+
+ return result;
}
-export type TranslateFn = (token: T, fallback?: T, args?: Record) => T;
+export function defaultTranslateFn(token: T, fallback?: T, args?: Record): T {
+ const result = fallback || token;
+ if (result && args) {
+ return interpolateTranslation(result as string, args) as T;
+ }
+ return result;
+}
+
+export type TranslateFn = (token: T, fallback?: T, args?: Record) => T;
export const TranslateContext = createContext<{ translate: TranslateFn }>({
- translate: (key, fallback) => fallback || key,
+ translate: defaultTranslateFn,
});
diff --git a/webapp/common-typescript/@dbeaver/js-helpers/src/formatNumber.ts b/webapp/common-typescript/@dbeaver/js-helpers/src/formatNumber.ts
new file mode 100644
index 0000000000..16699a7a95
--- /dev/null
+++ b/webapp/common-typescript/@dbeaver/js-helpers/src/formatNumber.ts
@@ -0,0 +1,24 @@
+/*
+ * CloudBeaver - Cloud Database Manager
+ * Copyright (C) 2020-2026 DBeaver Corp and others
+ *
+ * Licensed under the Apache License, Version 2.0.
+ * you may not use this file except in compliance with the License.
+ */
+
+export function formatNumber(n: number, d: number): string {
+ if (n < 1000) {
+ return n.toLocaleString(undefined, { maximumFractionDigits: 2 });
+ }
+
+ const numStr = n.toString();
+ const exponent = numStr.length - (numStr.length % 3);
+
+ const power = Math.pow(10, d);
+ const rounded = Math.round((n * power) / Math.pow(10, exponent)) / power;
+
+ const units = ' kMBTPE';
+ const unit = units[exponent / 3]!;
+
+ return rounded + unit;
+}
\ No newline at end of file
diff --git a/webapp/common-typescript/@dbeaver/js-helpers/src/index.ts b/webapp/common-typescript/@dbeaver/js-helpers/src/index.ts
index e8565e0642..8a8f1be87e 100644
--- a/webapp/common-typescript/@dbeaver/js-helpers/src/index.ts
+++ b/webapp/common-typescript/@dbeaver/js-helpers/src/index.ts
@@ -16,3 +16,4 @@ export * from './memoizeLast.js';
export * from './mutex.js';
export * from './reorderArray.js';
export * from './getLocalizedDisplayName.js';
+export * from './formatNumber.js';
diff --git a/webapp/packages/core-utils/package.json b/webapp/packages/core-utils/package.json
index f62ccba5bd..c9972bacf6 100644
--- a/webapp/packages/core-utils/package.json
+++ b/webapp/packages/core-utils/package.json
@@ -23,6 +23,7 @@
"validate-dependencies": "core-cli-validate-dependencies"
},
"dependencies": {
+ "@dbeaver/js-helpers": "workspace:*",
"@timohausmann/quadtree-ts": "^2",
"fast-deep-equal": "^3",
"md5": "^2",
diff --git a/webapp/packages/core-utils/src/formatNumber.ts b/webapp/packages/core-utils/src/formatNumber.ts
index 1a3d8f9e12..30d442a075 100644
--- a/webapp/packages/core-utils/src/formatNumber.ts
+++ b/webapp/packages/core-utils/src/formatNumber.ts
@@ -1,24 +1,9 @@
/*
* CloudBeaver - Cloud Database Manager
- * Copyright (C) 2020-2024 DBeaver Corp and others
+ * Copyright (C) 2020-2026 DBeaver Corp and others
*
* Licensed under the Apache License, Version 2.0.
* you may not use this file except in compliance with the License.
*/
-export function formatNumber(n: number, d: number) {
- if (n < 1000) {
- return n.toLocaleString(undefined, { maximumFractionDigits: 2 });
- }
-
- const numStr = n.toString();
- const exponent = numStr.length - (numStr.length % 3);
-
- const power = Math.pow(10, d);
- const rounded = Math.round((n * power) / Math.pow(10, exponent)) / power;
-
- const units = ' kMBTPE';
- const unit = units[exponent / 3]!;
-
- return rounded + unit;
-}
+export { formatNumber } from '@dbeaver/js-helpers';
diff --git a/webapp/packages/core-utils/tsconfig.json b/webapp/packages/core-utils/tsconfig.json
index 964a4a5f8b..30236ffc9b 100644
--- a/webapp/packages/core-utils/tsconfig.json
+++ b/webapp/packages/core-utils/tsconfig.json
@@ -13,6 +13,9 @@
{
"path": "../../common-typescript/@dbeaver/cli"
},
+ {
+ "path": "../../common-typescript/@dbeaver/js-helpers"
+ },
{
"path": "../core-cli"
},
diff --git a/webapp/packages/core-view/public/icons/zoom-in.svg b/webapp/packages/core-view/public/icons/zoom-in.svg
deleted file mode 100644
index 7ca279793b..0000000000
--- a/webapp/packages/core-view/public/icons/zoom-in.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-
diff --git a/webapp/packages/core-view/public/icons/zoom-out.svg b/webapp/packages/core-view/public/icons/zoom-out.svg
deleted file mode 100644
index efa287627c..0000000000
--- a/webapp/packages/core-view/public/icons/zoom-out.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-
diff --git a/webapp/packages/core-view/public/icons/zoom.svg b/webapp/packages/core-view/public/icons/zoom.svg
new file mode 100644
index 0000000000..8f0f823ec6
--- /dev/null
+++ b/webapp/packages/core-view/public/icons/zoom.svg
@@ -0,0 +1,11 @@
+
diff --git a/webapp/packages/core-view/public/icons/zoom_in.svg b/webapp/packages/core-view/public/icons/zoom_in.svg
new file mode 100644
index 0000000000..0a07b3fa4b
--- /dev/null
+++ b/webapp/packages/core-view/public/icons/zoom_in.svg
@@ -0,0 +1,13 @@
+
diff --git a/webapp/packages/core-view/public/icons/zoom_in_m.svg b/webapp/packages/core-view/public/icons/zoom_in_m.svg
new file mode 100644
index 0000000000..5b863afa24
--- /dev/null
+++ b/webapp/packages/core-view/public/icons/zoom_in_m.svg
@@ -0,0 +1,13 @@
+
diff --git a/webapp/packages/core-view/public/icons/zoom_in_sm.svg b/webapp/packages/core-view/public/icons/zoom_in_sm.svg
new file mode 100644
index 0000000000..6ffe2e4d23
--- /dev/null
+++ b/webapp/packages/core-view/public/icons/zoom_in_sm.svg
@@ -0,0 +1,18 @@
+
diff --git a/webapp/packages/core-view/public/icons/zoom_m.svg b/webapp/packages/core-view/public/icons/zoom_m.svg
new file mode 100644
index 0000000000..5f66f43286
--- /dev/null
+++ b/webapp/packages/core-view/public/icons/zoom_m.svg
@@ -0,0 +1,11 @@
+
diff --git a/webapp/packages/core-view/public/icons/zoom_out.svg b/webapp/packages/core-view/public/icons/zoom_out.svg
new file mode 100644
index 0000000000..01af24e5f0
--- /dev/null
+++ b/webapp/packages/core-view/public/icons/zoom_out.svg
@@ -0,0 +1,12 @@
+
diff --git a/webapp/packages/core-view/public/icons/zoom_out_m.svg b/webapp/packages/core-view/public/icons/zoom_out_m.svg
new file mode 100644
index 0000000000..72c80d928b
--- /dev/null
+++ b/webapp/packages/core-view/public/icons/zoom_out_m.svg
@@ -0,0 +1,12 @@
+
diff --git a/webapp/packages/core-view/public/icons/zoom_out_sm.svg b/webapp/packages/core-view/public/icons/zoom_out_sm.svg
new file mode 100644
index 0000000000..fe110d6b54
--- /dev/null
+++ b/webapp/packages/core-view/public/icons/zoom_out_sm.svg
@@ -0,0 +1,17 @@
+
diff --git a/webapp/packages/core-view/public/icons/zoom_sm.svg b/webapp/packages/core-view/public/icons/zoom_sm.svg
new file mode 100644
index 0000000000..7228cdb884
--- /dev/null
+++ b/webapp/packages/core-view/public/icons/zoom_sm.svg
@@ -0,0 +1,16 @@
+
diff --git a/webapp/packages/core-view/src/Action/Actions/ACTION_ZOOM_IN.ts b/webapp/packages/core-view/src/Action/Actions/ACTION_ZOOM_IN.ts
index 536eac3898..fe01f537f4 100644
--- a/webapp/packages/core-view/src/Action/Actions/ACTION_ZOOM_IN.ts
+++ b/webapp/packages/core-view/src/Action/Actions/ACTION_ZOOM_IN.ts
@@ -1,6 +1,6 @@
/*
* CloudBeaver - Cloud Database Manager
- * Copyright (C) 2020-2024 DBeaver Corp and others
+ * Copyright (C) 2020-2026 DBeaver Corp and others
*
* Licensed under the Apache License, Version 2.0.
* you may not use this file except in compliance with the License.
@@ -10,5 +10,5 @@ import { createAction } from '../createAction.js';
export const ACTION_ZOOM_IN = createAction('zoom-in', {
label: 'core_view_zoom_in',
tooltip: 'core_view_zoom_in',
- icon: '/icons/zoom-in.svg',
+ icon: '/icons/zoom_in.svg',
});
diff --git a/webapp/packages/core-view/src/Action/Actions/ACTION_ZOOM_OUT.ts b/webapp/packages/core-view/src/Action/Actions/ACTION_ZOOM_OUT.ts
index 5f63cb7822..8ed984b25e 100644
--- a/webapp/packages/core-view/src/Action/Actions/ACTION_ZOOM_OUT.ts
+++ b/webapp/packages/core-view/src/Action/Actions/ACTION_ZOOM_OUT.ts
@@ -1,6 +1,6 @@
/*
* CloudBeaver - Cloud Database Manager
- * Copyright (C) 2020-2024 DBeaver Corp and others
+ * Copyright (C) 2020-2026 DBeaver Corp and others
*
* Licensed under the Apache License, Version 2.0.
* you may not use this file except in compliance with the License.
@@ -10,5 +10,5 @@ import { createAction } from '../createAction.js';
export const ACTION_ZOOM_OUT = createAction('zoom-out', {
label: 'core_view_zoom_out',
tooltip: 'core_view_zoom_out',
- icon: '/icons/zoom-out.svg',
+ icon: '/icons/zoom_out.svg',
});
diff --git a/webapp/packages/plugin-sql-editor/src/SqlResultTabs/ExecutionPlan/ExecutionPlanTreeBlock.tsx b/webapp/packages/plugin-sql-editor/src/SqlResultTabs/ExecutionPlan/ExecutionPlanTreeBlock.tsx
index abd6111b21..395355f184 100644
--- a/webapp/packages/plugin-sql-editor/src/SqlResultTabs/ExecutionPlan/ExecutionPlanTreeBlock.tsx
+++ b/webapp/packages/plugin-sql-editor/src/SqlResultTabs/ExecutionPlan/ExecutionPlanTreeBlock.tsx
@@ -1,6 +1,6 @@
/*
* CloudBeaver - Cloud Database Manager
- * Copyright (C) 2020-2024 DBeaver Corp and others
+ * Copyright (C) 2020-2026 DBeaver Corp and others
*
* Licensed under the Apache License, Version 2.0.
* you may not use this file except in compliance with the License.
@@ -64,7 +64,7 @@ export const ExecutionPlanTreeBlock = observer(function ExecutionPlanTree
) : (
- {translate('sql_execution_plan_placeholder')}
+ {translate('plugin_sql_execution_plan_placeholder')}
)}
diff --git a/webapp/packages/plugin-sql-editor/src/SqlResultTabs/ExecutionPlan/ExecutionPlanTreeView.tsx b/webapp/packages/plugin-sql-editor/src/SqlResultTabs/ExecutionPlan/ExecutionPlanTreeView.tsx
new file mode 100644
index 0000000000..f2ae91aa78
--- /dev/null
+++ b/webapp/packages/plugin-sql-editor/src/SqlResultTabs/ExecutionPlan/ExecutionPlanTreeView.tsx
@@ -0,0 +1,20 @@
+/*
+ * CloudBeaver - Cloud Database Manager
+ * Copyright (C) 2020-2026 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 { observer } from 'mobx-react-lite';
+
+import type { ISqlExecutionPlanViewProps } from './ISqlExecutionPlanViewProps.js';
+import { ExecutionPlanTreeBlock } from './ExecutionPlanTreeBlock.js';
+
+export const ExecutionPlanTreeView = observer(function ExecutionPlanTreeView({
+ nodes,
+ query,
+ onNodeSelect,
+}) {
+ return ;
+});
diff --git a/webapp/packages/plugin-sql-editor/src/SqlResultTabs/ExecutionPlan/ISqlExecutionPlanViewProps.ts b/webapp/packages/plugin-sql-editor/src/SqlResultTabs/ExecutionPlan/ISqlExecutionPlanViewProps.ts
new file mode 100644
index 0000000000..4d295ea10d
--- /dev/null
+++ b/webapp/packages/plugin-sql-editor/src/SqlResultTabs/ExecutionPlan/ISqlExecutionPlanViewProps.ts
@@ -0,0 +1,16 @@
+/*
+ * CloudBeaver - Cloud Database Manager
+ * Copyright (C) 2020-2026 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 { SqlExecutionPlanNode } from '@cloudbeaver/core-sdk';
+
+export interface ISqlExecutionPlanViewProps {
+ nodes: SqlExecutionPlanNode[];
+ query: string;
+ selectedNode: string | null;
+ onNodeSelect: (nodeId: string | null) => void;
+}
diff --git a/webapp/packages/plugin-sql-editor/src/SqlResultTabs/ExecutionPlan/PropertiesPanel/PropertiesPanel.tsx b/webapp/packages/plugin-sql-editor/src/SqlResultTabs/ExecutionPlan/PropertiesPanel/PropertiesPanel.tsx
index 9e64f308c6..8abb0f1cd6 100644
--- a/webapp/packages/plugin-sql-editor/src/SqlResultTabs/ExecutionPlan/PropertiesPanel/PropertiesPanel.tsx
+++ b/webapp/packages/plugin-sql-editor/src/SqlResultTabs/ExecutionPlan/PropertiesPanel/PropertiesPanel.tsx
@@ -1,6 +1,6 @@
/*
* CloudBeaver - Cloud Database Manager
- * Copyright (C) 2020-2024 DBeaver Corp and others
+ * Copyright (C) 2020-2026 DBeaver Corp and others
*
* Licensed under the Apache License, Version 2.0.
* you may not use this file except in compliance with the License.
@@ -50,11 +50,11 @@ export const PropertiesPanel = observer(function PropertiesPanel({ select
).get();
if (!general.length && !details.length) {
- return {translate('sql_execution_plan_properties_panel_placeholder')};
+ return {translate('plugin_sql_execution_plan_properties_panel_placeholder')};
}
- const nameColumnTitle = translate('sql_execution_plan_properties_panel_name');
- const valueColumnTitle = translate('sql_execution_plan_properties_panel_value');
+ const nameColumnTitle = translate('plugin_sql_execution_plan_properties_panel_name');
+ const valueColumnTitle = translate('plugin_sql_execution_plan_properties_panel_value');
return (
@@ -63,8 +63,12 @@ export const PropertiesPanel = observer(function PropertiesPanel({ select
{valueColumnTitle}
- {!!general.length && }
- {!!details.length && }
+ {!!general.length && (
+
+ )}
+ {!!details.length && (
+
+ )}
);
diff --git a/webapp/packages/plugin-sql-editor/src/SqlResultTabs/ExecutionPlan/SqlExecutionPlanPanel.module.css b/webapp/packages/plugin-sql-editor/src/SqlResultTabs/ExecutionPlan/SqlExecutionPlanPanel.module.css
index c03d414621..7b3d848fba 100644
--- a/webapp/packages/plugin-sql-editor/src/SqlResultTabs/ExecutionPlan/SqlExecutionPlanPanel.module.css
+++ b/webapp/packages/plugin-sql-editor/src/SqlResultTabs/ExecutionPlan/SqlExecutionPlanPanel.module.css
@@ -1,6 +1,6 @@
/*
* CloudBeaver - Cloud Database Manager
- * Copyright (C) 2020-2024 DBeaver Corp and others
+ * Copyright (C) 2020-2026 DBeaver Corp and others
*
* Licensed under the Apache License, Version 2.0.
* you may not use this file except in compliance with the License.
@@ -8,6 +8,45 @@
.pane {
&:first-child {
+ display: flex;
+ flex-direction: column;
overflow: hidden;
+
+ /* Map diagram component variables to CloudBeaver theme */
+
+ /* Viewport */
+ --dbv-plan-viewport-bg: var(--theme-surface);
+
+ /* Node */
+ --dbv-plan-node-bg: var(--theme-sub-secondary);
+ --dbv-plan-node-border-color: var(--theme-input-border);
+ --dbv-plan-node-selected-border: var(--theme-primary);
+ --dbv-plan-node-selected-glow: color-mix(in srgb, var(--theme-primary) 30%, transparent);
+ --dbv-plan-node-heavy-color: var(--theme-negative);
+
+ /* Node caption */
+ --dbv-plan-node-caption-bg: var(--theme-background);
+ --dbv-plan-node-caption-color: var(--theme-on-surface);
+
+ /* Node name */
+ --dbv-plan-node-name-color: var(--theme-on-surface);
+
+ /* Node metrics */
+ --dbv-plan-node-metric-color: var(--theme-text-secondary-on-light);
+ --dbv-plan-node-metric-value-color: var(--theme-on-surface);
+
+ /* Node cost bar */
+ --dbv-plan-node-cost-bar-bg: var(--theme-input-border);
+ --dbv-plan-node-cost-bar-color: var(--theme-status);
+
+ /* Edges */
+ --dbv-plan-edge-color: var(--theme-text-hint-on-light);
+
+ /* Toolbar */
+ --dbv-plan-toolbar-border: var(--theme-input-border);
+ --dbv-plan-toolbar-bg: var(--theme-surface);
+ --dbv-plan-toolbar-color: var(--theme-on-surface);
+ --dbv-plan-toolbar-hover-bg: var(--theme-sub-secondary);
+ --dbv-plan-toolbar-active-bg: var(--theme-secondary);
}
}
diff --git a/webapp/packages/plugin-sql-editor/src/SqlResultTabs/ExecutionPlan/SqlExecutionPlanPanel.tsx b/webapp/packages/plugin-sql-editor/src/SqlResultTabs/ExecutionPlan/SqlExecutionPlanPanel.tsx
index 64d23e5c43..b177772a0d 100644
--- a/webapp/packages/plugin-sql-editor/src/SqlResultTabs/ExecutionPlan/SqlExecutionPlanPanel.tsx
+++ b/webapp/packages/plugin-sql-editor/src/SqlResultTabs/ExecutionPlan/SqlExecutionPlanPanel.tsx
@@ -1,6 +1,6 @@
/*
* CloudBeaver - Cloud Database Manager
- * Copyright (C) 2020-2024 DBeaver Corp and others
+ * Copyright (C) 2020-2026 DBeaver Corp and others
*
* Licensed under the Apache License, Version 2.0.
* you may not use this file except in compliance with the License.
@@ -10,12 +10,13 @@ import { useState } from 'react';
import { Loader, Pane, ResizerControls, s, Split, useS, useSplitUserState } from '@cloudbeaver/core-blocks';
import { useService } from '@cloudbeaver/core-di';
+import { TabList, TabPanelList, TabsState } from '@cloudbeaver/core-ui';
import type { IExecutionPlanTab } from '../../ISqlEditorTabState.js';
-import { ExecutionPlanTreeBlock } from './ExecutionPlanTreeBlock.js';
import { PropertiesPanel } from './PropertiesPanel/PropertiesPanel.js';
-import style from './SqlExecutionPlanPanel.module.css';
import { SqlExecutionPlanService } from './SqlExecutionPlanService.js';
+import { SqlExecutionPlanViewService } from './SqlExecutionPlanViewService.js';
+import style from './SqlExecutionPlanPanel.module.css';
interface Props {
executionPlanTab: IExecutionPlanTab;
@@ -24,6 +25,7 @@ interface Props {
export const SqlExecutionPlanPanel = observer(function SqlExecutionPlanPanel({ executionPlanTab }) {
const styles = useS(style);
const sqlExecutionPlanService = useService(SqlExecutionPlanService);
+ const sqlExecutionPlanViewService = useService(SqlExecutionPlanViewService);
const data = sqlExecutionPlanService.data.get(executionPlanTab.tabId);
const [selectedNode, setSelectedNode] = useState(null);
const splitState = useSplitUserState('execution-plan');
@@ -35,7 +37,17 @@ export const SqlExecutionPlanPanel = observer(function SqlExecutionPlanPa
return (
-
+
+
+
+
diff --git a/webapp/packages/plugin-sql-editor/src/SqlResultTabs/ExecutionPlan/SqlExecutionPlanViewBootstrap.ts b/webapp/packages/plugin-sql-editor/src/SqlResultTabs/ExecutionPlan/SqlExecutionPlanViewBootstrap.ts
new file mode 100644
index 0000000000..2e4165bd9d
--- /dev/null
+++ b/webapp/packages/plugin-sql-editor/src/SqlResultTabs/ExecutionPlan/SqlExecutionPlanViewBootstrap.ts
@@ -0,0 +1,30 @@
+/*
+ * CloudBeaver - Cloud Database Manager
+ * Copyright (C) 2020-2026 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 { importLazyComponent } from '@cloudbeaver/core-blocks';
+import { Bootstrap, injectable } from '@cloudbeaver/core-di';
+
+import { SqlExecutionPlanViewService } from './SqlExecutionPlanViewService.js';
+
+const ExecutionPlanTreeView = importLazyComponent(() => import('./ExecutionPlanTreeView.js').then(m => m.ExecutionPlanTreeView));
+
+@injectable(() => [SqlExecutionPlanViewService])
+export class SqlExecutionPlanViewBootstrap extends Bootstrap {
+ constructor(private readonly sqlExecutionPlanViewService: SqlExecutionPlanViewService) {
+ super();
+ }
+
+ override register(): void {
+ this.sqlExecutionPlanViewService.tabs.add({
+ key: 'table',
+ name: 'plugin_sql_execution_plan_view_table',
+ order: 0,
+ panel: () => ExecutionPlanTreeView,
+ });
+ }
+}
diff --git a/webapp/packages/plugin-sql-editor/src/SqlResultTabs/ExecutionPlan/SqlExecutionPlanViewService.ts b/webapp/packages/plugin-sql-editor/src/SqlResultTabs/ExecutionPlan/SqlExecutionPlanViewService.ts
new file mode 100644
index 0000000000..7ec9d84f81
--- /dev/null
+++ b/webapp/packages/plugin-sql-editor/src/SqlResultTabs/ExecutionPlan/SqlExecutionPlanViewService.ts
@@ -0,0 +1,21 @@
+/*
+ * CloudBeaver - Cloud Database Manager
+ * Copyright (C) 2020-2026 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 { injectable } from '@cloudbeaver/core-di';
+import { TabsContainer } from '@cloudbeaver/core-ui';
+
+import type { ISqlExecutionPlanViewProps } from './ISqlExecutionPlanViewProps.js';
+
+@injectable()
+export class SqlExecutionPlanViewService {
+ readonly tabs: TabsContainer;
+
+ constructor() {
+ this.tabs = new TabsContainer('Execution Plan Views');
+ }
+}
diff --git a/webapp/packages/plugin-sql-editor/src/index.ts b/webapp/packages/plugin-sql-editor/src/index.ts
index f6a6a39475..fc2ea4dd5e 100644
--- a/webapp/packages/plugin-sql-editor/src/index.ts
+++ b/webapp/packages/plugin-sql-editor/src/index.ts
@@ -54,3 +54,6 @@ export * from './SqlEditorService.js';
export * from './SqlEditorSettingsService.js';
export * from './SqlEditorView.js';
export * from './SqlResultTabs/SqlQueryService.js';
+export * from './SqlResultTabs/ExecutionPlan/SqlExecutionPlanViewService.js';
+export type { ISqlExecutionPlanViewProps } from './SqlResultTabs/ExecutionPlan/ISqlExecutionPlanViewProps.js';
+
diff --git a/webapp/packages/plugin-sql-editor/src/locales/en.ts b/webapp/packages/plugin-sql-editor/src/locales/en.ts
index 311762bf22..faed9e7eeb 100644
--- a/webapp/packages/plugin-sql-editor/src/locales/en.ts
+++ b/webapp/packages/plugin-sql-editor/src/locales/en.ts
@@ -27,12 +27,13 @@ export default [
['sql_editor_sql_statistics_unavailable', 'Statistics is not available'],
['sql_editor_sql_execution_executed_queries', 'Executed queries:'],
['sql_editor_sql_execution_executing', 'Executing...'],
- ['sql_execution_plan_placeholder', 'Execution plan is empty'],
- ['sql_execution_plan_properties_panel_placeholder', 'There are no items to show'],
- ['sql_execution_plan_properties_panel_name', 'Name'],
- ['sql_execution_plan_properties_panel_value', 'Value'],
- ['sql_execution_plan_properties_panel_general', 'General'],
- ['sql_execution_plan_properties_panel_details', 'Details'],
+ ['plugin_sql_execution_plan_placeholder', 'Execution plan is empty'],
+ ['plugin_sql_execution_plan_properties_panel_placeholder', 'There are no items to show'],
+ ['plugin_sql_execution_plan_properties_panel_name', 'Name'],
+ ['plugin_sql_execution_plan_properties_panel_value', 'Value'],
+ ['plugin_sql_execution_plan_properties_panel_general', 'General'],
+ ['plugin_sql_execution_plan_properties_panel_details', 'Details'],
+ ['plugin_sql_execution_plan_view_table', 'Table'],
['sql_editor_upload_script_tooltip', 'Upload sql script'],
['sql_editor_download_script_tooltip', 'Download sql script'],
[
diff --git a/webapp/packages/plugin-sql-editor/src/locales/fr.ts b/webapp/packages/plugin-sql-editor/src/locales/fr.ts
index 9f566bf708..2d633dc962 100644
--- a/webapp/packages/plugin-sql-editor/src/locales/fr.ts
+++ b/webapp/packages/plugin-sql-editor/src/locales/fr.ts
@@ -31,12 +31,13 @@ export default [
['sql_editor_lock_button', "Verrouiller l'éditeur"],
['sql_editor_sql_statistics_unavailable', 'Les statistiques SQL ne sont pas disponibles'],
['sql_editor_queries_tab_title', 'Requêtes exécutées'],
- ['sql_execution_plan_placeholder', "Le plan d'exécution est vide"],
- ['sql_execution_plan_properties_panel_placeholder', 'Aucun élément à afficher'],
- ['sql_execution_plan_properties_panel_name', 'Nom'],
- ['sql_execution_plan_properties_panel_value', 'Valeur'],
- ['sql_execution_plan_properties_panel_general', 'Général'],
- ['sql_execution_plan_properties_panel_details', 'Détails'],
+ ['plugin_sql_execution_plan_placeholder', "Le plan d'exécution est vide"],
+ ['plugin_sql_execution_plan_properties_panel_placeholder', 'Aucun élément à afficher'],
+ ['plugin_sql_execution_plan_properties_panel_name', 'Nom'],
+ ['plugin_sql_execution_plan_properties_panel_value', 'Valeur'],
+ ['plugin_sql_execution_plan_properties_panel_general', 'Général'],
+ ['plugin_sql_execution_plan_properties_panel_details', 'Détails'],
+ ['plugin_sql_execution_plan_view_table', 'Tableau'],
['sql_editor_upload_script_tooltip', 'Télécharger le script SQL'],
['sql_editor_upload_script', 'Télécharger le script'],
['sql_editor_upload_script_unsaved_changes_dialog_message', "Certains fichiers n'ont pas été enregistrés. Voulez-vous d'abord les enregistrer ?"],
diff --git a/webapp/packages/plugin-sql-editor/src/locales/it.ts b/webapp/packages/plugin-sql-editor/src/locales/it.ts
index cf2c12f840..0833b07197 100644
--- a/webapp/packages/plugin-sql-editor/src/locales/it.ts
+++ b/webapp/packages/plugin-sql-editor/src/locales/it.ts
@@ -27,12 +27,13 @@ export default [
['sql_editor_sql_statistics_unavailable', 'Statistiche non disponibili'],
['sql_editor_sql_execution_executed_queries', 'Executed queries:'],
['sql_editor_sql_execution_executing', 'Esecuzione in corso...'],
- ['sql_execution_plan_placeholder', 'Piano di esecuzione vuoto'],
- ['sql_execution_plan_properties_panel_placeholder', 'Non ci sono elementi da mostrare'],
- ['sql_execution_plan_properties_panel_name', 'Nome'],
- ['sql_execution_plan_properties_panel_value', 'Valore'],
- ['sql_execution_plan_properties_panel_general', 'Generale'],
- ['sql_execution_plan_properties_panel_details', 'Dettagli'],
+ ['plugin_sql_execution_plan_placeholder', 'Piano di esecuzione vuoto'],
+ ['plugin_sql_execution_plan_properties_panel_placeholder', 'Non ci sono elementi da mostrare'],
+ ['plugin_sql_execution_plan_properties_panel_name', 'Nome'],
+ ['plugin_sql_execution_plan_properties_panel_value', 'Valore'],
+ ['plugin_sql_execution_plan_properties_panel_general', 'Generale'],
+ ['plugin_sql_execution_plan_properties_panel_details', 'Dettagli'],
+ ['plugin_sql_execution_plan_view_table', 'Tabella'],
['sql_editor_close_result_tabs_dialog_title', 'Confirm closing tabs'],
['plugin_sql_editor_action_overlay_title', 'Action required'],
['plugin_sql_editor_action_overlay_description', 'Please reopen editor to continue working.'],
diff --git a/webapp/packages/plugin-sql-editor/src/locales/ru.ts b/webapp/packages/plugin-sql-editor/src/locales/ru.ts
index 0e16614799..3fc919c7ed 100644
--- a/webapp/packages/plugin-sql-editor/src/locales/ru.ts
+++ b/webapp/packages/plugin-sql-editor/src/locales/ru.ts
@@ -27,12 +27,13 @@ export default [
['sql_editor_sql_statistics_unavailable', 'Статистика не доступна'],
['sql_editor_sql_execution_executed_queries', 'Выполненные запросы:'],
['sql_editor_sql_execution_executing', 'Выполняется...'],
- ['sql_execution_plan_placeholder', 'План выполнения пуст'],
- ['sql_execution_plan_properties_panel_placeholder', 'Информация не доступна'],
- ['sql_execution_plan_properties_panel_name', 'Название'],
- ['sql_execution_plan_properties_panel_value', 'Значение'],
- ['sql_execution_plan_properties_panel_general', 'Общие'],
- ['sql_execution_plan_properties_panel_details', 'Дополнительные'],
+ ['plugin_sql_execution_plan_placeholder', 'План выполнения пуст'],
+ ['plugin_sql_execution_plan_properties_panel_placeholder', 'Информация не доступна'],
+ ['plugin_sql_execution_plan_properties_panel_name', 'Название'],
+ ['plugin_sql_execution_plan_properties_panel_value', 'Значение'],
+ ['plugin_sql_execution_plan_properties_panel_general', 'Общие'],
+ ['plugin_sql_execution_plan_properties_panel_details', 'Дополнительные'],
+ ['plugin_sql_execution_plan_view_table', 'Таблица'],
['sql_editor_upload_script_tooltip', 'Загрузить sql скрипт'],
['sql_editor_download_script_tooltip', 'Скачать sql скрипт'],
['sql_editor_upload_script_unsaved_changes_dialog_message', 'Текущий скрипт будет перезаписан загруженным. Сохранить текущий?'],
diff --git a/webapp/packages/plugin-sql-editor/src/locales/vi.ts b/webapp/packages/plugin-sql-editor/src/locales/vi.ts
index 513f0746d9..111b4b62b0 100644
--- a/webapp/packages/plugin-sql-editor/src/locales/vi.ts
+++ b/webapp/packages/plugin-sql-editor/src/locales/vi.ts
@@ -27,12 +27,13 @@ export default [
['sql_editor_sql_statistics_unavailable', 'Thống kê không khả dụng'],
['sql_editor_sql_execution_executed_queries', 'Các truy vấn đã thực thi:'],
['sql_editor_sql_execution_executing', 'Đang thực thi...'],
- ['sql_execution_plan_placeholder', 'Kế hoạch thực thi trống'],
- ['sql_execution_plan_properties_panel_placeholder', 'Không có mục nào để hiển thị'],
- ['sql_execution_plan_properties_panel_name', 'Tên'],
- ['sql_execution_plan_properties_panel_value', 'Giá trị'],
- ['sql_execution_plan_properties_panel_general', 'Chung'],
- ['sql_execution_plan_properties_panel_details', 'Chi tiết'],
+ ['plugin_sql_execution_plan_placeholder', 'Kế hoạch thực thi trống'],
+ ['plugin_sql_execution_plan_properties_panel_placeholder', 'Không có mục nào để hiển thị'],
+ ['plugin_sql_execution_plan_properties_panel_name', 'Tên'],
+ ['plugin_sql_execution_plan_properties_panel_value', 'Giá trị'],
+ ['plugin_sql_execution_plan_properties_panel_general', 'Chung'],
+ ['plugin_sql_execution_plan_properties_panel_details', 'Chi tiết'],
+ ['plugin_sql_execution_plan_view_table', 'Bảng'],
['sql_editor_upload_script_tooltip', 'Tải lên kịch bản SQL'],
['sql_editor_download_script_tooltip', 'Tải xuống kịch bản SQL'],
[
diff --git a/webapp/packages/plugin-sql-editor/src/locales/zh.ts b/webapp/packages/plugin-sql-editor/src/locales/zh.ts
index 7cec11ca77..4a04931be1 100644
--- a/webapp/packages/plugin-sql-editor/src/locales/zh.ts
+++ b/webapp/packages/plugin-sql-editor/src/locales/zh.ts
@@ -27,12 +27,13 @@ export default [
['sql_editor_sql_statistics_unavailable', '统计不可用'],
['sql_editor_sql_execution_queries', '查询:'],
['sql_editor_sql_execution_executing', '执行...'],
- ['sql_execution_plan_placeholder', '执行计划为空'],
- ['sql_execution_plan_properties_panel_placeholder', '没有要显示的项目'],
- ['sql_execution_plan_properties_panel_name', '名称'],
- ['sql_execution_plan_properties_panel_value', '值'],
- ['sql_execution_plan_properties_panel_general', '一般'],
- ['sql_execution_plan_properties_panel_details', '详情'],
+ ['plugin_sql_execution_plan_placeholder', '执行计划为空'],
+ ['plugin_sql_execution_plan_properties_panel_placeholder', '没有要显示的项目'],
+ ['plugin_sql_execution_plan_properties_panel_name', '名称'],
+ ['plugin_sql_execution_plan_properties_panel_value', '值'],
+ ['plugin_sql_execution_plan_properties_panel_general', '一般'],
+ ['plugin_sql_execution_plan_properties_panel_details', '详情'],
+ ['plugin_sql_execution_plan_view_table', '表格'],
['sql_editor_upload_script_tooltip', '上传SQL脚本'],
['sql_editor_download_script_tooltip', '下载SQL脚本'],
['sql_editor_upload_script_unsaved_changes_dialog_message', '您当前的脚本将被上传的脚本覆盖。要先保存吗?'],
diff --git a/webapp/packages/plugin-sql-editor/src/module.ts b/webapp/packages/plugin-sql-editor/src/module.ts
index 7b4d16819d..3cf6b6541e 100644
--- a/webapp/packages/plugin-sql-editor/src/module.ts
+++ b/webapp/packages/plugin-sql-editor/src/module.ts
@@ -1,6 +1,6 @@
/*
* CloudBeaver - Cloud Database Manager
- * Copyright (C) 2020-2025 DBeaver Corp and others
+ * Copyright (C) 2020-2026 DBeaver Corp and others
*
* Licensed under the Apache License, Version 2.0.
* you may not use this file except in compliance with the License.
@@ -15,6 +15,8 @@ import { OutputLogsService } from './SqlResultTabs/OutputLogs/OutputLogsService.
import { OutputLogsResource } from './SqlResultTabs/OutputLogs/OutputLogsResource.js';
import { OutputLogsEventHandler } from './SqlResultTabs/OutputLogs/OutputLogsEventHandler.js';
import { SqlExecutionPlanService } from './SqlResultTabs/ExecutionPlan/SqlExecutionPlanService.js';
+import { SqlExecutionPlanViewService } from './SqlResultTabs/ExecutionPlan/SqlExecutionPlanViewService.js';
+import { SqlExecutionPlanViewBootstrap } from './SqlResultTabs/ExecutionPlan/SqlExecutionPlanViewBootstrap.js';
import { SqlEditorView } from './SqlEditorView.js';
import { SqlEditorSettingsService } from './SqlEditorSettingsService.js';
import { SqlEditorService } from './SqlEditorService.js';
@@ -49,6 +51,8 @@ export default ModuleRegistry.add({
.addSingleton(OutputLogsResource)
.addSingleton(OutputLogsEventHandler)
.addSingleton(SqlExecutionPlanService)
+ .addSingleton(SqlExecutionPlanViewService)
+ .addSingleton(Bootstrap, SqlExecutionPlanViewBootstrap)
.addSingleton(SqlEditorView)
.addSingleton(SqlEditorSettingsService)
.addSingleton(SqlEditorService)
diff --git a/webapp/yarn.lock b/webapp/yarn.lock
index eba0f28e25..035ded3ebc 100644
--- a/webapp/yarn.lock
+++ b/webapp/yarn.lock
@@ -2260,6 +2260,7 @@ __metadata:
"@cloudbeaver/tests-runner": "workspace:*"
"@cloudbeaver/tsconfig": "workspace:*"
"@dbeaver/cli": "workspace:*"
+ "@dbeaver/js-helpers": "workspace:*"
"@dbeaver/react-tests": "workspace:*"
"@timohausmann/quadtree-ts": "npm:^2"
"@types/md5": "npm:^2"