From 9e9ec13db057cd583a61fe2eb52f4c4e64e6d944 Mon Sep 17 00:00:00 2001 From: alex <48489896+devnaumov@users.noreply.github.com> Date: Mon, 10 Feb 2025 14:48:35 +0100 Subject: [PATCH] CB-6128 add tooltips to tabs (#3221) * CB-6128 add tooltips to tabs * CB-6128 add project to the tooltip * CB-6128 remove code duplication * CB-6128 change file name --------- Co-authored-by: Evgenia <139753579+EvgeniaBzzz@users.noreply.github.com> --- webapp/packages/core-blocks/src/index.ts | 1 + .../core-blocks/src/useObjectInfoTooltip.ts | 33 +++++++++++++++++++ .../core-localization/src/locales/en.ts | 4 +++ .../core-localization/src/locales/fr.ts | 4 +++ .../core-localization/src/locales/it.ts | 4 +++ .../core-localization/src/locales/ru.ts | 4 +++ .../core-localization/src/locales/zh.ts | 5 +++ .../src/ObjectViewerTab.tsx | 15 ++++++++- .../src/SqlEditorTab.tsx | 19 ++++++----- 9 files changed, 80 insertions(+), 9 deletions(-) create mode 100644 webapp/packages/core-blocks/src/useObjectInfoTooltip.ts diff --git a/webapp/packages/core-blocks/src/index.ts b/webapp/packages/core-blocks/src/index.ts index c069fae2b0..68d0649602 100644 --- a/webapp/packages/core-blocks/src/index.ts +++ b/webapp/packages/core-blocks/src/index.ts @@ -257,3 +257,4 @@ export * from './Flex/Flex.js'; export * from './FormControls/useInputAutocomplete.js'; export * from './FormControls/InputAutocompletionMenu.js'; export * from './useSearch.js'; +export * from './useObjectInfoTooltip.js'; diff --git a/webapp/packages/core-blocks/src/useObjectInfoTooltip.ts b/webapp/packages/core-blocks/src/useObjectInfoTooltip.ts new file mode 100644 index 0000000000..b33e55f96c --- /dev/null +++ b/webapp/packages/core-blocks/src/useObjectInfoTooltip.ts @@ -0,0 +1,33 @@ +/* + * CloudBeaver - Cloud Database Manager + * Copyright (C) 2020-2024 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 { useTranslate } from './localization/useTranslate.js'; + +export function useObjectInfoTooltip(connection?: string, catalog?: string, schema?: string, project?: string) { + const translate = useTranslate(); + + let result = ''; + + if (connection) { + result += `${translate('ui_connection')}: ${connection}`; + } + + if (catalog) { + result += `\n${translate('ui_catalog')}: ${catalog}`; + } + + if (schema) { + result += `\n${translate('ui_schema')}: ${schema}`; + } + + if (project) { + result += `\n${translate('ui_project')}: ${project}`; + } + + return result || undefined; +} diff --git a/webapp/packages/core-localization/src/locales/en.ts b/webapp/packages/core-localization/src/locales/en.ts index 1fdb2d02ae..8060a5817d 100644 --- a/webapp/packages/core-localization/src/locales/en.ts +++ b/webapp/packages/core-localization/src/locales/en.ts @@ -138,6 +138,10 @@ export default [ ['ui_you', 'You'], ['ui_ms', 'ms'], ['ui_not_found', 'Not found'], + ['ui_connection', 'Connection'], + ['ui_catalog', 'Catalog'], + ['ui_schema', 'Schema'], + ['ui_project', 'Project'], ['root_permission_denied', "You don't have permissions"], ['root_permission_no_permission', "You don't have permission for this action"], diff --git a/webapp/packages/core-localization/src/locales/fr.ts b/webapp/packages/core-localization/src/locales/fr.ts index 2b68c71825..1c5adadb2a 100644 --- a/webapp/packages/core-localization/src/locales/fr.ts +++ b/webapp/packages/core-localization/src/locales/fr.ts @@ -132,6 +132,10 @@ export default [ ['ui_you', 'Vous'], ['ui_ms', 'ms'], ['ui_not_found', 'Not found'], + ['ui_connection', 'Connection'], + ['ui_catalog', 'Catalog'], + ['ui_schema', 'Schema'], + ['ui_project', 'Project'], ['root_permission_denied', "Vous n'avez pas les permissions"], ['root_permission_no_permission', "Vous n'avez pas la permission pour cette action"], diff --git a/webapp/packages/core-localization/src/locales/it.ts b/webapp/packages/core-localization/src/locales/it.ts index 1d8aafe290..9bb6c00a59 100644 --- a/webapp/packages/core-localization/src/locales/it.ts +++ b/webapp/packages/core-localization/src/locales/it.ts @@ -128,6 +128,10 @@ export default [ ['ui_you', 'You'], ['ui_ms', 'ms'], ['ui_not_found', 'Not found'], + ['ui_connection', 'Connection'], + ['ui_catalog', 'Catalog'], + ['ui_schema', 'Schema'], + ['ui_project', 'Project'], ['root_permission_denied', 'Non hai i permessi'], ['app_root_session_expire_warning_title', 'La sessione sta per scadere'], diff --git a/webapp/packages/core-localization/src/locales/ru.ts b/webapp/packages/core-localization/src/locales/ru.ts index 8fa57ca071..fc5284342b 100644 --- a/webapp/packages/core-localization/src/locales/ru.ts +++ b/webapp/packages/core-localization/src/locales/ru.ts @@ -134,6 +134,10 @@ export default [ ['ui_you', 'Вы'], ['ui_ms', 'мс'], ['ui_not_found', 'Не найдено'], + ['ui_connection', 'Подключение'], + ['ui_catalog', 'Каталог'], + ['ui_schema', 'Схема'], + ['ui_project', 'Проект'], ['root_permission_denied', 'Отказано в доступе'], ['root_permission_no_permission', 'У вас нет разрешения на это действие'], diff --git a/webapp/packages/core-localization/src/locales/zh.ts b/webapp/packages/core-localization/src/locales/zh.ts index 8dc5cfe030..abbdc322c5 100644 --- a/webapp/packages/core-localization/src/locales/zh.ts +++ b/webapp/packages/core-localization/src/locales/zh.ts @@ -134,6 +134,11 @@ export default [ ['ui_export', '导出'], ['ui_you', '你'], ['ui_ms', 'ms'], + ['ui_connection', 'Connection'], + ['ui_catalog', 'Catalog'], + ['ui_schema', 'Schema'], + ['ui_project', 'Project'], + ['root_permission_denied', '您没有权限'], ['root_permission_no_permission', '您没有权限执行此操作'], ['app_root_session_expire_warning_title', '会话即将过期'], diff --git a/webapp/packages/plugin-object-viewer/src/ObjectViewerTab.tsx b/webapp/packages/plugin-object-viewer/src/ObjectViewerTab.tsx index 0b6caeed9a..19ae8550eb 100644 --- a/webapp/packages/plugin-object-viewer/src/ObjectViewerTab.tsx +++ b/webapp/packages/plugin-object-viewer/src/ObjectViewerTab.tsx @@ -8,7 +8,12 @@ import { observer } from 'mobx-react-lite'; import { useContext } from 'react'; +import { useObjectInfoTooltip } from '@cloudbeaver/core-blocks'; +import { ConnectionInfoResource } from '@cloudbeaver/core-connections'; import { useDataContext } from '@cloudbeaver/core-data-context'; +import { useService } from '@cloudbeaver/core-di'; +import { NavNodeManagerService } from '@cloudbeaver/core-navigation-tree'; +import { ProjectInfoResource } from '@cloudbeaver/core-projects'; import { type ITabData, Tab, TabIcon, TabTitle } from '@cloudbeaver/core-ui'; import { CaptureViewContext } from '@cloudbeaver/core-view'; import type { TabHandlerTabComponent } from '@cloudbeaver/plugin-navigation-tabs'; @@ -17,15 +22,23 @@ import { useNode } from '@cloudbeaver/plugin-navigation-tree'; import type { IObjectViewerTabState } from './IObjectViewerTabState.js'; export const ObjectViewerTab: TabHandlerTabComponent = observer(function ObjectViewerTab({ tab, onSelect, onClose }) { + const connectionInfoResource = useService(ConnectionInfoResource); + const navNodeManagerService = useService(NavNodeManagerService); + const projectInfoResource = useService(ProjectInfoResource); const viewContext = useContext(CaptureViewContext); const tabMenuContext = useDataContext(viewContext); const { node } = useNode(tab.handlerState.objectId); const handleSelect = ({ tabId }: ITabData) => onSelect(tabId); const handleClose = onClose ? ({ tabId }: ITabData) => onClose(tabId) : undefined; const title = node?.name || tab.handlerState.tabTitle; + const connection = tab.handlerState.connectionKey ? connectionInfoResource.get(tab.handlerState.connectionKey) : undefined; + const project = connection ? projectInfoResource.get(connection.projectId) : undefined; + const nodeInfo = node ? navNodeManagerService.getNodeContainerInfo(node.id) : undefined; + + const tooltip = useObjectInfoTooltip(connection?.name, nodeInfo?.catalogId, nodeInfo?.schemaId, project?.name); return ( - + {title} diff --git a/webapp/packages/plugin-sql-editor-navigation-tab/src/SqlEditorTab.tsx b/webapp/packages/plugin-sql-editor-navigation-tab/src/SqlEditorTab.tsx index 38cbdaf129..a7a3194120 100644 --- a/webapp/packages/plugin-sql-editor-navigation-tab/src/SqlEditorTab.tsx +++ b/webapp/packages/plugin-sql-editor-navigation-tab/src/SqlEditorTab.tsx @@ -8,10 +8,11 @@ import { observer } from 'mobx-react-lite'; import { useContext } from 'react'; -import { IconOrImage, s, useTranslate } from '@cloudbeaver/core-blocks'; -import { type Connection, ConnectionInfoResource, createConnectionParam } from '@cloudbeaver/core-connections'; +import { IconOrImage, s, useObjectInfoTooltip, useTranslate } from '@cloudbeaver/core-blocks'; +import { ConnectionInfoResource, createConnectionParam } from '@cloudbeaver/core-connections'; import { useDataContext, useDataContextLink } from '@cloudbeaver/core-data-context'; import { useService } from '@cloudbeaver/core-di'; +import { ProjectInfoResource } from '@cloudbeaver/core-projects'; import { type ITabData, Tab, TabIcon, TabTitle } from '@cloudbeaver/core-ui'; import { CaptureViewContext } from '@cloudbeaver/core-view'; import type { TabHandlerTabComponent } from '@cloudbeaver/plugin-navigation-tabs'; @@ -38,16 +39,16 @@ export const SqlEditorTab: TabHandlerTabComponent = observer const sqlDataSourceService = useService(SqlDataSourceService); const connectionInfo = useService(ConnectionInfoResource); + const projectInfo = useService(ProjectInfoResource); const translate = useTranslate(); const dataSource = sqlDataSourceService.get(handlerState.editorId); - let connection: Connection | undefined; const executionContext = dataSource?.executionContext; - - if (executionContext) { - connection = connectionInfo.get(createConnectionParam(executionContext.projectId, executionContext.connectionId)); - } + const project = executionContext ? projectInfo.get(executionContext.projectId) : undefined; + const connection = executionContext + ? connectionInfo.get(createConnectionParam(executionContext.projectId, executionContext.connectionId)) + : undefined; const name = getSqlEditorName(handlerState, dataSource, connection); const icon = dataSource?.icon ?? '/icons/sql_script_m.svg'; @@ -59,8 +60,10 @@ export const SqlEditorTab: TabHandlerTabComponent = observer const handleSelect = ({ tabId }: ITabData) => onSelect(tabId); const handleClose = onClose ? ({ tabId }: ITabData) => onClose(tabId) : undefined; + const tooltip = useObjectInfoTooltip(connection?.name, executionContext?.defaultCatalog, executionContext?.defaultSchema, project?.name); + return ( - + {name} {isReadonly && isScript && (