Skip to content

Commit 4f796e5

Browse files
sergeyteleshevEvgeniaBzzzdariamarutkina
authored
[CB] Add Ask AI Feature for the Execution Plan (#4326)
* dbeaver/pro#9046 adds vertical tabs for execution plan to add more space for new button or panel with buttons * adds ask AI feature for execution plan * removes editor id and uses context state * makes ai feature spotlighted in the ui * rotates the icon also * removes bold label --------- Co-authored-by: Evgenia <139753579+EvgeniaBzzz@users.noreply.github.com> Co-authored-by: Daria Marutkina <125263541+dariamarutkina@users.noreply.github.com>
1 parent fb6f3c8 commit 4f796e5

11 files changed

Lines changed: 217 additions & 4 deletions
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/*
2+
* CloudBeaver - Cloud Database Manager
3+
* Copyright (C) 2020-2026 DBeaver Corp and others
4+
*
5+
* Licensed under the Apache License, Version 2.0.
6+
* you may not use this file except in compliance with the License.
7+
*/
8+
import { createDataContext } from '@cloudbeaver/core-data-context';
9+
10+
import type { IExecutionPlanTab } from '../../ISqlEditorTabState.js';
11+
12+
export const DATA_CONTEXT_SQL_EXECUTION_PLAN_TAB = createDataContext<IExecutionPlanTab>('sql-execution-plan-tab');
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
/*
2+
* CloudBeaver - Cloud Database Manager
3+
* Copyright (C) 2020-2026 DBeaver Corp and others
4+
*
5+
* Licensed under the Apache License, Version 2.0.
6+
* you may not use this file except in compliance with the License.
7+
*/
8+
import { createMenu } from '@cloudbeaver/core-view';
9+
10+
export const SQL_EXECUTION_PLAN_ACTIONS_MENU = createMenu('sql-execution-plan-actions', { label: '' });
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
* CloudBeaver - Cloud Database Manager
3+
* Copyright (C) 2020-2026 DBeaver Corp and others
4+
*
5+
* Licensed under the Apache License, Version 2.0.
6+
* you may not use this file except in compliance with the License.
7+
*/
8+
9+
.executionPlanActions {
10+
display: flex;
11+
flex-direction: column;
12+
}
13+
14+
.executionPlanActions.menuBar {
15+
height: unset;
16+
}
17+
18+
.executionPlanActions .menuBarItem {
19+
width: auto;
20+
height: auto;
21+
}
22+
23+
.executionPlanActions .menuBarItemBox {
24+
flex-direction: column-reverse;
25+
}
26+
27+
.executionPlanActions .menuBarItemIcon {
28+
transform: rotate(-90deg);
29+
}
30+
31+
.executionPlanActions .menuBarItemLabel {
32+
writing-mode: vertical-rl;
33+
text-orientation: mixed;
34+
transform: rotate(180deg);
35+
white-space: nowrap;
36+
font-weight: normal;
37+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/*
2+
* CloudBeaver - Cloud Database Manager
3+
* Copyright (C) 2020-2026 DBeaver Corp and others
4+
*
5+
* Licensed under the Apache License, Version 2.0.
6+
* you may not use this file except in compliance with the License.
7+
*/
8+
import { observer } from 'mobx-react-lite';
9+
10+
import { s, SContext, type StyleRegistry, useS } from '@cloudbeaver/core-blocks';
11+
import type { IDataContext } from '@cloudbeaver/core-data-context';
12+
import { MenuBar, MenuBarGroupStyles, MenuBarItemStyles, MenuBarStyles } from '@cloudbeaver/core-ui';
13+
import { useMenu } from '@cloudbeaver/core-view';
14+
15+
import { SQL_EXECUTION_PLAN_ACTIONS_MENU } from './SQL_EXECUTION_PLAN_ACTIONS_MENU.js';
16+
import style from './SqlExecutionPlanActionsMenu.module.css';
17+
18+
const registry: StyleRegistry = [
19+
[
20+
MenuBarStyles,
21+
{
22+
mode: 'append',
23+
styles: [style],
24+
},
25+
],
26+
[
27+
MenuBarItemStyles,
28+
{
29+
mode: 'append',
30+
styles: [style],
31+
},
32+
],
33+
];
34+
35+
interface Props {
36+
context: IDataContext;
37+
}
38+
39+
export const SqlExecutionPlanActionsMenu = observer<Props>(function SqlExecutionPlanActionsMenu({ context }) {
40+
const menuBarStyles = useS(style, MenuBarStyles, MenuBarItemStyles, MenuBarGroupStyles);
41+
const menu = useMenu({ menu: SQL_EXECUTION_PLAN_ACTIONS_MENU, context });
42+
43+
if (!menu.items.length) {
44+
return null;
45+
}
46+
47+
return (
48+
<SContext registry={registry}>
49+
<MenuBar
50+
menu={menu}
51+
className={s(menuBarStyles, { toolsMenu: true, floating: true, withLabel: true, executionPlanActions: true })}
52+
compact={false}
53+
/>
54+
</SContext>
55+
);
56+
});

webapp/packages/plugin-sql-editor/src/SqlResultTabs/ExecutionPlan/SqlExecutionPlanPanel.module.css

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,28 @@
66
* you may not use this file except in compliance with the License.
77
*/
88

9+
.tabsLayout {
10+
display: flex;
11+
flex-direction: row;
12+
flex: 1;
13+
overflow: hidden;
14+
height: 100%;
15+
}
16+
17+
.actionsBar {
18+
composes: theme-border-color-background from global;
19+
display: flex;
20+
flex-direction: column;
21+
align-items: center;
22+
overflow: auto;
23+
border-right: solid 1px;
24+
}
25+
26+
.tabPanelList {
27+
flex: 1;
28+
overflow: hidden;
29+
}
30+
931
.pane {
1032
&:first-child {
1133
display: flex;

webapp/packages/plugin-sql-editor/src/SqlResultTabs/ExecutionPlan/SqlExecutionPlanPanel.tsx

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,18 @@ import { observer } from 'mobx-react-lite';
99
import { useState } from 'react';
1010

1111
import { Loader, Pane, ResizerControls, s, Split, useS, useSplitUserState } from '@cloudbeaver/core-blocks';
12+
import { useDataContextLink } from '@cloudbeaver/core-data-context';
1213
import { useService } from '@cloudbeaver/core-di';
13-
import { TabList, TabPanelList, TabsState } from '@cloudbeaver/core-ui';
14+
import { TabPanelList, TabsState } from '@cloudbeaver/core-ui';
15+
import { useMenu } from '@cloudbeaver/core-view';
1416

1517
import type { IExecutionPlanTab } from '../../ISqlEditorTabState.js';
1618
import { PropertiesPanel } from './PropertiesPanel/PropertiesPanel.js';
19+
import { DATA_CONTEXT_SQL_EXECUTION_PLAN_TAB } from './DATA_CONTEXT_SQL_EXECUTION_PLAN_TAB.js';
20+
import { SQL_EXECUTION_PLAN_ACTIONS_MENU } from './SQL_EXECUTION_PLAN_ACTIONS_MENU.js';
21+
import { SqlExecutionPlanActionsMenu } from './SqlExecutionPlanActionsMenu.js';
1722
import { SqlExecutionPlanService } from './SqlExecutionPlanService.js';
23+
import { SqlExecutionPlanViewBar } from './SqlExecutionPlanViewBar.js';
1824
import { SqlExecutionPlanViewService } from './SqlExecutionPlanViewService.js';
1925
import style from './SqlExecutionPlanPanel.module.css';
2026

@@ -29,6 +35,11 @@ export const SqlExecutionPlanPanel = observer<Props>(function SqlExecutionPlanPa
2935
const data = sqlExecutionPlanService.data.get(executionPlanTab.tabId);
3036
const [selectedNode, setSelectedNode] = useState<string | null>(null);
3137
const splitState = useSplitUserState('execution-plan');
38+
const menu = useMenu({ menu: SQL_EXECUTION_PLAN_ACTIONS_MENU });
39+
40+
useDataContextLink(menu.context, (context, id) => {
41+
context.set(DATA_CONTEXT_SQL_EXECUTION_PLAN_TAB, executionPlanTab, id);
42+
});
3243

3344
if (data?.task.executing || !data?.executionPlan) {
3445
return <Loader cancelDisabled={!data?.task.cancellable} onCancel={() => data?.task.cancel()} />;
@@ -45,8 +56,13 @@ export const SqlExecutionPlanPanel = observer<Props>(function SqlExecutionPlanPa
4556
lazy
4657
onNodeSelect={setSelectedNode}
4758
>
48-
<TabList underline />
49-
<TabPanelList />
59+
<div className={s(styles, { tabsLayout: true })}>
60+
<div className={s(styles, { actionsBar: true })}>
61+
<SqlExecutionPlanActionsMenu context={menu.context} />
62+
</div>
63+
<TabPanelList className={s(styles, { tabPanelList: true })} />
64+
<SqlExecutionPlanViewBar />
65+
</div>
5066
</TabsState>
5167
</Pane>
5268
<ResizerControls />

webapp/packages/plugin-sql-editor/src/SqlResultTabs/ExecutionPlan/SqlExecutionPlanService.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
* CloudBeaver - Cloud Database Manager
3-
* Copyright (C) 2020-2025 DBeaver Corp and others
3+
* Copyright (C) 2020-2026 DBeaver Corp and others
44
*
55
* Licensed under the Apache License, Version 2.0.
66
* you may not use this file except in compliance with the License.
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
* CloudBeaver - Cloud Database Manager
3+
* Copyright (C) 2020-2026 DBeaver Corp and others
4+
*
5+
* Licensed under the Apache License, Version 2.0.
6+
* you may not use this file except in compliance with the License.
7+
*/
8+
9+
.tabBar {
10+
composes: theme-background-secondary theme-text-on-secondary from global;
11+
overflow-x: hidden;
12+
padding-top: 4px;
13+
}
14+
15+
.tab {
16+
composes: theme-ripple theme-background-background theme-text-text-primary-on-light theme-typography--body2 from global;
17+
text-transform: uppercase;
18+
font-weight: normal;
19+
20+
&:global([aria-selected='true']) {
21+
font-weight: normal !important;
22+
}
23+
}
24+
25+
.tabList {
26+
margin-right: 8px;
27+
margin-left: 4px;
28+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
* CloudBeaver - Cloud Database Manager
3+
* Copyright (C) 2020-2026 DBeaver Corp and others
4+
*
5+
* Licensed under the Apache License, Version 2.0.
6+
* you may not use this file except in compliance with the License.
7+
*/
8+
import { s, SContext, type StyleRegistry, useS } from '@cloudbeaver/core-blocks';
9+
import { TabList, TabListStyles, TabStyles } from '@cloudbeaver/core-ui';
10+
11+
import style from './SqlExecutionPlanViewBar.module.css';
12+
13+
const registry: StyleRegistry = [
14+
[TabListStyles, { mode: 'append', styles: [style] }],
15+
[TabStyles, { mode: 'append', styles: [style] }],
16+
];
17+
18+
export function SqlExecutionPlanViewBar() {
19+
const styles = useS(style);
20+
21+
return (
22+
<div className={s(styles, { tabBar: true })}>
23+
<SContext registry={registry}>
24+
<TabList vertical rotated />
25+
</SContext>
26+
</div>
27+
);
28+
}

webapp/packages/plugin-sql-editor/src/SqlResultTabs/ExecutionPlan/SqlExecutionPlanViewBootstrap.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ export class SqlExecutionPlanViewBootstrap extends Bootstrap {
2323
this.sqlExecutionPlanViewService.tabs.add({
2424
key: 'table',
2525
name: 'plugin_sql_execution_plan_view_table',
26+
icon: 'table-icon',
2627
order: 0,
2728
panel: () => ExecutionPlanTreeView,
2829
});

0 commit comments

Comments
 (0)