mirror of
https://github.com/dbeaver/cloudbeaver.git
synced 2026-10-12 23:37:00 +08:00
CB-3300 feat: dataset editing (#1614)
* CB-3300 feat: dataset editing * CB-3300 chore: remove unused styles --------- Co-authored-by: mr-anton-t <42037741+mr-anton-t@users.noreply.github.com>
This commit is contained in:
@@ -22,6 +22,7 @@ import { KEY_BINDING_SQL_EDITOR_EXECUTE_SCRIPT } from './actions/bindings/KEY_BI
|
||||
import { KEY_BINDING_SQL_EDITOR_FORMAT } from './actions/bindings/KEY_BINDING_SQL_EDITOR_FORMAT';
|
||||
import { KEY_BINDING_SQL_EDITOR_SHOW_EXECUTION_PLAN } from './actions/bindings/KEY_BINDING_SQL_EDITOR_SHOW_EXECUTION_PLAN';
|
||||
import { ScriptPreviewService } from './ScriptPreview/ScriptPreviewService';
|
||||
import { ESqlDataSourceFeatures } from './SqlDataSource/ESqlDataSourceFeatures';
|
||||
import { DATA_CONTEXT_SQL_EDITOR_DATA } from './SqlEditor/DATA_CONTEXT_SQL_EDITOR_DATA';
|
||||
|
||||
@injectable()
|
||||
@@ -53,6 +54,29 @@ export class MenuBootstrap extends Bootstrap {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (
|
||||
!sqlEditorData.dataSource?.hasFeature(ESqlDataSourceFeatures.executable)
|
||||
&& [
|
||||
ACTION_SQL_EDITOR_EXECUTE,
|
||||
ACTION_SQL_EDITOR_EXECUTE_NEW,
|
||||
ACTION_SQL_EDITOR_EXECUTE_SCRIPT,
|
||||
ACTION_SQL_EDITOR_SHOW_EXECUTION_PLAN,
|
||||
].includes(action)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (
|
||||
!sqlEditorData.dataSource?.hasFeature(ESqlDataSourceFeatures.query)
|
||||
&& [
|
||||
ACTION_SQL_EDITOR_EXECUTE,
|
||||
ACTION_SQL_EDITOR_EXECUTE_NEW,
|
||||
ACTION_SQL_EDITOR_SHOW_EXECUTION_PLAN,
|
||||
].includes(action)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (
|
||||
[
|
||||
ACTION_SQL_EDITOR_EXECUTE,
|
||||
@@ -86,7 +110,13 @@ export class MenuBootstrap extends Bootstrap {
|
||||
this.keyBindingService.addKeyBindingHandler({
|
||||
id: 'sql-editor-execute-script',
|
||||
binding: KEY_BINDING_SQL_EDITOR_EXECUTE_SCRIPT,
|
||||
isBindingApplicable: (contexts, action) => action === ACTION_SQL_EDITOR_EXECUTE_SCRIPT,
|
||||
isBindingApplicable: (contexts, action) => {
|
||||
const sqlEditorData = contexts.tryGet(DATA_CONTEXT_SQL_EDITOR_DATA);
|
||||
return (
|
||||
action === ACTION_SQL_EDITOR_EXECUTE_SCRIPT
|
||||
&& sqlEditorData?.dataSource?.hasFeature(ESqlDataSourceFeatures.executable) === true
|
||||
);
|
||||
},
|
||||
handler: this.sqlEditorActionHandler.bind(this),
|
||||
});
|
||||
|
||||
|
||||
@@ -40,9 +40,10 @@ export abstract class BaseSqlDataSource implements ISqlDataSource {
|
||||
}
|
||||
|
||||
get features(): ESqlDataSourceFeatures[] {
|
||||
return [ESqlDataSourceFeatures.script];
|
||||
return [ESqlDataSourceFeatures.script, ESqlDataSourceFeatures.query, ESqlDataSourceFeatures.executable];
|
||||
}
|
||||
|
||||
protected saved: boolean;
|
||||
readonly history: ISqlDataSourceHistory;
|
||||
readonly onUpdate: ISyncExecutor;
|
||||
readonly onSetScript: ISyncExecutor<ISetScriptData>;
|
||||
@@ -57,6 +58,7 @@ export abstract class BaseSqlDataSource implements ISqlDataSource {
|
||||
this.message = undefined;
|
||||
this.outdated = true;
|
||||
this.editing = true;
|
||||
this.saved = true;
|
||||
this.history = new SqlDataSourceHistory();
|
||||
this.onUpdate = new SyncExecutor();
|
||||
this.onSetScript = new SyncExecutor();
|
||||
@@ -83,17 +85,24 @@ export abstract class BaseSqlDataSource implements ISqlDataSource {
|
||||
}
|
||||
|
||||
setScript(script: string, source?: string): void {
|
||||
this.saved = false;
|
||||
this.onSetScript.execute({ script, source });
|
||||
}
|
||||
|
||||
abstract canRename(name: string | null): boolean;
|
||||
|
||||
setName(name: string | null): void {
|
||||
this.onUpdate.execute();
|
||||
}
|
||||
|
||||
setExecutionContext(executionContext?: IConnectionExecutionContextInfo | undefined): void {
|
||||
this.onUpdate.execute();
|
||||
}
|
||||
|
||||
isSaved(): boolean {
|
||||
return this.saved;
|
||||
}
|
||||
|
||||
isError(): boolean {
|
||||
return isContainsException(this.exception);
|
||||
}
|
||||
@@ -146,6 +155,10 @@ export abstract class BaseSqlDataSource implements ISqlDataSource {
|
||||
this.onUpdate.execute();
|
||||
}
|
||||
|
||||
save(): Promise<void> | void { }
|
||||
load(): Promise<void> | void { }
|
||||
reset(): Promise<void> | void {
|
||||
this.saved = true;
|
||||
}
|
||||
dispose(): void | Promise<void> { }
|
||||
}
|
||||
@@ -8,6 +8,8 @@
|
||||
|
||||
export enum ESqlDataSourceFeatures {
|
||||
script,
|
||||
query,
|
||||
executable,
|
||||
setName,
|
||||
setProject
|
||||
}
|
||||
@@ -40,6 +40,7 @@ export interface ISqlDataSource extends ILoadableState {
|
||||
readonly features: ESqlDataSourceFeatures[];
|
||||
readonly history: ISqlDataSourceHistory;
|
||||
|
||||
isSaved(): boolean;
|
||||
isReadonly(): boolean;
|
||||
isEditing(): boolean;
|
||||
isOutdated(): boolean;
|
||||
@@ -52,6 +53,8 @@ export interface ISqlDataSource extends ILoadableState {
|
||||
setScript(script: string, source?: string): void;
|
||||
setEditing(state: boolean): void;
|
||||
setExecutionContext(executionContext?: IConnectionExecutionContextInfo): void;
|
||||
save(): Promise<void> | void;
|
||||
load(): Promise<void> | void;
|
||||
reset(): Promise<void> | void;
|
||||
dispose(): Promise<void> | void;
|
||||
}
|
||||
+10
-1
@@ -30,7 +30,12 @@ export class LocalStorageSqlDataSource extends BaseSqlDataSource {
|
||||
}
|
||||
|
||||
get features(): ESqlDataSourceFeatures[] {
|
||||
return [ESqlDataSourceFeatures.script, ESqlDataSourceFeatures.setName];
|
||||
return [
|
||||
ESqlDataSourceFeatures.script,
|
||||
ESqlDataSourceFeatures.query,
|
||||
ESqlDataSourceFeatures.executable,
|
||||
ESqlDataSourceFeatures.setName,
|
||||
];
|
||||
}
|
||||
|
||||
private readonly state: ILocalStorageSqlDataSourceState;
|
||||
@@ -47,6 +52,10 @@ export class LocalStorageSqlDataSource extends BaseSqlDataSource {
|
||||
});
|
||||
}
|
||||
|
||||
isSaved(): boolean {
|
||||
return true;
|
||||
}
|
||||
|
||||
isReadonly(): boolean {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -29,7 +29,12 @@ export class MemorySqlDataSource extends BaseSqlDataSource {
|
||||
}
|
||||
|
||||
get features(): ESqlDataSourceFeatures[] {
|
||||
return [ESqlDataSourceFeatures.script, ESqlDataSourceFeatures.setName];
|
||||
return [
|
||||
ESqlDataSourceFeatures.script,
|
||||
ESqlDataSourceFeatures.query,
|
||||
ESqlDataSourceFeatures.executable,
|
||||
ESqlDataSourceFeatures.setName,
|
||||
];
|
||||
}
|
||||
|
||||
private _name: string | null;
|
||||
@@ -55,6 +60,10 @@ export class MemorySqlDataSource extends BaseSqlDataSource {
|
||||
});
|
||||
}
|
||||
|
||||
isSaved(): boolean {
|
||||
return true;
|
||||
}
|
||||
|
||||
isReadonly(): boolean {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -44,9 +44,7 @@ export const SQL_EDITOR_ACTIONS_MENU_STYLES = css`
|
||||
}
|
||||
|
||||
& menu-bar-item-label {
|
||||
display: block;
|
||||
text-transform: uppercase;
|
||||
font-weight: 700;
|
||||
display: none;
|
||||
}
|
||||
|
||||
& IconOrImage + menu-bar-item-label, & Loader + menu-bar-item-label {
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2023 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 { createMenu } from '@cloudbeaver/core-view';
|
||||
|
||||
export const SQL_EDITOR_TOOLS_MENU = createMenu('sql-editor-tools', '');
|
||||
@@ -20,6 +20,7 @@ import { ESqlDataSourceFeatures } from '../SqlDataSource/ESqlDataSourceFeatures'
|
||||
import { ISqlEditorModeProps, SqlEditorModeService } from '../SqlEditorModeService';
|
||||
import { DATA_CONTEXT_SQL_EDITOR_DATA } from './DATA_CONTEXT_SQL_EDITOR_DATA';
|
||||
import type { ISqlEditorProps } from './ISqlEditorProps';
|
||||
import { SqlEditorActionsMenu } from './SqlEditorActionsMenu';
|
||||
import { SqlEditorTools } from './SqlEditorTools';
|
||||
import { useSqlEditor } from './useSqlEditor';
|
||||
|
||||
@@ -53,7 +54,7 @@ const styles = css`
|
||||
user-select: none;
|
||||
|
||||
&:empty {
|
||||
display: none;
|
||||
width: initial;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,10 +125,16 @@ export const SqlEditor = observer<ISqlEditorProps>(function SqlEditor({ state, c
|
||||
const displayedEditors = getComputed(() => sqlEditorModeService.tabsContainer.getDisplayed({ state, data }).length);
|
||||
|
||||
useEffect(() => {
|
||||
split.fixate('maximize', displayedEditors === 0);
|
||||
if (displayedEditors === 0) {
|
||||
split.fixate('maximize', true);
|
||||
} else if (split.state.disable) {
|
||||
split.fixate('resize', false);
|
||||
split.state.setSize(-1);
|
||||
}
|
||||
});
|
||||
|
||||
const isScript = data.dataSource?.hasFeature(ESqlDataSourceFeatures.script);
|
||||
const isQuery = data.dataSource?.hasFeature(ESqlDataSourceFeatures.query);
|
||||
const isExecutable = data.dataSource?.hasFeature(ESqlDataSourceFeatures.executable);
|
||||
|
||||
return styled(styles, BASE_TAB_STYLES, VERTICAL_ROTATED_TAB_STYLES, tabStyles)(
|
||||
<TabsState
|
||||
@@ -142,22 +149,26 @@ export const SqlEditor = observer<ISqlEditorProps>(function SqlEditor({ state, c
|
||||
<sql-editor className={className}>
|
||||
<container>
|
||||
<actions onMouseDown={preventFocusHandler}>
|
||||
{isScript && (
|
||||
{isExecutable && (
|
||||
<>
|
||||
<button
|
||||
disabled={disabled}
|
||||
title={translate('sql_editor_sql_execution_button_tooltip')}
|
||||
onClick={data.executeQuery}
|
||||
>
|
||||
<StaticImage icon="/icons/sql_exec.svg" />
|
||||
</button>
|
||||
<button
|
||||
disabled={disabled}
|
||||
title={translate('sql_editor_sql_execution_new_tab_button_tooltip')}
|
||||
onClick={data.executeQueryNewTab}
|
||||
>
|
||||
<StaticImage icon="/icons/sql_exec_new.svg" />
|
||||
</button>
|
||||
{isQuery && (
|
||||
<>
|
||||
<button
|
||||
disabled={disabled}
|
||||
title={translate('sql_editor_sql_execution_button_tooltip')}
|
||||
onClick={data.executeQuery}
|
||||
>
|
||||
<StaticImage icon="/icons/sql_exec.svg" />
|
||||
</button>
|
||||
<button
|
||||
disabled={disabled}
|
||||
title={translate('sql_editor_sql_execution_new_tab_button_tooltip')}
|
||||
onClick={data.executeQueryNewTab}
|
||||
>
|
||||
<StaticImage icon="/icons/sql_exec_new.svg" />
|
||||
</button>
|
||||
</>
|
||||
)}
|
||||
<button
|
||||
disabled={disabled}
|
||||
title={translate('sql_editor_sql_execution_script_button_tooltip')}
|
||||
@@ -166,7 +177,7 @@ export const SqlEditor = observer<ISqlEditorProps>(function SqlEditor({ state, c
|
||||
>
|
||||
<StaticImage icon="/icons/sql_script_exec.svg" />
|
||||
</button>
|
||||
{data.dialect?.supportsExplainExecutionPlan && (
|
||||
{isQuery && data.dialect?.supportsExplainExecutionPlan && (
|
||||
<button
|
||||
disabled={disabled}
|
||||
title={translate('sql_editor_execution_plan_button_tooltip')}
|
||||
@@ -177,6 +188,7 @@ export const SqlEditor = observer<ISqlEditorProps>(function SqlEditor({ state, c
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
<SqlEditorActionsMenu state={state} />
|
||||
</actions>
|
||||
<SqlEditorTools data={data} state={state} style={styles} />
|
||||
</container>
|
||||
|
||||
@@ -28,6 +28,6 @@ export const SqlEditorActionsMenu = observer<Props>(function SqlEditorActionsMen
|
||||
menu.context.set(DATA_CONTEXT_SQL_EDITOR_STATE, state);
|
||||
|
||||
return (
|
||||
<MenuBar style={[SQL_EDITOR_ACTIONS_MENU_STYLES, style]} menu={menu} />
|
||||
<MenuBar style={[SQL_EDITOR_ACTIONS_MENU_STYLES, ...[style].flat(2)]} menu={menu} />
|
||||
);
|
||||
});
|
||||
@@ -15,7 +15,7 @@ import type { ComponentStyle } from '@cloudbeaver/core-theming';
|
||||
import type { ISqlEditorTabState } from '../ISqlEditorTabState';
|
||||
import { ESqlDataSourceFeatures } from '../SqlDataSource/ESqlDataSourceFeatures';
|
||||
import type { ISQLEditorData } from './ISQLEditorData';
|
||||
import { SqlEditorActionsMenu } from './SqlEditorActionsMenu';
|
||||
import { SqlEditorToolsMenu } from './SqlEditorToolsMenu';
|
||||
import { useTools } from './useTools';
|
||||
|
||||
const styles = css`
|
||||
@@ -73,19 +73,17 @@ export const SqlEditorTools = observer<Props>(function SqlEditorTools({
|
||||
|
||||
return styled(useStyles(style, styles))(
|
||||
<tools className={className} onMouseDown={preventFocusHandler}>
|
||||
<SqlEditorActionsMenu state={state} />
|
||||
<SqlEditorToolsMenu state={state} />
|
||||
{isScript && (
|
||||
<>
|
||||
{!data.readonly && (
|
||||
<button
|
||||
disabled={disabled}
|
||||
title={translate('sql_editor_sql_format_button_tooltip')}
|
||||
hidden={isActiveSegmentMode}
|
||||
onClick={data.formatScript}
|
||||
>
|
||||
<StaticImage icon="/icons/sql_format_sm.svg" />
|
||||
</button>
|
||||
)}
|
||||
<button
|
||||
disabled={disabled || data.readonly}
|
||||
title={translate('sql_editor_sql_format_button_tooltip')}
|
||||
hidden={isActiveSegmentMode}
|
||||
onClick={data.formatScript}
|
||||
>
|
||||
<StaticImage icon="/icons/sql_format_sm.svg" />
|
||||
</button>
|
||||
<button
|
||||
disabled={scriptEmpty}
|
||||
title={translate('sql_editor_download_script_tooltip')}
|
||||
@@ -94,14 +92,15 @@ export const SqlEditorTools = observer<Props>(function SqlEditorTools({
|
||||
>
|
||||
<StaticImage icon='/icons/export.svg' />
|
||||
</button>
|
||||
{!isActiveSegmentMode && !data.readonly && (
|
||||
{!isActiveSegmentMode && (
|
||||
<UploadArea
|
||||
accept='.sql'
|
||||
title={translate('sql_editor_upload_script_tooltip')}
|
||||
disabled={data.readonly}
|
||||
reset
|
||||
onChange={handleScriptUpload}
|
||||
>
|
||||
<upload>
|
||||
<upload disabled={data.readonly}>
|
||||
<StaticImage icon='/icons/import.svg' />
|
||||
</upload>
|
||||
</UploadArea>
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2023 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 { ComponentStyle } from '@cloudbeaver/core-theming';
|
||||
import { MenuBar } from '@cloudbeaver/core-ui';
|
||||
import { IDataContext, useMenu } from '@cloudbeaver/core-view';
|
||||
|
||||
import { DATA_CONTEXT_SQL_EDITOR_STATE } from '../DATA_CONTEXT_SQL_EDITOR_STATE';
|
||||
import type { ISqlEditorTabState } from '../ISqlEditorTabState';
|
||||
import { SQL_EDITOR_ACTIONS_MENU_STYLES } from './SQL_EDITOR_ACTIONS_MENU_STYLES';
|
||||
import { SQL_EDITOR_TOOLS_MENU } from './SQL_EDITOR_TOOLS_MENU';
|
||||
|
||||
interface Props {
|
||||
state: ISqlEditorTabState;
|
||||
context?: IDataContext;
|
||||
style?: ComponentStyle;
|
||||
}
|
||||
|
||||
export const SqlEditorToolsMenu = observer<Props>(function SqlEditorToolsMenu({ state, context, style }) {
|
||||
const menu = useMenu({ menu: SQL_EDITOR_TOOLS_MENU, context });
|
||||
menu.context.set(DATA_CONTEXT_SQL_EDITOR_STATE, state);
|
||||
|
||||
return (
|
||||
<MenuBar style={[SQL_EDITOR_ACTIONS_MENU_STYLES, ...[style].flat(2)]} menu={menu} />
|
||||
);
|
||||
});
|
||||
@@ -268,6 +268,12 @@ export function useSqlEditor(state: ISqlEditorTabState): ISQLEditorData {
|
||||
},
|
||||
|
||||
async executeQuery(): Promise<void> {
|
||||
const isQuery = this.dataSource?.hasFeature(ESqlDataSourceFeatures.query);
|
||||
const isExecutable = this.dataSource?.hasFeature(ESqlDataSourceFeatures.executable);
|
||||
|
||||
if (!isQuery || !isExecutable) {
|
||||
return;
|
||||
}
|
||||
const query = this.getSubQuery();
|
||||
|
||||
await this.executeQueryAction(
|
||||
@@ -296,6 +302,12 @@ export function useSqlEditor(state: ISqlEditorTabState): ISQLEditorData {
|
||||
},
|
||||
|
||||
async executeQueryNewTab(): Promise<void> {
|
||||
const isQuery = this.dataSource?.hasFeature(ESqlDataSourceFeatures.query);
|
||||
const isExecutable = this.dataSource?.hasFeature(ESqlDataSourceFeatures.executable);
|
||||
|
||||
if (!isQuery || !isExecutable) {
|
||||
return;
|
||||
}
|
||||
const query = this.getSubQuery();
|
||||
|
||||
await this.executeQueryAction(
|
||||
@@ -309,7 +321,10 @@ export function useSqlEditor(state: ISqlEditorTabState): ISQLEditorData {
|
||||
},
|
||||
|
||||
async showExecutionPlan(): Promise<void> {
|
||||
if (!this.dialect?.supportsExplainExecutionPlan) {
|
||||
const isQuery = this.dataSource?.hasFeature(ESqlDataSourceFeatures.query);
|
||||
const isExecutable = this.dataSource?.hasFeature(ESqlDataSourceFeatures.executable);
|
||||
|
||||
if (!isQuery || !isExecutable || !this.dialect?.supportsExplainExecutionPlan) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -329,7 +344,9 @@ export function useSqlEditor(state: ISqlEditorTabState): ISQLEditorData {
|
||||
},
|
||||
|
||||
async executeScript(): Promise<void> {
|
||||
if (this.isDisabled || this.isScriptEmpty) {
|
||||
const isExecutable = this.dataSource?.hasFeature(ESqlDataSourceFeatures.executable);
|
||||
|
||||
if (!isExecutable || this.isDisabled || this.isScriptEmpty) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ const styles = css`
|
||||
display: flex;
|
||||
overflow: auto;
|
||||
}
|
||||
TabList:not([|script]) tab-outer:only-child {
|
||||
TabList:not([|executable]) tab-outer:only-child {
|
||||
display: none;
|
||||
}
|
||||
TextPlaceholder {
|
||||
@@ -91,11 +91,22 @@ export const SqlResultTabs = observer<Props>(function SqlDataResult({ state, onT
|
||||
}
|
||||
}
|
||||
|
||||
function handleCanClose(tab: ITabData): boolean {
|
||||
const resultTab = state.resultTabs.find(tabState => tabState.tabId === tab.tabId);
|
||||
|
||||
if (resultTab) {
|
||||
const group = state.resultGroups.find(group => group.groupId === resultTab.groupId)!;
|
||||
|
||||
return dataSource?.databaseModels.some(model => model.id === group.modelId) !== true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!state.tabs.length) {
|
||||
return styled(style)(<TextPlaceholder>{translate(dataSource?.emptyPlaceholder ?? 'sql_editor_placeholder')}</TextPlaceholder>);
|
||||
}
|
||||
|
||||
const script = dataSource?.hasFeature(ESqlDataSourceFeatures.script);
|
||||
const executable = dataSource?.hasFeature(ESqlDataSourceFeatures.executable);
|
||||
const tabList = orderedTabs.map(tab => tab.id);
|
||||
|
||||
return styled(style)(
|
||||
@@ -103,11 +114,12 @@ export const SqlResultTabs = observer<Props>(function SqlDataResult({ state, onT
|
||||
<TabsState
|
||||
currentTabId={state.currentTabId}
|
||||
tabList={tabList}
|
||||
canClose={handleCanClose}
|
||||
enabledBaseActions
|
||||
onChange={handleSelect}
|
||||
onClose={handleClose}
|
||||
>
|
||||
<TabList aria-label='SQL Results' {...use({ script })} style={styles}>
|
||||
<TabList aria-label='SQL Results' {...use({ executable })} style={styles}>
|
||||
{orderedTabs.map(result => (
|
||||
<SqlResultTab
|
||||
key={result.id}
|
||||
|
||||
@@ -13,5 +13,6 @@ export const ACTION_SQL_EDITOR_EXECUTE_SCRIPT = createAction(
|
||||
{
|
||||
icon: '/icons/sql_script_exec.svg',
|
||||
label: 'sql_editor_sql_execution_script_button_tooltip',
|
||||
tooltip: 'sql_editor_sql_execution_script_button_tooltip',
|
||||
}
|
||||
);
|
||||
|
||||
@@ -20,6 +20,8 @@ export * from './SqlDataSource/MemorySqlDataSource';
|
||||
export * from './SqlEditor/SQLCodeEditor/SQLCodeEditorLoader';
|
||||
export * from './SqlEditor/ISQLEditorData';
|
||||
export * from './SqlEditor/DATA_CONTEXT_SQL_EDITOR_DATA';
|
||||
export * from './SqlEditor/SQL_EDITOR_ACTIONS_MENU';
|
||||
export * from './SqlEditor/SQL_EDITOR_TOOLS_MENU';
|
||||
export * from './SqlEditor/SQLEditorModeContext';
|
||||
export * from './SqlResultTabs/DATA_CONTEXT_SQL_EDITOR_RESULT_ID';
|
||||
export * from './SqlResultTabs/SqlResultTabsService';
|
||||
@@ -32,7 +34,6 @@ export * from './SqlEditor';
|
||||
export * from './SqlEditorModeService';
|
||||
export * from './SqlEditorService';
|
||||
export * from './SqlEditorSettingsService';
|
||||
export * from './SqlEditor/SQL_EDITOR_ACTIONS_MENU';
|
||||
export * from './SqlGenerators/SqlGeneratorsResource';
|
||||
export * from './SqlGenerators/SqlGeneratorsBootstrap';
|
||||
|
||||
|
||||
Reference in New Issue
Block a user