Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions webapp/packages/plugin-data-spreadsheet-new/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"@cloudbeaver/core-dialogs": "workspace:*",
"@cloudbeaver/core-events": "workspace:*",
"@cloudbeaver/core-localization": "workspace:*",
"@cloudbeaver/core-navigation-tree": "workspace:*",
"@cloudbeaver/core-sdk": "workspace:*",
"@cloudbeaver/core-settings": "workspace:*",
"@cloudbeaver/core-ui": "workspace:*",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
import { injectable } from '@cloudbeaver/core-di';
import { CommonDialogService } from '@cloudbeaver/core-dialogs';
import { NotificationService } from '@cloudbeaver/core-events';
import { LocalizationService } from '@cloudbeaver/core-localization';
import { SqlResultSetGeneratorId, type SqlQueryGeneratorOptions, type SqlResultRow } from '@cloudbeaver/core-sdk';
import { NavNodeInfoResource } from '@cloudbeaver/core-navigation-tree';
import { ActionService, MenuService, type IAction } from '@cloudbeaver/core-view';
import {
DATA_CONTEXT_DV_DDM,
Expand Down Expand Up @@ -42,14 +44,24 @@ import type { IDataContextProvider } from '@cloudbeaver/core-data-context';
import { getDefaultQueryGeneratorOptions, GeneratedSqlDialog, SqlGeneratorsResource, DDL_GENERATOR_ID } from '@cloudbeaver/plugin-sql-generator';
import { isNotNullDefined } from '@dbeaver/js-helpers';

@injectable(() => [ActionService, MenuService, CommonDialogService, NotificationService, SqlGeneratorsResource])
@injectable(() => [
ActionService,
MenuService,
CommonDialogService,
NotificationService,
SqlGeneratorsResource,
LocalizationService,
NavNodeInfoResource,
])
export class DataGridContextMenuGenerateSqlService {
constructor(
private readonly actionService: ActionService,
private readonly menuService: MenuService,
private readonly commonDialogService: CommonDialogService,
private readonly notificationService: NotificationService,
private readonly sqlGenerationResource: SqlGeneratorsResource,
private readonly localizationService: LocalizationService,
private readonly navNodeInfoResource: NavNodeInfoResource,
) {}

register(): void {
Expand Down Expand Up @@ -107,21 +119,22 @@ export class DataGridContextMenuGenerateSqlService {
return;
}

await this.openSqlDialog(context, mapGeneratorIdFromAction(action));
await this.openSqlDialog(context, mapGeneratorIdFromAction(action), action.info.label);
},
});
}

