mirror of
https://github.com/dbeaver/cloudbeaver.git
synced 2026-09-24 16:04:36 +08:00
218 lines
7.9 KiB
TypeScript
218 lines
7.9 KiB
TypeScript
/*
|
|
* CloudBeaver - Cloud Database Manager
|
|
* Copyright (C) 2020-2022 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 { ConnectionInfoResource, isConnectionProvider } from '@cloudbeaver/core-connections';
|
|
import { Bootstrap, injectable } from '@cloudbeaver/core-di';
|
|
import { CommonDialogService, DialogueStateResult, RenameDialog } from '@cloudbeaver/core-dialogs';
|
|
import type { IExecutorHandler } from '@cloudbeaver/core-executor';
|
|
import { ExtensionUtils } from '@cloudbeaver/core-extensions';
|
|
import { DATA_CONTEXT_NAV_NODE, EObjectFeature, isObjectCatalogProvider, isObjectSchemaProvider } from '@cloudbeaver/core-navigation-tree';
|
|
import { ISessionAction, sessionActionContext, SessionActionService } from '@cloudbeaver/core-root';
|
|
import { ActionService, ACTION_RENAME, DATA_CONTEXT_MENU_NESTED, menuExtractActions, MenuService, ViewService } from '@cloudbeaver/core-view';
|
|
import { DATA_CONTEXT_CONNECTION } from '@cloudbeaver/plugin-connections';
|
|
import { ConnectionSchemaManagerService } from '@cloudbeaver/plugin-datasource-context-switch';
|
|
import { NavigationTabsService } from '@cloudbeaver/plugin-navigation-tabs';
|
|
import { DATA_CONTEXT_SQL_EDITOR_STATE, ESqlDataSourceFeatures, getSqlEditorName, LocalStorageSqlDataSource, SqlDataSourceService, SqlEditorService } from '@cloudbeaver/plugin-sql-editor';
|
|
import { MainMenuService } from '@cloudbeaver/plugin-top-app-bar';
|
|
|
|
import { ACTION_SQL_EDITOR_OPEN } from './ACTION_SQL_EDITOR_OPEN';
|
|
import { DATA_CONTEXT_SQL_EDITOR_TAB } from './DATA_CONTEXT_SQL_EDITOR_TAB';
|
|
import { isSessionActionOpenSQLEditor } from './sessionActionOpenSQLEditor';
|
|
import { SQL_EDITOR_SOURCE_ACTION } from './SQL_EDITOR_SOURCE_ACTION';
|
|
import { SqlEditorNavigatorService } from './SqlEditorNavigatorService';
|
|
import { SqlEditorTabService } from './SqlEditorTabService';
|
|
|
|
@injectable()
|
|
export class SqlEditorBootstrap extends Bootstrap {
|
|
constructor(
|
|
private readonly mainMenuService: MainMenuService,
|
|
private readonly sqlEditorNavigatorService: SqlEditorNavigatorService,
|
|
private readonly navigationTabsService: NavigationTabsService,
|
|
private readonly connectionSchemaManagerService: ConnectionSchemaManagerService,
|
|
private readonly viewService: ViewService,
|
|
private readonly actionService: ActionService,
|
|
private readonly menuService: MenuService,
|
|
private readonly sessionActionService: SessionActionService,
|
|
private readonly commonDialogService: CommonDialogService,
|
|
private readonly sqlEditorTabService: SqlEditorTabService,
|
|
private readonly sqlDataSourceService: SqlDataSourceService,
|
|
private readonly connectionInfoResource: ConnectionInfoResource,
|
|
private readonly sqlEditorService: SqlEditorService,
|
|
) {
|
|
super();
|
|
}
|
|
|
|
register(): void {
|
|
this.mainMenuService.registerRootItem(
|
|
{
|
|
id: 'sql-editor',
|
|
title: 'SQL',
|
|
order: 2,
|
|
onClick: this.openSQLEditor.bind(this),
|
|
}
|
|
);
|
|
|
|
this.menuService.addCreator({
|
|
isApplicable: context => context.has(DATA_CONTEXT_SQL_EDITOR_STATE) && context.has(DATA_CONTEXT_SQL_EDITOR_TAB),
|
|
getItems: (context, items) => [
|
|
...items,
|
|
ACTION_RENAME,
|
|
],
|
|
orderItems: (context, items) => {
|
|
const actions = menuExtractActions(items, [
|
|
ACTION_RENAME,
|
|
]);
|
|
|
|
if (actions.length > 0) {
|
|
items.unshift(...actions);
|
|
}
|
|
|
|
return items;
|
|
},
|
|
});
|
|
|
|
this.menuService.addCreator({
|
|
isApplicable: context => {
|
|
if (!context.has(DATA_CONTEXT_CONNECTION)) {
|
|
return false;
|
|
}
|
|
|
|
const node = context.tryGet(DATA_CONTEXT_NAV_NODE);
|
|
|
|
if (node && !node.objectFeatures.includes(EObjectFeature.dataSource)) {
|
|
return false;
|
|
}
|
|
|
|
return !context.has(DATA_CONTEXT_MENU_NESTED);
|
|
},
|
|
getItems: (context, items) => [
|
|
...items,
|
|
ACTION_SQL_EDITOR_OPEN,
|
|
],
|
|
});
|
|
|
|
this.actionService.addHandler({
|
|
id: 'sql-editor',
|
|
isActionApplicable: (context, action) => {
|
|
if (action === ACTION_RENAME) {
|
|
const editorState = context.tryGet(DATA_CONTEXT_SQL_EDITOR_STATE);
|
|
|
|
if (!editorState) {
|
|
return false;
|
|
}
|
|
|
|
const dataSource = this.sqlDataSourceService.get(editorState.editorId);
|
|
|
|
return dataSource?.features.includes(ESqlDataSourceFeatures.setName) ?? false;
|
|
}
|
|
return (
|
|
action === ACTION_SQL_EDITOR_OPEN
|
|
&& context.has(DATA_CONTEXT_CONNECTION)
|
|
);
|
|
},
|
|
handler: async (context, action) => {
|
|
switch (action) {
|
|
case ACTION_RENAME: {
|
|
const state = context.get(DATA_CONTEXT_SQL_EDITOR_STATE);
|
|
const dataSource = this.sqlDataSourceService.get(state.editorId);
|
|
|
|
if (!dataSource) {
|
|
return;
|
|
}
|
|
|
|
const connection = this.connectionInfoResource.get(dataSource.executionContext?.connectionId ?? '');
|
|
|
|
const name = getSqlEditorName(state, dataSource, connection);
|
|
const regexp = /^(.*?)(\.\w+)$/ig.exec(name);
|
|
|
|
const result = await this.commonDialogService.open(RenameDialog, {
|
|
value: regexp?.[1] ?? name,
|
|
objectName: name,
|
|
icon: '/icons/sql_script_m.svg',
|
|
validation: name => (
|
|
!this.sqlEditorTabService.sqlEditorTabs.some(tab => (
|
|
tab.handlerState.order !== state.order
|
|
&& this.sqlEditorService.getName(tab.handlerState) === name.trim()
|
|
))
|
|
&& dataSource.canRename(name)
|
|
),
|
|
});
|
|
|
|
if (result !== DialogueStateResult.Rejected && result !== DialogueStateResult.Resolved) {
|
|
dataSource.setName((result ?? '').trim());
|
|
}
|
|
break;
|
|
}
|
|
case ACTION_SQL_EDITOR_OPEN: {
|
|
const connection = context.get(DATA_CONTEXT_CONNECTION);
|
|
|
|
this.sqlEditorNavigatorService.openNewEditor({
|
|
dataSourceKey: LocalStorageSqlDataSource.key,
|
|
connectionId: connection.id,
|
|
});
|
|
break;
|
|
}
|
|
}
|
|
},
|
|
});
|
|
|
|
this.navigationTabsService.onInit.addHandler(state => {
|
|
if (state) {
|
|
this.sessionActionService.onAction.addHandler(this.handleAction);
|
|
} else {
|
|
this.sessionActionService.onAction.removeHandler(this.handleAction);
|
|
}
|
|
});
|
|
}
|
|
|
|
load(): void { }
|
|
|
|
private openSQLEditor() {
|
|
let connectionId: string | undefined;
|
|
let catalogId: string | undefined;
|
|
let schemaId: string | undefined;
|
|
|
|
const activeView = this.viewService.activeView;
|
|
|
|
if (activeView) {
|
|
ExtensionUtils.from(activeView.extensions)
|
|
.on(isConnectionProvider, extension => { connectionId = extension(activeView.context); })
|
|
.on(isObjectCatalogProvider, extension => { catalogId = extension(activeView.context); })
|
|
.on(isObjectSchemaProvider, extension => { schemaId = extension(activeView.context); });
|
|
} else {
|
|
connectionId = this.connectionSchemaManagerService.currentConnectionId || undefined;
|
|
catalogId = this.connectionSchemaManagerService.currentObjectCatalogId;
|
|
schemaId = this.connectionSchemaManagerService.currentObjectSchemaId;
|
|
}
|
|
|
|
this.sqlEditorNavigatorService.openNewEditor({
|
|
dataSourceKey: LocalStorageSqlDataSource.key,
|
|
connectionId,
|
|
catalogId,
|
|
schemaId,
|
|
});
|
|
}
|
|
|
|
private readonly handleAction: IExecutorHandler<ISessionAction | null> = (data, contexts) => {
|
|
const processInfo = contexts.getContext(sessionActionContext);
|
|
|
|
if (isSessionActionOpenSQLEditor(data)) {
|
|
try {
|
|
this.sqlEditorNavigatorService.openNewEditor({
|
|
dataSourceKey: LocalStorageSqlDataSource.key,
|
|
name: data['editor-name'],
|
|
connectionId: data['connection-id'],
|
|
source: SQL_EDITOR_SOURCE_ACTION,
|
|
});
|
|
} finally {
|
|
processInfo.process();
|
|
}
|
|
}
|
|
};
|
|
}
|