mirror of
https://github.com/dbeaver/cloudbeaver.git
synced 2026-10-24 11:35:54 +08:00
CB-4289 add file name param for data export (#2308)
* CB-4289 add file name param for data export * CB-4289 pass file name based on context * CB-4289 use existing export action --------- Co-authored-by: naumov <iamemptyhuh@gmail.com> Co-authored-by: kseniaguzeeva <112612526+kseniaguzeeva@users.noreply.github.com>
This commit is contained in:
co-authored by
naumov
kseniaguzeeva
parent
3274988d4a
commit
bc7cd3b217
@@ -8,11 +8,19 @@
|
||||
import { EAdminPermission } from '@cloudbeaver/core-authentication';
|
||||
import { createConnectionParam, DATA_CONTEXT_CONNECTION } from '@cloudbeaver/core-connections';
|
||||
import { injectable } from '@cloudbeaver/core-di';
|
||||
import { CommonDialogService, IMenuContext } from '@cloudbeaver/core-dialogs';
|
||||
import { CommonDialogService } from '@cloudbeaver/core-dialogs';
|
||||
import { LocalizationService } from '@cloudbeaver/core-localization';
|
||||
import { DATA_CONTEXT_NAV_NODE, EObjectFeature } from '@cloudbeaver/core-navigation-tree';
|
||||
import { SessionPermissionsResource } from '@cloudbeaver/core-root';
|
||||
import { ACTION_EXPORT, ActionService, DATA_CONTEXT_MENU_NESTED, MenuService } from '@cloudbeaver/core-view';
|
||||
import { IDatabaseDataSource, IDataContainerOptions, ITableFooterMenuContext, TableFooterMenuService } from '@cloudbeaver/plugin-data-viewer';
|
||||
import { withTimestamp } from '@cloudbeaver/core-utils';
|
||||
import { ACTION_EXPORT, ActionService, DATA_CONTEXT_MENU, DATA_CONTEXT_MENU_NESTED, menuExtractItems, MenuService } from '@cloudbeaver/core-view';
|
||||
import {
|
||||
DATA_CONTEXT_DV_DDM,
|
||||
DATA_CONTEXT_DV_DDM_RESULT_INDEX,
|
||||
DATA_VIEWER_DATA_MODEL_ACTIONS_MENU,
|
||||
IDatabaseDataSource,
|
||||
IDataContainerOptions,
|
||||
} from '@cloudbeaver/plugin-data-viewer';
|
||||
import type { IDataQueryOptions } from '@cloudbeaver/plugin-sql-editor';
|
||||
|
||||
import { DataExportSettingsService } from './DataExportSettingsService';
|
||||
@@ -22,32 +30,83 @@ import { DataExportDialog } from './Dialog/DataExportDialog';
|
||||
export class DataExportMenuService {
|
||||
constructor(
|
||||
private readonly commonDialogService: CommonDialogService,
|
||||
private readonly tableFooterMenuService: TableFooterMenuService,
|
||||
private readonly dataExportSettingsService: DataExportSettingsService,
|
||||
private readonly actionService: ActionService,
|
||||
private readonly menuService: MenuService,
|
||||
private readonly sessionPermissionsResource: SessionPermissionsResource,
|
||||
private readonly localizationService: LocalizationService,
|
||||
) {}
|
||||
|
||||
register(): void {
|
||||
this.tableFooterMenuService.registerMenuItem({
|
||||
id: 'export ',
|
||||
order: 5,
|
||||
title: 'data_transfer_dialog_export',
|
||||
tooltip: 'data_transfer_dialog_export_tooltip',
|
||||
icon: 'table-export',
|
||||
isPresent(context) {
|
||||
return context.contextType === TableFooterMenuService.nodeContextType;
|
||||
this.actionService.addHandler({
|
||||
id: 'data-export-base-handler',
|
||||
isActionApplicable(context, action) {
|
||||
const menu = context.hasValue(DATA_CONTEXT_MENU, DATA_VIEWER_DATA_MODEL_ACTIONS_MENU);
|
||||
const model = context.tryGet(DATA_CONTEXT_DV_DDM);
|
||||
const resultIndex = context.tryGet(DATA_CONTEXT_DV_DDM_RESULT_INDEX);
|
||||
|
||||
if (!menu || !model || resultIndex === undefined) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return [ACTION_EXPORT].includes(action);
|
||||
},
|
||||
isHidden: () => this.isDisabled(),
|
||||
isDisabled(context) {
|
||||
return (
|
||||
context.data.model.isLoading() ||
|
||||
context.data.model.isDisabled(context.data.resultIndex) ||
|
||||
!context.data.model.getResult(context.data.resultIndex)
|
||||
);
|
||||
const model = context.get(DATA_CONTEXT_DV_DDM);
|
||||
const resultIndex = context.get(DATA_CONTEXT_DV_DDM_RESULT_INDEX);
|
||||
|
||||
return model.isLoading() || model.isDisabled(resultIndex) || !model.getResult(resultIndex);
|
||||
},
|
||||
getActionInfo(context, action) {
|
||||
if (action === ACTION_EXPORT) {
|
||||
return { ...action.info, icon: 'table-export' };
|
||||
}
|
||||
|
||||
return action.info;
|
||||
},
|
||||
handler: (context, action) => {
|
||||
const model = context.get(DATA_CONTEXT_DV_DDM);
|
||||
const resultIndex = context.get(DATA_CONTEXT_DV_DDM_RESULT_INDEX);
|
||||
|
||||
if (action === ACTION_EXPORT) {
|
||||
const result = model.getResult(resultIndex);
|
||||
|
||||
if (!result) {
|
||||
throw new Error('Result must be provided');
|
||||
}
|
||||
|
||||
const source = model.source as IDatabaseDataSource<IDataContainerOptions & IDataQueryOptions>;
|
||||
|
||||
if (!source.options) {
|
||||
throw new Error('Source options must be provided');
|
||||
}
|
||||
|
||||
this.commonDialogService.open(DataExportDialog, {
|
||||
connectionKey: source.options.connectionKey,
|
||||
contextId: source.executionContext?.context?.id,
|
||||
containerNodePath: source.options.containerNodePath,
|
||||
resultId: result.id,
|
||||
name: model.name ?? undefined,
|
||||
fileName: withTimestamp(model.name ?? this.localizationService.translate('data_transfer_dialog_title')),
|
||||
query: source.options.query,
|
||||
filter: {
|
||||
constraints: source.options.constraints,
|
||||
where: source.options.whereFilter,
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
});
|
||||
this.menuService.addCreator({
|
||||
menus: [DATA_VIEWER_DATA_MODEL_ACTIONS_MENU],
|
||||
isApplicable: () => !this.isExportDisabled(),
|
||||
getItems(context, items) {
|
||||
return [...items, ACTION_EXPORT];
|
||||
},
|
||||
orderItems(context, items) {
|
||||
const extracted = menuExtractItems(items, [ACTION_EXPORT]);
|
||||
return [...items, ...extracted];
|
||||
},
|
||||
onClick: this.exportData.bind(this),
|
||||
});
|
||||
|
||||
this.menuService.addCreator({
|
||||
@@ -58,7 +117,7 @@ export class DataExportMenuService {
|
||||
return false;
|
||||
}
|
||||
|
||||
return !this.isDisabled() && context.has(DATA_CONTEXT_CONNECTION) && !context.has(DATA_CONTEXT_MENU_NESTED);
|
||||
return !this.isExportDisabled() && context.has(DATA_CONTEXT_CONNECTION) && !context.has(DATA_CONTEXT_MENU_NESTED);
|
||||
},
|
||||
getItems: (context, items) => [...items, ACTION_EXPORT],
|
||||
});
|
||||
@@ -69,44 +128,19 @@ export class DataExportMenuService {
|
||||
handler: async (context, action) => {
|
||||
const node = context.get(DATA_CONTEXT_NAV_NODE);
|
||||
const connection = context.get(DATA_CONTEXT_CONNECTION);
|
||||
const fileName = withTimestamp(`${connection.name}${node?.name ? ` - ${node.name}` : ''}`);
|
||||
|
||||
this.commonDialogService.open(DataExportDialog, {
|
||||
connectionKey: createConnectionParam(connection),
|
||||
name: node?.name,
|
||||
fileName,
|
||||
containerNodePath: node?.id,
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
private exportData(context: IMenuContext<ITableFooterMenuContext>) {
|
||||
const result = context.data.model.getResult(context.data.resultIndex);
|
||||
|
||||
if (!result) {
|
||||
throw new Error('Result must be provided');
|
||||
}
|
||||
|
||||
const source = context.data.model.source as IDatabaseDataSource<IDataContainerOptions & IDataQueryOptions>;
|
||||
|
||||
if (!source.options) {
|
||||
throw new Error('Source options must be provided');
|
||||
}
|
||||
|
||||
this.commonDialogService.open(DataExportDialog, {
|
||||
connectionKey: source.options.connectionKey,
|
||||
contextId: context.data.model.source.executionContext?.context?.id,
|
||||
containerNodePath: source.options.containerNodePath,
|
||||
resultId: result.id,
|
||||
name: context.data.model.name ?? undefined,
|
||||
query: source.options.query,
|
||||
filter: {
|
||||
constraints: source.options.constraints,
|
||||
where: source.options.whereFilter,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
private isDisabled() {
|
||||
private isExportDisabled() {
|
||||
if (this.sessionPermissionsResource.has(EAdminPermission.admin)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -94,7 +94,10 @@ export function useDataExportDialog(context: IExportContext, onExport?: () => vo
|
||||
processorId: this.processor.id,
|
||||
processorProperties: this.processorProperties,
|
||||
filter: this.context.filter,
|
||||
outputSettings: this.outputSettings,
|
||||
outputSettings: {
|
||||
...this.outputSettings,
|
||||
fileName: this.context.fileName,
|
||||
},
|
||||
});
|
||||
|
||||
this.onExport?.();
|
||||
|
||||
@@ -14,6 +14,7 @@ export interface IExportContext {
|
||||
resultId?: string | null;
|
||||
containerNodePath?: string;
|
||||
name?: string;
|
||||
fileName?: string;
|
||||
query?: string;
|
||||
filter?: SqlDataFilter;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user