private async openSqlDialog(context: IDataContextProvider, generatorId: SqlResultSetGeneratorId): Promise<void> {
private async openSqlDialog(context: IDataContextProvider, generatorId: SqlResultSetGeneratorId, generatorLabel: string): Promise<void> {
const model = context.get(DATA_CONTEXT_DV_DDM)!;
const resultIndex = context.get(DATA_CONTEXT_DV_DDM_RESULT_INDEX)!;
const key = context.get(DATA_CONTEXT_DV_RESULT_KEY);
const options = model.source.options as IDataContainerOptions | undefined;
const containerNodePath = options?.containerNodePath;

if (!isResultSetDataModel(model)) {
return;
}

const options = model.source.options as IDataContainerOptions | undefined;
const nodePath = options?.containerNodePath;
const select = model.source.tryGetAction(resultIndex, IDatabaseDataSelectAction, GridSelectAction);
const projectId = model.source.executionContext?.context?.projectId;
Expand Down Expand Up @@ -165,6 +178,8 @@ export class DataGridContextMenuGenerateSqlService {
await this.commonDialogService.open(GeneratedSqlDialog, {
query,
nodeId: nodePath ?? connectionId,
nodeName: this.getEntityNameFromNodePath(containerNodePath, model.name),
generatorName: this.localizationService.translate(generatorLabel),
options: getDefaultQueryGeneratorOptions(),
regenerateQuery: options =>
this.generateQuery({
Expand Down Expand Up @@ -218,6 +233,8 @@ export class DataGridContextMenuGenerateSqlService {
await this.commonDialogService.open(GeneratedSqlDialog, {
query,
nodeId: nodePathList,
nodeName: this.getEntityNameFromNodePath(nodePathList, model.name),
generatorName: createGenerator.label,
options: getDefaultQueryGeneratorOptions(),
regenerateQuery: genOptions => this.sqlGenerationResource.generateEntityQuery(createGenerator.id, nodePathList, genOptions),
});
Expand Down Expand Up @@ -259,6 +276,18 @@ export class DataGridContextMenuGenerateSqlService {

return query;
}

private getEntityNameFromNodePath(nodePath: string | undefined, fallbackName?: string | null): string | undefined {
if (nodePath) {
const name = this.navNodeInfoResource.get(nodePath)?.name;

if (name) {
return name;
}
}

return fallbackName ?? undefined;
}
}

function mapGeneratorIdFromAction(action: IAction): SqlResultSetGeneratorId {
Expand Down
3 changes: 3 additions & 0 deletions webapp/packages/plugin-data-spreadsheet-new/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@
{
"path": "../core-localization"
},
{
"path": "../core-navigation-tree"
},
{
"path": "../core-sdk"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {
import { ConnectionDialectResource, ConnectionInfoResource, createConnectionParam } from '@cloudbeaver/core-connections';
import { useService } from '@cloudbeaver/core-di';
import type { DialogComponentProps } from '@cloudbeaver/core-dialogs';
import { download, withTimestamp } from '@cloudbeaver/core-utils';
import { NavNodeManagerService } from '@cloudbeaver/core-navigation-tree';
import { useCodemirrorExtensions } from '@cloudbeaver/plugin-codemirror6';
import { SqlEditorNavigatorService } from '@cloudbeaver/plugin-sql-editor-navigation-tab';
Expand All @@ -34,6 +35,8 @@ import type { SqlQueryGeneratorOptions } from '@cloudbeaver/core-sdk';

interface Payload {
nodeId: string;
nodeName?: string;
generatorName?: string;
query: string;
options?: SqlQueryGeneratorOptions;
regenerateQuery: (options: SqlQueryGeneratorOptions) => Promise<string>;
Expand Down Expand Up @@ -110,6 +113,13 @@ export const GeneratedSqlDialog = observer<DialogComponentProps<Payload>>(functi
}
}

function handleSaveToFile() {
const blob = new Blob([state.query], { type: 'application/sql' });
const name = [payload.nodeName, payload.generatorName].join('-') || 'Generated';

download(blob, `${withTimestamp(name)}.sql`);
}

return (
<CommonDialogWrapper size="large">
<CommonDialogHeader title="app_shared_sql_generators_dialog_title" icon="sql-script" onReject={rejectDialog} />
Expand Down Expand Up @@ -141,14 +151,31 @@ export const GeneratedSqlDialog = observer<DialogComponentProps<Payload>>(functi
/>
</div>
</div>
<div className="tw:flex tw:justify-end tw:w-full tw:gap-6">
<Button variant="secondary" disabled={!state.query || visibleLoading} onClick={() => copy(state.query, true)}>
{translate('ui_copy_to_clipboard')}
</Button>
<Button variant="secondary" disabled={!state.query || visibleLoading} onClick={handleOpenInEditor}>
{translate('app_shared_sql_generators_open_in_editor')}
</Button>
<Button onClick={() => rejectDialog()}>{translate('ui_close')}</Button>
<div className="tw:flex tw:items-center tw:justify-between tw:w-full tw:gap-6">
<div className="tw:flex tw:items-center tw:gap-2">
<Button
variant="secondary"
icon="/icons/export.svg"
title={translate('ui_download')}
disabled={!state.query || visibleLoading}
className="tw:aspect-square tw:!min-w-0 tw:!px-0"
onClick={handleSaveToFile}
/>
<Button
variant="secondary"
icon="copy"
title={translate('ui_copy_to_clipboard')}
disabled={!state.query || visibleLoading}
className="tw:aspect-square tw:!min-w-0 tw:!px-0"
onClick={() => copy(state.query, true)}
/>
</div>
<div className="tw:flex tw:items-center tw:gap-6">
<Button variant="secondary" disabled={!state.query || visibleLoading} onClick={handleOpenInEditor}>
{translate('app_shared_sql_generators_open_in_editor')}
</Button>
<Button onClick={() => rejectDialog()}>{translate('ui_close')}</Button>
</div>
</div>
</div>
</CommonDialogFooter>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ export class SqlGeneratorsBootstrap extends Bootstrap {
await this.commonDialogService.open(GeneratedSqlDialog, {
query,
nodeId: node.uri,
nodeName: node.name,
generatorName: action.label,
options: getDefaultQueryGeneratorOptions(),
regenerateQuery: options => this.sqlGeneratorsResource.generateEntityQuery(action.id, node.uri, options),
});
Expand Down
1 change: 1 addition & 0 deletions webapp/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3049,6 +3049,7 @@ __metadata:
"@cloudbeaver/core-dialogs": "workspace:*"
"@cloudbeaver/core-events": "workspace:*"
"@cloudbeaver/core-localization": "workspace:*"
"@cloudbeaver/core-navigation-tree": "workspace:*"
"@cloudbeaver/core-sdk": "workspace:*"
"@cloudbeaver/core-settings": "workspace:*"
"@cloudbeaver/core-ui": "workspace:*"
Expand Down
Loading