import React from 'react'; import { CodeOutlined, ConsoleSqlOutlined, CopyOutlined, DeleteOutlined, DisconnectOutlined, EditOutlined, ExportOutlined, FileAddOutlined, FolderOpenOutlined, FolderOutlined, SaveOutlined, SendOutlined, LinkOutlined, ReloadOutlined, TableOutlined, ThunderboltOutlined, DatabaseOutlined, CheckSquareOutlined, CloudOutlined, ClearOutlined, ColumnWidthOutlined, DashboardOutlined, EyeInvisibleOutlined, FileTextOutlined, FolderAddOutlined, HddOutlined, PushpinOutlined, UndoOutlined, SortAscendingOutlined, SortDescendingOutlined, VerticalAlignBottomOutlined, } from '@ant-design/icons'; import { getCurrentLanguage, t } from '../i18n'; import { getPrimaryShortcutDisplayLabel, type ShortcutPlatform } from '../utils/shortcuts'; export type V2TableContextMenuActionKey = | 'pin-table' | 'unpin-table' | 'open-data' | 'design-table' | 'open-new-tab' | 'new-query' | 'publish-message' | 'view-ddl' | 'view-er' | 'copy-table-name' | 'copy-structure' | 'copy-insert' | 'rename-table' | 'new-rollup' | 'backup-table' | 'refresh-stats' | 'export-data' | 'ai-explain' | 'ai-generate-query' | 'truncate-table' | 'drop-table'; export type V2TableContextMenuStats = { rowCount?: number; dataLength?: number; indexLength?: number; engine?: string; loading?: boolean; unavailable?: boolean; }; type V2TableContextMenuItemConfig = { action: string; icon: React.ReactNode; title: string; kbd?: string; featured?: boolean; selected?: boolean; disabled?: boolean; tone?: 'default' | 'ai' | 'danger'; }; export const formatV2TableContextMenuRows = (count?: number): string => { if (count === undefined || count === null || !Number.isFinite(count) || count < 0) { return t('sidebar.v2_table_menu.meta.rows_empty'); } return t('sidebar.v2_table_menu.meta.rows', { count: Math.round(count).toLocaleString(getCurrentLanguage()), }); }; export const formatV2TableContextMenuSize = (bytes?: number): string => { if (bytes === undefined || bytes === null || !Number.isFinite(bytes) || bytes < 0) return '—'; if (bytes < 1024) return `${Math.round(bytes)} B`; if (bytes < 1024 * 1024) return `${Math.round(bytes / 1024)} KB`; if (bytes < 1024 * 1024 * 1024) return `${(bytes / (1024 * 1024)).toFixed(1)} MB`; return `${(bytes / (1024 * 1024 * 1024)).toFixed(2)} GB`; }; const resolveV2TableContextMenuMeta = (stats?: V2TableContextMenuStats): string => { if (!stats) return t('sidebar.v2_table_menu.meta.idle'); if (stats?.loading) return t('sidebar.v2_table_menu.meta.loading'); if (stats?.unavailable) return t('sidebar.v2_table_menu.meta.unavailable'); return t('sidebar.v2_table_menu.meta.summary', { rows: formatV2TableContextMenuRows(stats?.rowCount), data: formatV2TableContextMenuSize(stats?.dataLength), indexes: formatV2TableContextMenuSize(stats?.indexLength), }); }; const V2TableContextMenuItem: React.FC<{ item: V2TableContextMenuItemConfig; onAction?: (action: string) => void; }> = ({ item, onAction }) => ( ); const V2ContextMenuHeader: React.FC<{ icon: React.ReactNode; title: string; meta: string; pill?: string; }> = ({ icon, title, meta, pill }) => (
{icon} {title} {meta} {pill && ( {pill} )}
); const renderV2ContextMenuItems = ( items: V2TableContextMenuItemConfig[], onAction?: (action: string) => void, ) => items.map((item) => ( )); export const V2TableContextMenuView: React.FC<{ tableName: string; shortcutPlatform?: ShortcutPlatform; stats?: V2TableContextMenuStats; isPinned?: boolean; supportsTruncate?: boolean; supportsStarRocksRollup?: boolean; supportsMessagePublish?: boolean; onAction?: (action: V2TableContextMenuActionKey) => void; }> = ({ tableName, shortcutPlatform = DEFAULT_V2_CONTEXT_MENU_SHORTCUT_PLATFORM, stats, isPinned = false, supportsTruncate = true, supportsStarRocksRollup = false, supportsMessagePublish = false, onAction, }) => { const renderItems = (items: V2TableContextMenuItemConfig[]) => renderV2ContextMenuItems( items, onAction as (action: string) => void, ); const maintenanceItems: V2TableContextMenuItemConfig[] = [ { action: 'rename-table', icon: , title: t('sidebar.v2_table_menu.rename_compact'), kbd: 'F2' }, ...(supportsStarRocksRollup ? [{ action: 'new-rollup' as const, icon: , title: t('sidebar.v2_table_menu.new_rollup', { keyword: 'Rollup' }) }] : []), { action: 'backup-table', icon: , title: t('sidebar.v2_table_menu.backup_sql_dump', { keyword: 'SQL Dump' }) }, { action: 'refresh-stats', icon: , title: t('sidebar.v2_table_menu.refresh_stats') }, ]; const dangerItems: V2TableContextMenuItemConfig[] = [ ...(supportsTruncate ? [{ action: 'truncate-table' as const, icon: , title: t('sidebar.v2_table_menu.item_with_suffix', { label: t('sidebar.v2_table_menu.truncate_table'), suffix: 'TRUNCATE' }), tone: 'danger' as const, }] : []), { action: 'drop-table', icon: , title: t('sidebar.v2_table_menu.item_with_suffix', { label: t('sidebar.menu.delete_table'), suffix: 'DROP' }), kbd: '⌫', tone: 'danger', }, ]; return (
} title={tableName} meta={resolveV2TableContextMenuMeta(stats)} pill={(stats?.engine || stats?.loading) ? (stats?.loading ? '...' : stats?.engine) : undefined} />
{renderItems([ { action: 'open-data', icon: , title: t('sidebar.v2_table_menu.open_data'), kbd: '↵', featured: true }, { action: isPinned ? 'unpin-table' : 'pin-table', icon: , title: isPinned ? t('sidebar.action.unpin_table') : t('sidebar.action.pin_table'), kbd: isPinned ? t('sidebar.status.pinned') : undefined, selected: isPinned }, { action: 'design-table', icon: , title: `${t('sidebar.menu.design_table')} · ${t('sidebar.v2_table_menu.design_table_detail')}`, kbd: primaryShortcut('D', shortcutPlatform) }, { action: 'open-new-tab', icon: , title: t('sidebar.v2_table_menu.open_in_new_tab'), kbd: primaryShortcut('Enter', shortcutPlatform) }, { action: 'new-query', icon: , title: t('sidebar.menu.new_query') }, ...(supportsMessagePublish ? [{ action: 'publish-message' as const, icon: , title: '测试发送消息' }] : []), ])}
{t('sidebar.v2_table_menu.metadata_section')}
{renderItems([ { action: 'view-ddl', icon: , title: `${t('data_grid.ddl.view')} · CREATE TABLE` }, { action: 'view-er', icon: , title: t('sidebar.v2_table_menu.view_in_er') }, ])}
{t('sidebar.v2_table_menu.copy_section')}
{renderItems([ { action: 'copy-table-name', icon: , title: t('sidebar.v2_table_menu.copy_table_name'), kbd: primaryShortcut('C', shortcutPlatform) }, { action: 'copy-structure', icon: , title: `${t('sidebar.menu.copy_table_structure')} · DDL` }, { action: 'copy-insert', icon: , title: t('sidebar.v2_table_menu.copy_table_as_insert', { keyword: 'INSERT' }) }, ])}
{t('sidebar.v2_table_menu.maintenance_section')}
{renderItems(maintenanceItems)}
{t('sidebar.menu.export_table_data')}
{renderItems([ { action: 'export-data', icon: , title: t('sidebar.v2_table_menu.open_export_workbench') }, ])}
{renderItems([ { action: 'ai-explain', icon: , title: t('sidebar.v2_table_menu.ai_explain_table'), tone: 'ai', featured: true }, { action: 'ai-generate-query', icon: , title: t('sidebar.v2_table_menu.ai_generate_query'), tone: 'ai' }, ])}
{renderItems(dangerItems)}
); }; export type V2TableGroupContextMenuActionKey = | 'new-table' | 'sort-by-name' | 'sort-by-frequency'; export const V2TableGroupContextMenuView: React.FC<{ title?: string; shortcutPlatform?: ShortcutPlatform; dbName?: string; count?: number; currentSort?: 'name' | 'frequency'; onAction?: (action: V2TableGroupContextMenuActionKey) => void; }> = ({ title, shortcutPlatform = DEFAULT_V2_CONTEXT_MENU_SHORTCUT_PLATFORM, dbName, count, currentSort = 'name', onAction, }) => { const sortLabel = currentSort === 'frequency' ? t('sidebar.v2_table_group_menu.sort_frequency') : t('sidebar.v2_table_group_menu.sort_name'); const databaseLabel = dbName || t('sidebar.v2_table_group_menu.current_database'); const tableCountLabel = Math.max(0, count ?? 0).toLocaleString(getCurrentLanguage()); const renderItems = (items: V2TableContextMenuItemConfig[]) => renderV2ContextMenuItems( items, onAction as (action: string) => void, ); return (
} title={title ?? t('sidebar.v2_table_group_menu.title')} meta={t('sidebar.v2_table_group_menu.meta', { database: databaseLabel, count: tableCountLabel, sort: sortLabel, })} pill="GROUP" />
{renderItems([ { action: 'new-table', icon: , title: t('sidebar.menu.create_table'), kbd: primaryShortcut('N', shortcutPlatform), featured: true }, ])}
{t('data_grid.context_menu.sort_section')}
{renderItems([ { action: 'sort-by-name', icon: currentSort === 'name' ? : , title: t('sidebar.menu.sort_by_name'), kbd: currentSort === 'name' ? t('data_grid.context_menu.current_marker') : undefined, selected: currentSort === 'name' }, { action: 'sort-by-frequency', icon: currentSort === 'frequency' ? : , title: t('sidebar.menu.sort_by_frequency'), kbd: currentSort === 'frequency' ? t('data_grid.context_menu.current_marker') : undefined, selected: currentSort === 'frequency' }, ])}
); }; export type V2DatabaseContextMenuActionKey = | 'new-table' | 'new-schema' | 'new-materialized-view' | 'new-external-catalog' | 'rename-db' | 'refresh' | 'export-db-schema' | 'backup-db-sql' | 'disconnect-db' | 'new-query' | 'run-sql' | 'drop-db'; export type V2SchemaContextMenuActionKey = | 'rename-schema' | 'refresh-schema' | 'export-schema' | 'backup-schema-sql' | 'drop-schema'; export const V2DatabaseContextMenuView: React.FC<{ dbName: string; shortcutPlatform?: ShortcutPlatform; dialect?: string; supportsSchemaActions?: boolean; supportsStarRocksActions?: boolean; supportsRenameDatabase?: boolean; supportsDropDatabase?: boolean; onAction?: (action: V2DatabaseContextMenuActionKey) => void; }> = ({ dbName, shortcutPlatform = DEFAULT_V2_CONTEXT_MENU_SHORTCUT_PLATFORM, dialect, supportsSchemaActions = false, supportsStarRocksActions = false, supportsRenameDatabase = true, supportsDropDatabase = true, onAction, }) => { const renderItems = (items: V2TableContextMenuItemConfig[]) => renderV2ContextMenuItems( items, onAction as (action: string) => void, ); return (
} title={dbName} meta={t('sidebar.v2_database_menu.meta', { dialect: dialect || 'database' })} pill="DB" />
{renderItems([ { action: 'new-table', icon: , title: t('sidebar.menu.create_table'), kbd: primaryShortcut('N', shortcutPlatform), featured: true }, ...(supportsSchemaActions ? [{ action: 'new-schema', icon: , title: t('sidebar.v2_database_menu.new_schema') }] : []), { action: 'new-query', icon: , title: t('sidebar.menu.new_query') }, { action: 'run-sql', icon: , title: t('sidebar.sql_file_exec.title') }, ])} {supportsStarRocksActions && ( <>
StarRocks
{renderItems([ { action: 'new-materialized-view', icon: , title: t('sidebar.v2_database_menu.new_materialized_view') }, { action: 'new-external-catalog', icon: , title: t('sidebar.v2_database_menu.new_external_catalog') }, ])} )}
{t('sidebar.v2_table_menu.maintenance_section')}
{renderItems([ ...(supportsRenameDatabase ? [{ action: 'rename-db', icon: , title: t('sidebar.menu.rename_database'), kbd: 'F2' }] : []), { action: 'refresh', icon: , title: t('sidebar.v2_database_menu.refresh_object_tree') }, { action: 'disconnect-db', icon: , title: t('sidebar.menu.close_database') }, ])}
{t('sidebar.v2_database_menu.export_backup_section')}
{renderItems([ { action: 'export-db-schema', icon: , title: t('sidebar.v2_database_menu.export_all_table_schema_sql') }, { action: 'backup-db-sql', icon: , title: t('sidebar.v2_database_menu.backup_all_tables_sql') }, ])}
{supportsDropDatabase && renderItems([ { action: 'drop-db', icon: , title: t('sidebar.v2_table_menu.item_with_suffix', { label: t('sidebar.menu.delete_database'), suffix: 'DROP' }), tone: 'danger', kbd: '⌫' }, ])}
); }; export const V2SchemaContextMenuView: React.FC<{ dbName: string; schemaName: string; shortcutPlatform?: ShortcutPlatform; onAction?: (action: V2SchemaContextMenuActionKey) => void; }> = ({ dbName, schemaName, shortcutPlatform = DEFAULT_V2_CONTEXT_MENU_SHORTCUT_PLATFORM, onAction, }) => { const renderItems = (items: V2TableContextMenuItemConfig[]) => renderV2ContextMenuItems( items, onAction as (action: string) => void, ); return (
} title={schemaName} meta={`${dbName || '当前数据库'} · 模式操作`} pill="SCHEMA" />
维护
{renderItems([ { action: 'rename-schema', icon: , title: '编辑模式', kbd: 'F2', featured: true }, { action: 'refresh-schema', icon: , title: '刷新对象树', kbd: primaryShortcut('R', shortcutPlatform) }, ])}
导出与备份
{renderItems([ { action: 'export-schema', icon: , title: '导出当前模式表结构 · SQL' }, { action: 'backup-schema-sql', icon: , title: '备份当前模式全部表 · 结构 + 数据' }, ])}
{renderItems([ { action: 'drop-schema', icon: , title: '删除模式 · DROP CASCADE', tone: 'danger', kbd: '⌫' }, ])}
); }; const DEFAULT_V2_CONTEXT_MENU_SHORTCUT_PLATFORM: ShortcutPlatform = 'windows'; const primaryShortcut = ( key: string, shortcutPlatform: ShortcutPlatform = DEFAULT_V2_CONTEXT_MENU_SHORTCUT_PLATFORM, ): string => getPrimaryShortcutDisplayLabel(key, shortcutPlatform); export type V2ConnectionContextMenuActionKey = | 'new-db' | 'refresh' | 'new-query' | 'open-sql-file' | 'new-command' | 'open-monitor' | 'edit' | 'copy-connection' | 'disconnect' | 'delete' | 'move-to-ungrouped' | `move-to-tag:${string}`; export type V2ConnectionContextMenuTagItem = { id: string; name: string; selected?: boolean; }; export type V2ConnectionGroupContextMenuActionKey = | 'edit-group' | 'delete-group'; export const V2ConnectionGroupContextMenuView: React.FC<{ groupName: string; count?: number; onAction?: (action: V2ConnectionGroupContextMenuActionKey) => void; }> = ({ groupName, count = 0, onAction, }) => { const renderItems = (items: V2TableContextMenuItemConfig[]) => renderV2ContextMenuItems( items, onAction as (action: string) => void, ); return (
} title={groupName || t('connection.sidebar.group.untitled')} meta={t('connection.sidebar.group.meta', { count: count.toLocaleString() })} pill={t('connection.sidebar.group.badge')} />
{renderItems([ { action: 'edit-group', icon: , title: t('connection.sidebar.group.edit'), kbd: 'F2', featured: true }, ])}
{renderItems([ { action: 'delete-group', icon: , title: t('connection.sidebar.group.delete'), tone: 'danger', kbd: '⌫' }, ])}
); }; export const V2ConnectionContextMenuView: React.FC<{ connectionName: string; shortcutPlatform?: ShortcutPlatform; hostSummary?: string; driverLabel?: string; isRedis?: boolean; supportsCreateDatabase?: boolean; tags?: V2ConnectionContextMenuTagItem[]; onAction?: (action: V2ConnectionContextMenuActionKey) => void; }> = ({ connectionName, shortcutPlatform = DEFAULT_V2_CONTEXT_MENU_SHORTCUT_PLATFORM, hostSummary, driverLabel, isRedis = false, supportsCreateDatabase = true, tags = [], onAction, }) => { const renderItems = (items: V2TableContextMenuItemConfig[]) => renderV2ContextMenuItems( items, onAction as (action: string) => void, ); const hasSelectedTag = tags.some((tag) => tag.selected); const meta = [ driverLabel || (isRedis ? 'redis' : 'database'), hostSummary || t('connection.sidebar.menu.hostFallback'), ].filter(Boolean).join(' · '); return (
: } title={connectionName} meta={meta} pill={t('connection.sidebar.menu.hostBadge')} />
{isRedis ? renderItems([ { action: 'refresh', icon: , title: t('connection.sidebar.menu.refresh'), kbd: primaryShortcut('R', shortcutPlatform), featured: true }, { action: 'new-command', icon: , title: t('sidebar.menu.new_command_window'), featured: true }, { action: 'open-monitor', icon: , title: t('redis_monitor.title.instance') }, ]) : renderItems([ ...(supportsCreateDatabase ? [{ action: 'new-db' as const, icon: , title: t('connection.sidebar.menu.createDatabase'), kbd: primaryShortcut('N', shortcutPlatform), featured: true }] : []), { action: 'refresh', icon: , title: t('connection.sidebar.menu.refresh'), kbd: primaryShortcut('R', shortcutPlatform) }, { action: 'new-query', icon: , title: t('sidebar.menu.new_query') }, { action: 'open-sql-file', icon: , title: t('sidebar.sql_file_exec.title') }, ])}
{t('connection.sidebar.menu.section')}
{renderItems([ { action: 'edit', icon: , title: t('sidebar.menu.edit_connection'), kbd: 'F2' }, { action: 'copy-connection', icon: , title: t('connection.sidebar.menu.copy') }, { action: 'disconnect', icon: , title: t('connection.sidebar.menu.disconnect') }, ])} {tags.length > 0 && ( <>
{t('connection.sidebar.menu.groupSection')}
{renderItems([ ...tags.map((tag): V2TableContextMenuItemConfig => ({ action: `move-to-tag:${tag.id}`, icon: tag.selected ? : , title: tag.name, kbd: tag.selected ? t('connection.sidebar.menu.current') : undefined, selected: tag.selected, })), { action: 'move-to-ungrouped', icon: hasSelectedTag ? : , title: t('connection.sidebar.menu.moveToUngrouped'), kbd: hasSelectedTag ? undefined : t('connection.sidebar.menu.current'), selected: !hasSelectedTag, }, ])} )}
{renderItems([ { action: 'delete', icon: , title: t('connection.sidebar.menu.delete'), tone: 'danger', kbd: '⌫' }, ])}
); }; export type V2CellContextMenuActionKey = | 'copy-field-name' | 'copy-row-data' | 'copy-row-for-paste' | 'paste-row-as-new' | 'copy-column-data' | 'undo-cell-change' | 'set-null' | 'edit-row' | 'fill-selected' | 'paste-copied-columns' | 'copy-insert' | 'copy-update' | 'copy-delete' | 'copy-json' | 'copy-csv' | 'copy-markdown' | 'export-csv' | 'export-xlsx' | 'export-json' | 'export-html'; export type V2ColumnHeaderContextMenuActionKey = | 'copy-field-name' | 'copy-column-data' | 'sort-asc' | 'sort-desc' | 'clear-sort' | 'auto-fit-column' | 'hide-column' | 'show-column-type' | 'hide-column-type' | 'show-column-comment' | 'hide-column-comment'; export const V2ColumnHeaderContextMenuView: React.FC<{ fieldName: string; shortcutPlatform?: ShortcutPlatform; columnType?: string; columnComment?: string; sortOrder?: 'ascend' | 'descend' | null; showColumnType?: boolean; showColumnComment?: boolean; onAction?: (action: V2ColumnHeaderContextMenuActionKey) => void; }> = ({ fieldName, shortcutPlatform = DEFAULT_V2_CONTEXT_MENU_SHORTCUT_PLATFORM, columnType, columnComment, sortOrder, showColumnType = true, showColumnComment = true, onAction, }) => { const renderItems = (items: V2TableContextMenuItemConfig[]) => renderV2ContextMenuItems( items, onAction as (action: string) => void, ); const normalizedType = String(columnType || '').trim(); const normalizedComment = String(columnComment || '').trim(); const meta = [ normalizedType || t('data_grid.context_menu.column_unknown_type'), normalizedComment || t('data_grid.context_menu.column_no_comment'), ].join(' · '); return (
} title={fieldName || t('data_grid.context_menu.column_unnamed_field')} meta={meta} pill="FIELD" />
{t('sidebar.v2_table_menu.copy_section')}
{renderItems([ { action: 'copy-field-name', icon: , title: t('data_grid.context_menu.copy_field_name'), kbd: primaryShortcut('C', shortcutPlatform), featured: true }, { action: 'copy-column-data', icon: , title: t('data_grid.context_menu.copy_column_data') }, ])}
{t('data_grid.context_menu.sort_section')}
{renderItems([ { action: 'sort-asc', icon: , title: t('data_grid.context_menu.sort_ascending'), selected: sortOrder === 'ascend', kbd: sortOrder === 'ascend' ? t('data_grid.context_menu.current_marker') : undefined }, { action: 'sort-desc', icon: , title: t('data_grid.context_menu.sort_descending'), selected: sortOrder === 'descend', kbd: sortOrder === 'descend' ? t('data_grid.context_menu.current_marker') : undefined }, { action: 'clear-sort', icon: , title: t('data_grid.context_menu.clear_column_sort'), disabled: !sortOrder }, ])}
{t('data_grid.context_menu.column_display_section')}
{renderItems([ { action: 'auto-fit-column', icon: , title: t('data_grid.context_menu.auto_fit_column') }, { action: 'hide-column', icon: , title: t('data_grid.context_menu.hide_column') }, { action: showColumnType ? 'hide-column-type' : 'show-column-type', icon: , title: showColumnType ? t('data_grid.context_menu.hide_column_type') : t('data_grid.context_menu.show_column_type'), selected: showColumnType, }, { action: showColumnComment ? 'hide-column-comment' : 'show-column-comment', icon: , title: showColumnComment ? t('data_grid.context_menu.hide_column_comment') : t('data_grid.context_menu.show_column_comment'), selected: showColumnComment, }, ])}
); }; export const V2CellContextMenuView: React.FC<{ fieldName: string; shortcutPlatform?: ShortcutPlatform; tableName?: string; rowLabel?: string; selectedRowCount?: number; canModifyData?: boolean; canUndoCellChange?: boolean; copiedRowCount?: number; canPasteCopiedColumns?: boolean; supportsCopyInsert?: boolean; onAction?: (action: V2CellContextMenuActionKey) => void; }> = ({ fieldName, shortcutPlatform = DEFAULT_V2_CONTEXT_MENU_SHORTCUT_PLATFORM, tableName, rowLabel, selectedRowCount = 0, canModifyData = false, canUndoCellChange = false, copiedRowCount = 0, canPasteCopiedColumns = false, supportsCopyInsert = true, onAction, }) => { const renderItems = (items: V2TableContextMenuItemConfig[]) => renderV2ContextMenuItems( items, onAction as (action: string) => void, ); const selectedCountLabel = Math.max(0, selectedRowCount).toLocaleString(getCurrentLanguage()); const menuTitle = fieldName || t('data_grid.context_menu.column_unnamed_field'); const meta = [tableName, rowLabel || t('data_grid.context_menu.current_row')].filter(Boolean).join(' · ') || t('data_grid.context_menu.current_cell'); return (
} title={menuTitle} meta={meta} pill="CELL" />
{renderItems([ { action: 'copy-field-name', icon: , title: t('data_grid.context_menu.copy_field_name'), kbd: primaryShortcut('C', shortcutPlatform), featured: true }, ])} {canModifyData && ( <>
{t('data_grid.context_menu.edit_section')}
{renderItems([ { action: 'undo-cell-change', icon: , title: t('data_grid.context_menu.undo_cell_change'), disabled: !canUndoCellChange, }, { action: 'set-null', icon: , title: t('data_grid.batch_fill.set_null') }, { action: 'edit-row', icon: , title: t('data_grid.context_menu.edit_row'), kbd: '↵' }, { action: 'copy-row-for-paste', icon: , title: t('data_grid.context_menu.copy_row_as_new') }, { action: 'paste-row-as-new', icon: , title: copiedRowCount > 0 ? t('data_grid.context_menu.paste_row_as_new_count', { count: copiedRowCount.toLocaleString(getCurrentLanguage()) }) : t('data_grid.context_menu.paste_row_as_new'), disabled: copiedRowCount <= 0, }, { action: 'fill-selected', icon: , title: t('data_grid.context_menu.fill_to_selected_rows', { count: selectedCountLabel }), disabled: selectedRowCount <= 0, }, { action: 'paste-copied-columns', icon: , title: t('data_grid.context_menu.paste_copied_columns'), disabled: !canPasteCopiedColumns, }, ])} )}
{t('sidebar.v2_table_menu.copy_section')}
{renderItems([ { action: 'copy-row-data', icon: , title: t('data_grid.context_menu.copy_row_data') }, { action: 'copy-column-data', icon: , title: t('data_grid.context_menu.copy_column_data') }, ...(supportsCopyInsert ? [ { action: 'copy-insert' as const, icon: , title: t('data_grid.context_menu.copy_as_insert'), kbd: 'SQL' }, { action: 'copy-update' as const, icon: , title: t('data_grid.context_menu.copy_as_update') }, { action: 'copy-delete' as const, icon: , title: t('data_grid.context_menu.copy_as_delete') }, ] : []), { action: 'copy-json', icon: , title: t('data_grid.context_menu.copy_as_json') }, { action: 'copy-csv', icon: , title: t('data_grid.context_menu.copy_as_csv') }, { action: 'copy-markdown', icon: , title: t('data_grid.context_menu.copy_as_markdown') }, ])}
{t('data_grid.toolbar.export')}
{renderItems([ { action: 'export-csv', icon: , title: t('sidebar.v2_table_menu.item_with_suffix', { label: 'CSV', suffix: '.csv' }) }, { action: 'export-xlsx', icon: , title: t('sidebar.v2_table_menu.item_with_suffix', { label: 'Excel', suffix: '.xlsx' }) }, { action: 'export-json', icon: , title: t('sidebar.v2_table_menu.item_with_suffix', { label: 'JSON', suffix: '.json' }) }, { action: 'export-html', icon: , title: t('sidebar.v2_table_menu.item_with_suffix', { label: 'HTML', suffix: '.html' }) }, ])}
); };