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>
@@ -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<T extends LocalizationToken | undefined>(token: T, fallback?: T): T {
|
||||
return fallback || token;
|
||||
export function interpolateTranslation(template: string, args?: Record<string | number, unknown>): 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 = <T extends LocalizationToken | undefined>(token: T, fallback?: T, args?: Record<string | number, any>) => T;
|
||||
export function defaultTranslateFn<T extends LocalizationToken | undefined>(token: T, fallback?: T, args?: Record<string | number, unknown>): T {
|
||||
const result = fallback || token;
|
||||
if (result && args) {
|
||||
return interpolateTranslation(result as string, args) as T;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
export type TranslateFn = <T extends LocalizationToken | undefined>(token: T, fallback?: T, args?: Record<string | number, unknown>) => T;
|
||||
export const TranslateContext = createContext<{ translate: TranslateFn }>({
|
||||
translate: (key, fallback) => fallback || key,
|
||||
translate: defaultTranslateFn,
|
||||
});
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -16,3 +16,4 @@ export * from './memoizeLast.js';
|
||||
export * from './mutex.js';
|
||||
export * from './reorderArray.js';
|
||||
export * from './getLocalizedDisplayName.js';
|
||||
export * from './formatNumber.js';
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -13,6 +13,9 @@
|
||||
{
|
||||
"path": "../../common-typescript/@dbeaver/cli"
|
||||
},
|
||||
{
|
||||
"path": "../../common-typescript/@dbeaver/js-helpers"
|
||||
},
|
||||
{
|
||||
"path": "../core-cli"
|
||||
},
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M10.5 6.5C10.5 8.70914 8.70914 10.5 6.5 10.5C4.29086 10.5 2.5 8.70914 2.5 6.5C2.5 4.29086 4.29086 2.5 6.5 2.5C8.70914 2.5 10.5 4.29086 10.5 6.5ZM9.68256 10.9862C8.78427 11.6246 7.68597 12 6.5 12C3.46243 12 1 9.53757 1 6.5C1 3.46243 3.46243 1 6.5 1C9.53757 1 12 3.46243 12 6.5C12 7.88792 11.4859 9.15577 10.6378 10.1235L10.7678 10.1464L15.0104 14.3891L13.9497 15.4497L9.70711 11.2071L9.68256 10.9862ZM4.8 7.29999V5.79999H5.8V4.79999H7.3V5.79999H8.3V7.29999H7.3V8.29999H5.8V7.29999H4.8Z" fill="#398FCA"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 655 B |
@@ -1,3 +0,0 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M6.5 10.5C8.70914 10.5 10.5 8.70914 10.5 6.5C10.5 4.29086 8.70914 2.5 6.5 2.5C4.29086 2.5 2.5 4.29086 2.5 6.5C2.5 8.70914 4.29086 10.5 6.5 10.5ZM6.5 12C7.68597 12 8.78427 11.6246 9.68256 10.9862L9.70711 11.2071L13.9497 15.4497L15.0104 14.3891L10.7678 10.1464L10.6378 10.1235C11.4859 9.15577 12 7.88792 12 6.5C12 3.46243 9.53757 1 6.5 1C3.46243 1 1 3.46243 1 6.5C1 9.53757 3.46243 12 6.5 12ZM4.8 5.79999V7.29999H8.3V5.79999H4.8Z" fill="#398FCA"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 598 B |
@@ -0,0 +1,11 @@
|
||||
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_7928_11650)">
|
||||
<path d="M12.0001 3.00001C16.9601 3.00001 21.0001 7.04003 21.0001 12.0001C21.0001 16.9601 16.9601 21.0001 12.0001 21.0001C7.04003 21.0001 3.00001 16.9601 3.00001 12.0001C3.00001 7.04003 7.04003 3.00001 12.0001 3.00001ZM12.0001 1C5.92002 1 1 5.92002 1 12.0001C1 18.0801 5.92002 23.0001 12.0001 23.0001C18.0801 23.0001 23.0001 18.0801 23.0001 12.0001C23.0001 5.92002 18.0801 1 12.0001 1Z" fill="#3387C5"/>
|
||||
<path d="M19 19L30.0001 30" stroke="#3387C5" stroke-width="2" stroke-miterlimit="10"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_7928_11650">
|
||||
<rect width="32" height="32" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 742 B |
@@ -0,0 +1,13 @@
|
||||
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_7923_11529)">
|
||||
<path d="M12.0001 3.00001C16.9601 3.00001 21.0001 7.04003 21.0001 12.0001C21.0001 16.9601 16.9601 21.0001 12.0001 21.0001C7.04003 21.0001 3.00001 16.9601 3.00001 12.0001C3.00001 7.04003 7.04003 3.00001 12.0001 3.00001ZM12.0001 1C5.92002 1 1 5.92002 1 12.0001C1 18.0801 5.92002 23.0001 12.0001 23.0001C18.0801 23.0001 23.0001 18.0801 23.0001 12.0001C23.0001 5.92002 18.0801 1 12.0001 1Z" fill="#3387C5"/>
|
||||
<path d="M19 19L30.0001 30" stroke="#3387C5" stroke-width="2" stroke-miterlimit="10"/>
|
||||
<path d="M13 6H11V18.0001H13V6Z" fill="#3387C5"/>
|
||||
<path d="M18.0001 11H6V13H18.0001V11Z" fill="#3387C5"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_7923_11529">
|
||||
<rect width="32" height="32" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 848 B |
@@ -0,0 +1,13 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_7923_11590)">
|
||||
<path d="M9.64291 2.57142C13.5401 2.57142 16.7144 5.74569 16.7144 9.64282C16.7144 13.5399 13.5401 16.7142 9.64291 16.7142C5.74574 16.7142 2.57144 13.5399 2.57144 9.64282C2.57144 5.74569 5.74574 2.57142 9.64291 2.57142ZM9.64291 1C4.86574 1 1 4.8657 1 9.64282C1 14.4199 4.86574 18.2856 9.64291 18.2856C14.4201 18.2856 18.2858 14.4199 18.2858 9.64282C18.2858 4.8657 14.4201 1 9.64291 1Z" fill="#3387C5"/>
|
||||
<path d="M15.1426 15.1426L22.9998 22.9997" stroke="#3387C5" stroke-width="1.5" stroke-miterlimit="10"/>
|
||||
<path d="M10.4279 4.92871H8.85645V14.3572H10.4279V4.92871Z" fill="#3387C5"/>
|
||||
<path d="M14.3573 8.85645H4.92871V10.4279H14.3573V8.85645Z" fill="#3387C5"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_7923_11590">
|
||||
<rect width="24" height="24" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 911 B |
@@ -0,0 +1,18 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_7923_11544)">
|
||||
<g clip-path="url(#clip1_7923_11544)">
|
||||
<path d="M6.28559 1.14283C9.11982 1.14283 11.4283 3.45136 11.4283 6.28559C11.4283 9.11982 9.11982 11.4283 6.28559 11.4283C3.45136 11.4283 1.14283 9.11982 1.14283 6.28559C1.14283 3.45136 3.45136 1.14283 6.28559 1.14283ZM6.28559 0C2.81137 0 0 2.81137 0 6.28559C0 9.7598 2.81137 12.5712 6.28559 12.5712C9.7598 12.5712 12.5712 9.7598 12.5712 6.28559C12.5712 2.81137 9.7598 0 6.28559 0Z" fill="#3387C5"/>
|
||||
<path d="M10.2861 10.2861L16.0003 16.0003" stroke="#3387C5" stroke-miterlimit="10"/>
|
||||
<path d="M6.85768 2.85645H5.71484V9.71345H6.85768V2.85645Z" fill="#3387C5"/>
|
||||
<path d="M9.71345 5.71484H2.85645V6.85768H9.71345V5.71484Z" fill="#3387C5"/>
|
||||
</g>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_7923_11544">
|
||||
<rect width="16" height="16" fill="white"/>
|
||||
</clipPath>
|
||||
<clipPath id="clip1_7923_11544">
|
||||
<rect width="16" height="16" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1023 B |
@@ -0,0 +1,11 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_7928_11656)">
|
||||
<path d="M9.64291 2.57142C13.5401 2.57142 16.7144 5.74569 16.7144 9.64282C16.7144 13.5399 13.5401 16.7142 9.64291 16.7142C5.74574 16.7142 2.57144 13.5399 2.57144 9.64282C2.57144 5.74569 5.74574 2.57142 9.64291 2.57142ZM9.64291 1C4.86574 1 1 4.8657 1 9.64282C1 14.4199 4.86574 18.2856 9.64291 18.2856C14.4201 18.2856 18.2858 14.4199 18.2858 9.64282C18.2858 4.8657 14.4201 1 9.64291 1Z" fill="#3387C5"/>
|
||||
<path d="M15.1426 15.1426L22.9998 22.9997" stroke="#3387C5" stroke-width="1.5" stroke-miterlimit="10"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_7928_11656">
|
||||
<rect width="24" height="24" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 757 B |
@@ -0,0 +1,12 @@
|
||||
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_7928_11629)">
|
||||
<path d="M12.0001 3.00001C16.9601 3.00001 21.0001 7.04003 21.0001 12.0001C21.0001 16.9601 16.9601 21.0001 12.0001 21.0001C7.04003 21.0001 3.00001 16.9601 3.00001 12.0001C3.00001 7.04003 7.04003 3.00001 12.0001 3.00001ZM12.0001 1C5.92002 1 1 5.92002 1 12.0001C1 18.0801 5.92002 23.0001 12.0001 23.0001C18.0801 23.0001 23.0001 18.0801 23.0001 12.0001C23.0001 5.92002 18.0801 1 12.0001 1Z" fill="#3387C5"/>
|
||||
<path d="M19 19L30.0001 30" stroke="#3387C5" stroke-width="2" stroke-miterlimit="10"/>
|
||||
<path d="M18.0001 11H6V13H18.0001V11Z" fill="#3387C5"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_7928_11629">
|
||||
<rect width="32" height="32" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 798 B |
@@ -0,0 +1,12 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_7928_11636)">
|
||||
<path d="M9.64291 2.57142C13.5401 2.57142 16.7144 5.74569 16.7144 9.64282C16.7144 13.5399 13.5401 16.7142 9.64291 16.7142C5.74574 16.7142 2.57144 13.5399 2.57144 9.64282C2.57144 5.74569 5.74574 2.57142 9.64291 2.57142ZM9.64291 1C4.86574 1 1 4.8657 1 9.64282C1 14.4199 4.86574 18.2856 9.64291 18.2856C14.4201 18.2856 18.2858 14.4199 18.2858 9.64282C18.2858 4.8657 14.4201 1 9.64291 1Z" fill="#3387C5"/>
|
||||
<path d="M15.1426 15.1426L22.9998 22.9997" stroke="#3387C5" stroke-width="1.5" stroke-miterlimit="10"/>
|
||||
<path d="M14.3573 8.85645H4.92871V10.4279H14.3573V8.85645Z" fill="#3387C5"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_7928_11636">
|
||||
<rect width="24" height="24" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 834 B |
@@ -0,0 +1,17 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_7928_11643)">
|
||||
<g clip-path="url(#clip1_7928_11643)">
|
||||
<path d="M6.28559 1.14283C9.11982 1.14283 11.4283 3.45136 11.4283 6.28559C11.4283 9.11982 9.11982 11.4283 6.28559 11.4283C3.45136 11.4283 1.14283 9.11982 1.14283 6.28559C1.14283 3.45136 3.45136 1.14283 6.28559 1.14283ZM6.28559 0C2.81137 0 0 2.81137 0 6.28559C0 9.7598 2.81137 12.5712 6.28559 12.5712C9.7598 12.5712 12.5712 9.7598 12.5712 6.28559C12.5712 2.81137 9.7598 0 6.28559 0Z" fill="#3387C5"/>
|
||||
<path d="M10.2861 10.2861L16.0003 16.0003" stroke="#3387C5" stroke-miterlimit="10"/>
|
||||
<path d="M9.71345 5.71484H2.85645V6.85768H9.71345V5.71484Z" fill="#3387C5"/>
|
||||
</g>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_7928_11643">
|
||||
<rect width="16" height="16" fill="white"/>
|
||||
</clipPath>
|
||||
<clipPath id="clip1_7928_11643">
|
||||
<rect width="16" height="16" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 946 B |
@@ -0,0 +1,16 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_7928_11662)">
|
||||
<g clip-path="url(#clip1_7928_11662)">
|
||||
<path d="M6.28559 1.14283C9.11982 1.14283 11.4283 3.45136 11.4283 6.28559C11.4283 9.11982 9.11982 11.4283 6.28559 11.4283C3.45136 11.4283 1.14283 9.11982 1.14283 6.28559C1.14283 3.45136 3.45136 1.14283 6.28559 1.14283ZM6.28559 0C2.81137 0 0 2.81137 0 6.28559C0 9.7598 2.81137 12.5712 6.28559 12.5712C9.7598 12.5712 12.5712 9.7598 12.5712 6.28559C12.5712 2.81137 9.7598 0 6.28559 0Z" fill="#3387C5"/>
|
||||
<path d="M10.2861 10.2861L16.0003 16.0003" stroke="#3387C5" stroke-miterlimit="10"/>
|
||||
</g>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_7928_11662">
|
||||
<rect width="16" height="16" fill="white"/>
|
||||
</clipPath>
|
||||
<clipPath id="clip1_7928_11662">
|
||||
<rect width="16" height="16" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 869 B |
@@ -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',
|
||||
});
|
||||
|
||||
@@ -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',
|
||||
});
|
||||
|
||||
@@ -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<Props>(function ExecutionPlanTree
|
||||
</TableBody>
|
||||
</Table>
|
||||
) : (
|
||||
<TextPlaceholder>{translate('sql_execution_plan_placeholder')}</TextPlaceholder>
|
||||
<TextPlaceholder>{translate('plugin_sql_execution_plan_placeholder')}</TextPlaceholder>
|
||||
)}
|
||||
</Pane>
|
||||
<ResizerControls className={styles['resizerControls']} />
|
||||
|
||||
@@ -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<ISqlExecutionPlanViewProps>(function ExecutionPlanTreeView({
|
||||
nodes,
|
||||
query,
|
||||
onNodeSelect,
|
||||
}) {
|
||||
return <ExecutionPlanTreeBlock nodeList={nodes} query={query} onNodeSelect={onNodeSelect} />;
|
||||
});
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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<Props>(function PropertiesPanel({ select
|
||||
).get();
|
||||
|
||||
if (!general.length && !details.length) {
|
||||
return <TextPlaceholder>{translate('sql_execution_plan_properties_panel_placeholder')}</TextPlaceholder>;
|
||||
return <TextPlaceholder>{translate('plugin_sql_execution_plan_properties_panel_placeholder')}</TextPlaceholder>;
|
||||
}
|
||||
|
||||
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 (
|
||||
<Table className={className}>
|
||||
@@ -63,8 +63,12 @@ export const PropertiesPanel = observer<Props>(function PropertiesPanel({ select
|
||||
<TableColumnHeader title={valueColumnTitle}>{valueColumnTitle}</TableColumnHeader>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
{!!general.length && <PropertiesPanelItemsGroup properties={general} name={translate('sql_execution_plan_properties_panel_general')} />}
|
||||
{!!details.length && <PropertiesPanelItemsGroup properties={details} name={translate('sql_execution_plan_properties_panel_details')} />}
|
||||
{!!general.length && (
|
||||
<PropertiesPanelItemsGroup properties={general} name={translate('plugin_sql_execution_plan_properties_panel_general')} />
|
||||
)}
|
||||
{!!details.length && (
|
||||
<PropertiesPanelItemsGroup properties={details} name={translate('plugin_sql_execution_plan_properties_panel_details')} />
|
||||
)}
|
||||
</TableBody>
|
||||
</Table>
|
||||
);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<Props>(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<string | null>(null);
|
||||
const splitState = useSplitUserState('execution-plan');
|
||||
@@ -35,7 +37,17 @@ export const SqlExecutionPlanPanel = observer<Props>(function SqlExecutionPlanPa
|
||||
return (
|
||||
<Split {...splitState} mode={selectedNode ? splitState.mode : 'minimize'} disable={!selectedNode} sticky={30}>
|
||||
<Pane className={s(styles, { pane: true })}>
|
||||
<ExecutionPlanTreeBlock nodeList={data.executionPlan.nodes} query={data.executionPlan.query} onNodeSelect={setSelectedNode} />
|
||||
<TabsState
|
||||
container={sqlExecutionPlanViewService.tabs}
|
||||
nodes={data.executionPlan.nodes}
|
||||
query={data.executionPlan.query}
|
||||
selectedNode={selectedNode}
|
||||
lazy
|
||||
onNodeSelect={setSelectedNode}
|
||||
>
|
||||
<TabList underline />
|
||||
<TabPanelList />
|
||||
</TabsState>
|
||||
</Pane>
|
||||
<ResizerControls />
|
||||
<Pane className={s(styles, { pane: true })} basis="30%" main>
|
||||
|
||||
@@ -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,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -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<ISqlExecutionPlanViewProps>;
|
||||
|
||||
constructor() {
|
||||
this.tabs = new TabsContainer('Execution Plan Views');
|
||||
}
|
||||
}
|
||||
@@ -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';
|
||||
|
||||
|
||||
@@ -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'],
|
||||
[
|
||||
|
||||
@@ -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 ?"],
|
||||
|
||||
@@ -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.'],
|
||||
|
||||
@@ -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', 'Текущий скрипт будет перезаписан загруженным. Сохранить текущий?'],
|
||||
|
||||
@@ -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'],
|
||||
[
|
||||
|
||||
@@ -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', '您当前的脚本将被上传的脚本覆盖。要先保存吗?'],
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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"
|
||||
|
||||