From 7068373be98a47663ee7f311264d1a406ec83c63 Mon Sep 17 00:00:00 2001 From: Anton Standrik Date: Thu, 30 Oct 2025 17:22:42 +0300 Subject: [PATCH 1/7] feat: option to insert additional diagnostics tab --- .rooignore | 34 +++++++++++++++++++ .../Tenant/Diagnostics/Diagnostics.tsx | 16 +++++++++ .../Tenant/Diagnostics/DiagnosticsPages.ts | 31 ++++++++++++++++- src/lib.ts | 1 + src/store/reducers/tenant/types.ts | 2 +- src/uiFactory/types.ts | 22 +++++++++++- 6 files changed, 103 insertions(+), 3 deletions(-) create mode 100644 .rooignore diff --git a/.rooignore b/.rooignore new file mode 100644 index 0000000000..55195ae5b8 --- /dev/null +++ b/.rooignore @@ -0,0 +1,34 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js + +# testing +/coverage +playwright-artifacts + +# production +/build +/dist +*.zip + +# misc +.idea +.DS_Store +.env.local +.env.development.local +.env.test.local +.env.production.local +.vscode +.cursor + +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +.env + + +embedded-ui.tar.bz2 \ No newline at end of file diff --git a/src/containers/Tenant/Diagnostics/Diagnostics.tsx b/src/containers/Tenant/Diagnostics/Diagnostics.tsx index 86f5fec76e..a53bbd41b1 100644 --- a/src/containers/Tenant/Diagnostics/Diagnostics.tsx +++ b/src/containers/Tenant/Diagnostics/Diagnostics.tsx @@ -215,6 +215,22 @@ function Diagnostics({additionalTenantProps}: DiagnosticsProps) { }); } default: { + const customTab = uiFactory.additionalDiagnosticsTabs?.find( + (tab) => tab.id === activeTab?.id, + ); + + if (customTab) { + return customTab.render({ + type, + subType, + database, + path, + databaseFullPath, + additionalTenantProps, + scrollContainerRef: containerRef, + }); + } + return
{i18n('no-data')}
; } } diff --git a/src/containers/Tenant/Diagnostics/DiagnosticsPages.ts b/src/containers/Tenant/Diagnostics/DiagnosticsPages.ts index 3e0b4ff8a5..7560288f57 100644 --- a/src/containers/Tenant/Diagnostics/DiagnosticsPages.ts +++ b/src/containers/Tenant/Diagnostics/DiagnosticsPages.ts @@ -7,6 +7,8 @@ import {TENANT_DIAGNOSTICS_TABS_IDS} from '../../../store/reducers/tenant/consta import type {TenantDiagnosticsTab} from '../../../store/reducers/tenant/types'; import {EPathSubType, EPathType} from '../../../types/api/schema'; import type {ETenantType} from '../../../types/api/tenant'; +import type {AdditionalDiagnosticsTab} from '../../../uiFactory/types'; +import {uiFactory} from '../../../uiFactory/uiFactory'; import type {TenantQuery} from '../TenantPages'; import {TenantTabsGroups} from '../TenantPages'; import {isDatabaseEntityType, isTopicEntityType} from '../utils/schema'; @@ -233,7 +235,34 @@ export const getPagesByType = ( const dbContext = isDatabaseEntityType(type) || options?.isTopLevel; const seeded = dbContext ? getDatabasePages(options?.databaseType) : base; - return applyFilters(seeded, type, options); + const filtered = applyFilters(seeded, type, options); + + // Add custom tabs from uiFactory if available + const customTabsToInsert = + uiFactory.additionalDiagnosticsTabs?.filter( + (tab: AdditionalDiagnosticsTab) => !tab.shouldShow || tab.shouldShow(type, subType), + ) || []; + + if (customTabsToInsert.length === 0) { + return filtered; + } + + const result = [...filtered]; + + customTabsToInsert.forEach((customTab: AdditionalDiagnosticsTab) => { + const tabPage = {id: customTab.id, title: customTab.title}; + + if (customTab.insertAfter === undefined) { + // Append at the end + result.push(tabPage); + } else { + // Insert at specific index + const index = Math.max(0, Math.min(customTab.insertAfter, result.length)); + result.splice(index, 0, tabPage); + } + }); + + return result; }; export const useDiagnosticsPageLinkGetter = () => { diff --git a/src/lib.ts b/src/lib.ts index 5e1013c8d2..0ca030a18d 100644 --- a/src/lib.ts +++ b/src/lib.ts @@ -35,3 +35,4 @@ export type {AsideNavigationProps} from './containers/AsideNavigation/AsideNavig export type {GetMonitoringLink, GetMonitoringClusterLink} from './utils/monitoring'; export {configureUIFactory} from './uiFactory/uiFactory'; +export type {DiagnosticsTabProps, AdditionalDiagnosticsTab} from './uiFactory/types'; diff --git a/src/store/reducers/tenant/types.ts b/src/store/reducers/tenant/types.ts index 7e140abc88..9485de8329 100644 --- a/src/store/reducers/tenant/types.ts +++ b/src/store/reducers/tenant/types.ts @@ -14,7 +14,7 @@ export const tenantPageSchema = z.nativeEnum(TENANT_PAGES_IDS); export type TenantPage = z.infer; export type TenantQueryTab = ValueOf; -export type TenantDiagnosticsTab = ValueOf; +export type TenantDiagnosticsTab = ValueOf | string; export type TenantSummaryTab = ValueOf; export type TenantMetricsTab = ValueOf; diff --git a/src/uiFactory/types.ts b/src/uiFactory/types.ts index afa4f586d7..781a7eac33 100644 --- a/src/uiFactory/types.ts +++ b/src/uiFactory/types.ts @@ -9,8 +9,9 @@ import type { import type {ClusterInfo} from '../store/reducers/cluster/cluster'; import type {IssuesTree} from '../store/reducers/healthcheckInfo/types'; import type {PreparedTenant} from '../store/reducers/tenants/types'; -import type {ClusterLink, DatabaseLink} from '../types/additionalProps'; +import type {AdditionalTenantsProps, ClusterLink, DatabaseLink} from '../types/additionalProps'; import type {MetaBaseClusterInfo} from '../types/api/meta'; +import type {EPathSubType, EPathType} from '../types/api/schema/schema'; import type {ETenantType} from '../types/api/tenant'; import type {GetLogsLink} from '../utils/logs'; import type {GetMonitoringClusterLink, GetMonitoringLink} from '../utils/monitoring'; @@ -35,6 +36,7 @@ export interface UIFactory { renderBackups?: RenderBackups; renderEvents?: RenderEvents; + additionalDiagnosticsTabs?: AdditionalDiagnosticsTab[]; clusterOrDatabaseAccessError?: Partial; healthcheck: { @@ -85,3 +87,21 @@ export type RenderBackups = (props: { export type RenderEvents = (props: { scrollContainerRef: React.RefObject; }) => React.ReactNode; + +export type DiagnosticsTabProps = { + type?: EPathType; + subType?: EPathSubType; + database: string; + path: string; + databaseFullPath?: string; + additionalTenantProps?: AdditionalTenantsProps; + scrollContainerRef: React.RefObject; +}; + +export type AdditionalDiagnosticsTab = { + id: string; + title: string; + render: (props: DiagnosticsTabProps) => React.ReactNode; + shouldShow?: (type?: EPathType, subType?: EPathSubType) => boolean; + insertAfter?: number; +}; From 715197417ec2bedae610ac63b4752ba67e69bb82 Mon Sep 17 00:00:00 2001 From: Anton Standrik Date: Thu, 30 Oct 2025 17:48:07 +0300 Subject: [PATCH 2/7] fix: use render pattern --- .../Tenant/Diagnostics/Diagnostics.tsx | 27 ++++++--------- .../Tenant/Diagnostics/DiagnosticsPages.ts | 34 +++++-------------- src/lib.ts | 1 - src/store/reducers/tenant/constants.ts | 1 + src/store/reducers/tenant/types.ts | 2 +- src/uiFactory/types.ts | 14 ++------ 6 files changed, 25 insertions(+), 54 deletions(-) diff --git a/src/containers/Tenant/Diagnostics/Diagnostics.tsx b/src/containers/Tenant/Diagnostics/Diagnostics.tsx index a53bbd41b1..745b6a18aa 100644 --- a/src/containers/Tenant/Diagnostics/Diagnostics.tsx +++ b/src/containers/Tenant/Diagnostics/Diagnostics.tsx @@ -214,23 +214,18 @@ function Diagnostics({additionalTenantProps}: DiagnosticsProps) { scrollContainerRef: containerRef, }); } + case TENANT_DIAGNOSTICS_TABS_IDS.monitoring: { + return uiFactory.renderMonitoring?.({ + type, + subType, + database, + path, + databaseFullPath, + additionalTenantProps, + scrollContainerRef: containerRef, + }); + } default: { - const customTab = uiFactory.additionalDiagnosticsTabs?.find( - (tab) => tab.id === activeTab?.id, - ); - - if (customTab) { - return customTab.render({ - type, - subType, - database, - path, - databaseFullPath, - additionalTenantProps, - scrollContainerRef: containerRef, - }); - } - return
{i18n('no-data')}
; } } diff --git a/src/containers/Tenant/Diagnostics/DiagnosticsPages.ts b/src/containers/Tenant/Diagnostics/DiagnosticsPages.ts index 7560288f57..926b4714cb 100644 --- a/src/containers/Tenant/Diagnostics/DiagnosticsPages.ts +++ b/src/containers/Tenant/Diagnostics/DiagnosticsPages.ts @@ -7,7 +7,6 @@ import {TENANT_DIAGNOSTICS_TABS_IDS} from '../../../store/reducers/tenant/consta import type {TenantDiagnosticsTab} from '../../../store/reducers/tenant/types'; import {EPathSubType, EPathType} from '../../../types/api/schema'; import type {ETenantType} from '../../../types/api/tenant'; -import type {AdditionalDiagnosticsTab} from '../../../uiFactory/types'; import {uiFactory} from '../../../uiFactory/uiFactory'; import type {TenantQuery} from '../TenantPages'; import {TenantTabsGroups} from '../TenantPages'; @@ -112,6 +111,11 @@ const operations = { title: 'Operations', }; +const monitoring = { + id: TENANT_DIAGNOSTICS_TABS_IDS.monitoring, + title: 'Monitoring', +}; + const ASYNC_REPLICATION_PAGES = [overview, tablets, describe, access]; const TRANSFER_PAGES = [overview, tablets, describe, access]; @@ -235,33 +239,13 @@ export const getPagesByType = ( const dbContext = isDatabaseEntityType(type) || options?.isTopLevel; const seeded = dbContext ? getDatabasePages(options?.databaseType) : base; - const filtered = applyFilters(seeded, type, options); + const result = applyFilters(seeded, type, options); - // Add custom tabs from uiFactory if available - const customTabsToInsert = - uiFactory.additionalDiagnosticsTabs?.filter( - (tab: AdditionalDiagnosticsTab) => !tab.shouldShow || tab.shouldShow(type, subType), - ) || []; - - if (customTabsToInsert.length === 0) { - return filtered; + // Add monitoring tab as second tab if renderMonitoring is available + if (uiFactory.renderMonitoring) { + result.splice(1, 0, monitoring); } - const result = [...filtered]; - - customTabsToInsert.forEach((customTab: AdditionalDiagnosticsTab) => { - const tabPage = {id: customTab.id, title: customTab.title}; - - if (customTab.insertAfter === undefined) { - // Append at the end - result.push(tabPage); - } else { - // Insert at specific index - const index = Math.max(0, Math.min(customTab.insertAfter, result.length)); - result.splice(index, 0, tabPage); - } - }); - return result; }; diff --git a/src/lib.ts b/src/lib.ts index 0ca030a18d..5e1013c8d2 100644 --- a/src/lib.ts +++ b/src/lib.ts @@ -35,4 +35,3 @@ export type {AsideNavigationProps} from './containers/AsideNavigation/AsideNavig export type {GetMonitoringLink, GetMonitoringClusterLink} from './utils/monitoring'; export {configureUIFactory} from './uiFactory/uiFactory'; -export type {DiagnosticsTabProps, AdditionalDiagnosticsTab} from './uiFactory/types'; diff --git a/src/store/reducers/tenant/constants.ts b/src/store/reducers/tenant/constants.ts index 9b3ae84100..2efa6be3b1 100644 --- a/src/store/reducers/tenant/constants.ts +++ b/src/store/reducers/tenant/constants.ts @@ -30,6 +30,7 @@ export const TENANT_DIAGNOSTICS_TABS_IDS = { operations: 'operations', access: 'access', backups: 'backups', + monitoring: 'monitoring', } as const; export const TENANT_SUMMARY_TABS_IDS = { diff --git a/src/store/reducers/tenant/types.ts b/src/store/reducers/tenant/types.ts index 9485de8329..7e140abc88 100644 --- a/src/store/reducers/tenant/types.ts +++ b/src/store/reducers/tenant/types.ts @@ -14,7 +14,7 @@ export const tenantPageSchema = z.nativeEnum(TENANT_PAGES_IDS); export type TenantPage = z.infer; export type TenantQueryTab = ValueOf; -export type TenantDiagnosticsTab = ValueOf | string; +export type TenantDiagnosticsTab = ValueOf; export type TenantSummaryTab = ValueOf; export type TenantMetricsTab = ValueOf; diff --git a/src/uiFactory/types.ts b/src/uiFactory/types.ts index 781a7eac33..ed04f72635 100644 --- a/src/uiFactory/types.ts +++ b/src/uiFactory/types.ts @@ -36,7 +36,7 @@ export interface UIFactory { renderBackups?: RenderBackups; renderEvents?: RenderEvents; - additionalDiagnosticsTabs?: AdditionalDiagnosticsTab[]; + renderMonitoring?: RenderMonitoring; clusterOrDatabaseAccessError?: Partial; healthcheck: { @@ -88,7 +88,7 @@ export type RenderEvents = (props: { scrollContainerRef: React.RefObject; }) => React.ReactNode; -export type DiagnosticsTabProps = { +export type RenderMonitoring = (props: { type?: EPathType; subType?: EPathSubType; database: string; @@ -96,12 +96,4 @@ export type DiagnosticsTabProps = { databaseFullPath?: string; additionalTenantProps?: AdditionalTenantsProps; scrollContainerRef: React.RefObject; -}; - -export type AdditionalDiagnosticsTab = { - id: string; - title: string; - render: (props: DiagnosticsTabProps) => React.ReactNode; - shouldShow?: (type?: EPathType, subType?: EPathSubType) => boolean; - insertAfter?: number; -}; +}) => React.ReactNode; From f6ff486dc362c58943aa5e23fac7fe3e04feb18a Mon Sep 17 00:00:00 2001 From: Anton Standrik Date: Sat, 1 Nov 2025 10:31:06 +0300 Subject: [PATCH 3/7] fix: better code and buttons --- src/containers/Header/Header.tsx | 23 ++++++- .../Tenant/Diagnostics/Diagnostics.scss | 4 ++ .../Tenant/Diagnostics/Diagnostics.tsx | 24 +++---- .../Tenant/Diagnostics/DiagnosticsPages.ts | 25 +++++-- .../Tenant/Diagnostics/DiagnosticsTabItem.tsx | 33 ++++++++++ .../TenantOverview/TenantOverview.tsx | 65 +++++++++++++------ .../Diagnostics/TenantOverview/i18n/en.json | 1 + .../ObjectSummary/SchemaTree/SchemaTree.tsx | 2 + src/containers/Tenant/i18n/en.json | 1 + src/containers/Tenant/utils/schemaActions.tsx | 27 ++++++-- src/routes.ts | 2 +- src/utils/additionalProps.ts | 36 ++++++++++ src/utils/constants.ts | 1 + 13 files changed, 200 insertions(+), 44 deletions(-) create mode 100644 src/containers/Tenant/Diagnostics/DiagnosticsTabItem.tsx diff --git a/src/containers/Header/Header.tsx b/src/containers/Header/Header.tsx index 172f94c7ef..ecbf83e654 100644 --- a/src/containers/Header/Header.tsx +++ b/src/containers/Header/Header.tsx @@ -28,7 +28,7 @@ import {clustersApi} from '../../store/reducers/clusters/clusters'; import {tenantApi} from '../../store/reducers/tenant/tenant'; import {uiFactory} from '../../uiFactory/uiFactory'; import {cn} from '../../utils/cn'; -import {DEVELOPER_UI_TITLE} from '../../utils/constants'; +import {DEVELOPER_UI_TITLE, MONITORING_UI_TITLE} from '../../utils/constants'; import {createDeveloperUIInternalPageHref} from '../../utils/developerUI/developerUI'; import {useTypedSelector} from '../../utils/hooks'; import { @@ -56,7 +56,7 @@ function Header() { const isMetaDatabasesAvailable = useDatabasesAvailable(); - const {title: clusterTitle} = useClusterBaseInfo(); + const {title: clusterTitle, monitoring} = useClusterBaseInfo(); const database = useDatabaseFromQuery(); @@ -93,6 +93,16 @@ function Header() { const {currentData: databaseData, isLoading: isDatabaseDataLoading} = tenantApi.useGetTenantInfoQuery(params); + const monitoringLinkUrl = + monitoring && uiFactory.getMonitoringLink && databaseData?.Name && databaseData?.Type + ? uiFactory.getMonitoringLink({ + monitoring, + clusterName, + dbName: databaseData.Name, + dbType: databaseData.Type, + }) + : null; + const breadcrumbItems = React.useMemo(() => { let options = { ...pageBreadcrumbsOptions, @@ -128,6 +138,15 @@ function Header() { } if (isDatabasePage && database) { + if (monitoringLinkUrl) { + elements.push( + , + ); + } + elements.push( + )} + {renderName()} - - {links.map(({title, url, icon}) => ( - - ))} - + {links.length > 0 && ( + + {links.map(({title, url, icon}) => ( + + ))} + + )} {!isServerless && } diff --git a/src/containers/Tenant/Diagnostics/TenantOverview/i18n/en.json b/src/containers/Tenant/Diagnostics/TenantOverview/i18n/en.json index 9ec4807cc0..c51694d47c 100644 --- a/src/containers/Tenant/Diagnostics/TenantOverview/i18n/en.json +++ b/src/containers/Tenant/Diagnostics/TenantOverview/i18n/en.json @@ -1,4 +1,5 @@ { + "action_open-monitoring": "Monitoring", "top-nodes.empty-data": "No such nodes", "title_top-nodes-load": "Top nodes by load", "title_top-nodes-pool": "Top nodes by pools usage", diff --git a/src/containers/Tenant/ObjectSummary/SchemaTree/SchemaTree.tsx b/src/containers/Tenant/ObjectSummary/SchemaTree/SchemaTree.tsx index c481f81516..d3331f0c61 100644 --- a/src/containers/Tenant/ObjectSummary/SchemaTree/SchemaTree.tsx +++ b/src/containers/Tenant/ObjectSummary/SchemaTree/SchemaTree.tsx @@ -14,6 +14,7 @@ import {selectIsDirty, selectUserInput} from '../../../../store/reducers/query/q import {schemaApi} from '../../../../store/reducers/schema/schema'; import {tableSchemaDataApi} from '../../../../store/reducers/tableSchemaData'; import type {EPathType, TEvDescribeSchemeResult} from '../../../../types/api/schema'; +import {uiFactory} from '../../../../uiFactory/uiFactory'; import {valueIsDefined} from '../../../../utils'; import {useTypedDispatch, useTypedSelector} from '../../../../utils/hooks'; import {getConfirmation} from '../../../../utils/hooks/withConfirmation/useChangeInputWithConfirmation'; @@ -144,6 +145,7 @@ export function SchemaTree(props: SchemaTreeProps) { getConnectToDBDialog, schemaData: actionsSchemaData, isSchemaDataLoading: isActionsDataFetching, + hasMonitoring: typeof uiFactory.renderMonitoring === 'function', }, databaseFullPath, database, diff --git a/src/containers/Tenant/i18n/en.json b/src/containers/Tenant/i18n/en.json index 371eb83583..07d30799a9 100644 --- a/src/containers/Tenant/i18n/en.json +++ b/src/containers/Tenant/i18n/en.json @@ -28,6 +28,7 @@ "actions.connectToDB": "Connect to DB", "actions.dropIndex": "Drop index", "actions.openPreview": "Open preview", + "actions.openMonitoring": "Monitoring", "actions.createTable": "Create table...", "actions.createExternalTable": "Create external table...", "actions.createTopic": "Create topic...", diff --git a/src/containers/Tenant/utils/schemaActions.tsx b/src/containers/Tenant/utils/schemaActions.tsx index 1ad121c38e..135b237092 100644 --- a/src/containers/Tenant/utils/schemaActions.tsx +++ b/src/containers/Tenant/utils/schemaActions.tsx @@ -1,12 +1,16 @@ -import {CirclePlus, Copy, PlugConnection} from '@gravity-ui/icons'; +import {CirclePlus, Copy, DisplayPulse, PlugConnection} from '@gravity-ui/icons'; import {Flex, Spin} from '@gravity-ui/uikit'; import copy from 'copy-to-clipboard'; import type {NavigationTreeNodeType} from 'ydb-ui-components'; import type {SnippetParams} from '../../../components/ConnectToDB/types'; import type {AppDispatch} from '../../../store'; -import {TENANT_PAGES_IDS, TENANT_QUERY_TABS_ID} from '../../../store/reducers/tenant/constants'; -import {setQueryTab, setTenantPage} from '../../../store/reducers/tenant/tenant'; +import { + TENANT_DIAGNOSTICS_TABS_IDS, + TENANT_PAGES_IDS, + TENANT_QUERY_TABS_ID, +} from '../../../store/reducers/tenant/constants'; +import {setDiagnosticsTab, setQueryTab, setTenantPage} from '../../../store/reducers/tenant/tenant'; import createToast from '../../../utils/createToast'; import {insertSnippetToEditor} from '../../../utils/monaco/insertSnippet'; import {transformPath} from '../ObjectSummary/transformPath'; @@ -48,6 +52,7 @@ interface ActionsAdditionalParams { getConnectToDBDialog?: (params: SnippetParams) => Promise; schemaData?: SchemaData[]; isSchemaDataLoading?: boolean; + hasMonitoring?: boolean; } interface BindActionParams { @@ -98,6 +103,11 @@ const bindActions = ( } : undefined, getConnectToDBDialog: () => getConnectToDBDialog?.({database: params.database}), + openMonitoring: () => { + dispatch(setTenantPage(TENANT_PAGES_IDS.diagnostics)); + dispatch(setDiagnosticsTab(TENANT_DIAGNOSTICS_TABS_IDS.monitoring)); + setActivePath(params.path); + }, createTable: inputQuery(createTableTemplate), createColumnTable: inputQuery(createColumnTableTemplate), createAsyncReplication: inputQuery(createAsyncReplicationTemplate), @@ -190,6 +200,11 @@ export const getActions = action: actions.getConnectToDBDialog, iconStart: , }; + const monitoringItem = { + text: i18n('actions.openMonitoring'), + action: actions.openMonitoring, + iconStart: , + }; const createEntitiesSet = [ {text: i18n('actions.createTable'), action: actions.createTable}, @@ -216,10 +231,14 @@ export const getActions = }, ], }; - const DB_SET: ActionsSet = [[copyItem, connectToDBItem], createEntitiesSet]; + let DB_SET: ActionsSet = [[copyItem, connectToDBItem], createEntitiesSet]; const DIR_SET: ActionsSet = [[copyItem], createEntitiesSet]; + if (additionalEffects.hasMonitoring) { + DB_SET = [[copyItem, connectToDBItem, monitoringItem], createEntitiesSet]; + } + if (actions.createDirectory) { const createDirectoryItem = { text: i18n('actions.createDirectory'), diff --git a/src/routes.ts b/src/routes.ts index b94f0a7874..99c31b707f 100644 --- a/src/routes.ts +++ b/src/routes.ts @@ -26,7 +26,7 @@ export const TABLET = 'tablet'; const routes = { clusters: `/${CLUSTERS}`, cluster: `/:environment?/${CLUSTER}/:activeTab?`, - tenant: `/:environment?/${TENANT}`, + tenant: `/${TENANT}`, node: `/:environment?/${NODE}/:id/:activeTab?`, pDisk: `/:environment?/${PDISK}`, vDisk: `/:environment?/${VDISK}`, diff --git a/src/utils/additionalProps.ts b/src/utils/additionalProps.ts index 71fc11edce..d55acac1db 100644 --- a/src/utils/additionalProps.ts +++ b/src/utils/additionalProps.ts @@ -6,6 +6,17 @@ import type {ETenantType} from '../types/api/tenant'; import monitoringIcon from '../assets/icons/monitoring.svg'; +export function getMonitoringLink( + additionalProps?: AdditionalTenantsProps, + name?: string, + type?: ETenantType, +): string | null { + if (!additionalProps?.getMonitoringLink) { + return null; + } + return additionalProps.getMonitoringLink(name, type); +} + export function getDatabaseLinks( additionalProps?: AdditionalTenantsProps, name?: string, @@ -36,3 +47,28 @@ export function getDatabaseLinks( return links; } + +export function getInfoTabLinks( + additionalProps?: AdditionalTenantsProps, + name?: string, + type?: ETenantType, +) { + if (!additionalProps) { + return []; + } + + const links: DatabaseLink[] = []; + + if (additionalProps.getLogsLink) { + const link = additionalProps.getLogsLink(name); + if (link) { + links.push({title: i18n('field_logs-link'), url: link, icon: FileText}); + } + } + + if (additionalProps.getLinks) { + links.push(...additionalProps.getLinks(name, type)); + } + + return links; +} diff --git a/src/utils/constants.ts b/src/utils/constants.ts index a41e27e201..24f5567db7 100644 --- a/src/utils/constants.ts +++ b/src/utils/constants.ts @@ -106,6 +106,7 @@ export const QUERY_TECHNICAL_MARK = '/*UI-QUERY-EXCLUDE*/'; // ==== Titles ==== export const DEVELOPER_UI_TITLE = 'Developer UI'; +export const MONITORING_UI_TITLE = 'Monitoring'; export const CLUSTER_DEFAULT_TITLE = 'Cluster'; export const TENANT_DEFAULT_TITLE = 'Database'; From ed3b31c474c74657be5ea1d93813db85c93a260a Mon Sep 17 00:00:00 2001 From: Anton Standrik Date: Sat, 1 Nov 2025 10:37:10 +0300 Subject: [PATCH 4/7] fix: remove rooignore --- .rooignore | 34 ---------------------------------- 1 file changed, 34 deletions(-) delete mode 100644 .rooignore diff --git a/.rooignore b/.rooignore deleted file mode 100644 index 55195ae5b8..0000000000 --- a/.rooignore +++ /dev/null @@ -1,34 +0,0 @@ -# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. - -# dependencies -/node_modules -/.pnp -.pnp.js - -# testing -/coverage -playwright-artifacts - -# production -/build -/dist -*.zip - -# misc -.idea -.DS_Store -.env.local -.env.development.local -.env.test.local -.env.production.local -.vscode -.cursor - -npm-debug.log* -yarn-debug.log* -yarn-error.log* - -.env - - -embedded-ui.tar.bz2 \ No newline at end of file From 5dcff7a057f8cea7476bfc1a440b787f9367e34e Mon Sep 17 00:00:00 2001 From: Anton Standrik Date: Sat, 1 Nov 2025 10:38:00 +0300 Subject: [PATCH 5/7] fix: review fix --- src/containers/Tenant/Diagnostics/DiagnosticsPages.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/containers/Tenant/Diagnostics/DiagnosticsPages.ts b/src/containers/Tenant/Diagnostics/DiagnosticsPages.ts index 925f725e9e..2768cb85f6 100644 --- a/src/containers/Tenant/Diagnostics/DiagnosticsPages.ts +++ b/src/containers/Tenant/Diagnostics/DiagnosticsPages.ts @@ -257,9 +257,7 @@ export const getPagesByType = ( const dbContext = isDatabaseEntityType(type) || options?.isTopLevel; const seeded = dbContext ? getDatabasePages(options?.databaseType) : base; - const result = applyFilters(seeded, type, options); - - return result; + return applyFilters(seeded, type, options); }; export const useDiagnosticsPageLinkGetter = () => { From 463aa0700b8feefcb9a77b1810a1edd0c8466b18 Mon Sep 17 00:00:00 2001 From: Anton Standrik Date: Sat, 1 Nov 2025 11:16:04 +0300 Subject: [PATCH 6/7] fix: review fixes --- .../Diagnostics/TenantOverview/TenantOverview.tsx | 2 +- src/routes.ts | 10 ++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/containers/Tenant/Diagnostics/TenantOverview/TenantOverview.tsx b/src/containers/Tenant/Diagnostics/TenantOverview/TenantOverview.tsx index 5d39449c37..c9601d46f6 100644 --- a/src/containers/Tenant/Diagnostics/TenantOverview/TenantOverview.tsx +++ b/src/containers/Tenant/Diagnostics/TenantOverview/TenantOverview.tsx @@ -200,7 +200,7 @@ export function TenantOverview({
-
{tenantType}
+ {tenantType} {monitoringTabAvailable && (