Skip to content

Commit 195e92e

Browse files
committed
fix: open monitoring tab in new navigation
1 parent e4d9eae commit 195e92e

6 files changed

Lines changed: 125 additions & 38 deletions

File tree

src/containers/Tenant/Diagnostics/DiagnosticsPages.ts

Lines changed: 20 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,16 @@ import type {LabelProps} from '@gravity-ui/uikit';
44
import {useLocation} from 'react-router-dom';
55

66
import {getTenantPath, parseQuery} from '../../../routes';
7-
import {
8-
TENANT_DIAGNOSTICS_TABS_IDS,
9-
TENANT_PAGE,
10-
TENANT_PAGES_IDS,
11-
} from '../../../store/reducers/tenant/constants';
12-
import type {TenantDiagnosticsTab, TenantPage} from '../../../store/reducers/tenant/types';
7+
import {TENANT_DIAGNOSTICS_TABS_IDS, TENANT_PAGE} from '../../../store/reducers/tenant/constants';
8+
import type {TenantDiagnosticsTab} from '../../../store/reducers/tenant/types';
139
import {EPathSubType, EPathType} from '../../../types/api/schema';
1410
import type {ETenantType} from '../../../types/api/tenant';
1511
import type {TenantQuery} from '../TenantPages';
1612
import {TenantTabsGroups} from '../TenantPages';
13+
import {
14+
V2_DATABASE_PAGE_DIAGNOSTICS_TABS,
15+
getTenantPageForDiagnosticsTab,
16+
} from '../utils/diagnosticsNavigation';
1717
import {useNavigationV2Enabled} from '../utils/useNavigationV2Enabled';
1818

1919
import i18n from './i18n';
@@ -163,7 +163,18 @@ const ALL_DB_PAGES = [
163163
backups,
164164
];
165165

166-
const DB_PAGES = [database, monitoring, topQueries, storage, network, configs, operations, backups];
166+
const databasePageById = {
167+
[TENANT_DIAGNOSTICS_TABS_IDS.database]: database,
168+
[TENANT_DIAGNOSTICS_TABS_IDS.monitoring]: monitoring,
169+
[TENANT_DIAGNOSTICS_TABS_IDS.topQueries]: topQueries,
170+
[TENANT_DIAGNOSTICS_TABS_IDS.storage]: storage,
171+
[TENANT_DIAGNOSTICS_TABS_IDS.network]: network,
172+
[TENANT_DIAGNOSTICS_TABS_IDS.configs]: configs,
173+
[TENANT_DIAGNOSTICS_TABS_IDS.operations]: operations,
174+
[TENANT_DIAGNOSTICS_TABS_IDS.backups]: backups,
175+
} satisfies Record<(typeof V2_DATABASE_PAGE_DIAGNOSTICS_TABS)[number], Page>;
176+
177+
const DB_PAGES = V2_DATABASE_PAGE_DIAGNOSTICS_TABS.map((id) => databasePageById[id]);
167178

168179
const DIAGNOSTICS_DB_PAGES = [overview, topShards, nodes, tablets, describe, access];
169180

@@ -328,39 +339,13 @@ export const getPagesByType = (
328339
return applyFilters(seeded, options);
329340
};
330341

331-
// In tenant navigation v2 the database-overview tabs are split across two
332-
// top-level pages: the "stats"/management tabs (topQueries, storage, network,
333-
// monitoring, configs, operations, backups) live on `databasePage=database`,
334-
// while the rest (overview, topShards, nodes, tablets, describe, access) live
335-
// on `databasePage=diagnostics`. We have to route every "See all" link to the
336-
// correct top-level page, otherwise the target tab is missing from the active
337-
// page and Diagnostics silently falls back to its first tab. In v1 everything
338-
// lives under `databasePage=diagnostics`.
339-
//
340-
// Derive the set from the same DB_PAGES list used to render navigation, so the
341-
// two stay in sync automatically if pages are moved between sections later.
342-
// Serverless drops a few tabs from DB_PAGES (storage, network, nodes), but the
343-
// set is only used to *decide which top-level page hosts a tab*; missing tabs
344-
// just won't be rendered on either page, so we can safely use the regular-DB
345-
// arrays without branching on databaseType.
346-
const V2_DATABASE_PAGE_TABS = new Set<string>(DB_PAGES.map((page) => page.id));
347-
348-
function getTenantPageForTab(tab: string, isV2Enabled: boolean): TenantPage {
349-
if (!isV2Enabled) {
350-
return TENANT_PAGES_IDS.diagnostics;
351-
}
352-
return V2_DATABASE_PAGE_TABS.has(tab)
353-
? TENANT_PAGES_IDS.database
354-
: TENANT_PAGES_IDS.diagnostics;
355-
}
356-
357342
export const useDiagnosticsPageLinkGetter = () => {
358343
const location = useLocation();
359344
const queryParams = parseQuery(location);
360345
const isV2Enabled = useNavigationV2Enabled();
361346

362347
const getLink = React.useCallback(
363-
(tab: string, params?: TenantQuery) => {
348+
(tab: TenantDiagnosticsTab, params?: TenantQuery) => {
364349
return getTenantPath({
365350
...queryParams,
366351
...params,
@@ -371,7 +356,7 @@ export const useDiagnosticsPageLinkGetter = () => {
371356
// tab does not exist (and gets silently replaced by the first tab).
372357
// Spread after `params` so callers cannot accidentally override the
373358
// page/tab the helper is responsible for.
374-
[TENANT_PAGE]: getTenantPageForTab(tab, isV2Enabled),
359+
[TENANT_PAGE]: getTenantPageForDiagnosticsTab(tab, isV2Enabled),
375360
[TenantTabsGroups.diagnosticsTab]: tab,
376361
});
377362
},

src/containers/Tenant/Diagnostics/TenantOverview/TenantOverview.tsx

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ import {
1616
import {
1717
TENANT_DIAGNOSTICS_TABS_IDS,
1818
TENANT_METRICS_TABS_IDS,
19-
TENANT_PAGES_IDS,
2019
} from '../../../../store/reducers/tenant/constants';
2120
import {setDiagnosticsTab, tenantApi} from '../../../../store/reducers/tenant/tenant';
2221
import type {TenantMetricsTab} from '../../../../store/reducers/tenant/types';
@@ -34,6 +33,7 @@ import {useClusterNameFromQuery} from '../../../../utils/hooks/useDatabaseFromQu
3433
import {useDatabasesV2} from '../../../../utils/hooks/useDatabasesV2';
3534
import {canShowTenantMonitoringTab} from '../../../../utils/monitoringVisibility';
3635
import {useTenantPage} from '../../TenantNavigation/useTenantNavigation';
36+
import {getTenantPageForDiagnosticsTab} from '../../utils/diagnosticsNavigation';
3737
import {mapDatabaseTypeToDBName} from '../../utils/schema';
3838
import {useNavigationV2Enabled} from '../../utils/useNavigationV2Enabled';
3939

@@ -340,7 +340,12 @@ export function TenantOverview({
340340
);
341341

342342
const handleOpenMonitoring = () => {
343-
handleTenantPageChange(TENANT_PAGES_IDS.diagnostics);
343+
handleTenantPageChange(
344+
getTenantPageForDiagnosticsTab(
345+
TENANT_DIAGNOSTICS_TABS_IDS.monitoring,
346+
isV2NavigationEnabled,
347+
),
348+
);
344349
dispatch(setDiagnosticsTab(TENANT_DIAGNOSTICS_TABS_IDS.monitoring));
345350
};
346351

src/containers/Tenant/ObjectSummary/SchemaTree/SchemaTree.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ import {
4141
} from '../../utils/schema';
4242
import {getActions} from '../../utils/schemaActions';
4343
import type {DropdownItem, TreeNodeMeta} from '../../utils/types';
44+
import {useNavigationV2Enabled} from '../../utils/useNavigationV2Enabled';
4445
import {CreateDirectoryDialog} from '../CreateDirectoryDialog/CreateDirectoryDialog';
4546
import {useDispatchTreeKey, useTreeKey} from '../UpdateTreeContext';
4647
import {isDomain, transformPath} from '../transformPath';
@@ -78,6 +79,7 @@ export function SchemaTree(props: SchemaTreeProps) {
7879
const isTopicPreviewAvailable = useTopicDataAvailable();
7980

8081
const {handleTenantPageChange} = useTenantPage();
82+
const isV2NavigationEnabled = useNavigationV2Enabled();
8183

8284
const [createDirectoryOpen, setCreateDirectoryOpen] = React.useState(false);
8385
const [parentPath, setParentPath] = React.useState('');
@@ -222,6 +224,7 @@ export function SchemaTree(props: SchemaTreeProps) {
222224
schemaData: actionsSchemaData,
223225
isSchemaDataLoading: isActionsDataFetching,
224226
hasMonitoring,
227+
isV2NavigationEnabled,
225228
streamingQueryData: streamingSysData,
226229
showCreateTableData: getStringifiedData(showCreateTableData),
227230
isShowCreateTableLoading: isShowCreateTableFetching,
@@ -242,6 +245,7 @@ export function SchemaTree(props: SchemaTreeProps) {
242245
isMultiTabEnabled,
243246
actionsSchemaData,
244247
isActionsDataFetching,
248+
isV2NavigationEnabled,
245249
streamingSysData,
246250
showCreateTableData,
247251
isShowCreateTableFetching,
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import {
2+
TENANT_DIAGNOSTICS_TABS_IDS,
3+
TENANT_PAGES_IDS,
4+
} from '../../../store/reducers/tenant/constants';
5+
import type {TenantDiagnosticsTab, TenantPage} from '../../../store/reducers/tenant/types';
6+
7+
// In tenant navigation v2 database diagnostics tabs are split between two top-level pages.
8+
// Route each tab to the page that renders it; otherwise Diagnostics falls back to the
9+
// first available tab and actions like "Monitoring" appear to do nothing.
10+
// These tabs live under databasePage=database; the rest stay under databasePage=diagnostics.
11+
export const V2_DATABASE_PAGE_DIAGNOSTICS_TABS = [
12+
TENANT_DIAGNOSTICS_TABS_IDS.database,
13+
TENANT_DIAGNOSTICS_TABS_IDS.monitoring,
14+
TENANT_DIAGNOSTICS_TABS_IDS.topQueries,
15+
TENANT_DIAGNOSTICS_TABS_IDS.storage,
16+
TENANT_DIAGNOSTICS_TABS_IDS.network,
17+
TENANT_DIAGNOSTICS_TABS_IDS.configs,
18+
TENANT_DIAGNOSTICS_TABS_IDS.operations,
19+
TENANT_DIAGNOSTICS_TABS_IDS.backups,
20+
] as const satisfies readonly TenantDiagnosticsTab[];
21+
22+
const V2_DATABASE_PAGE_TABS = new Set<TenantDiagnosticsTab>(V2_DATABASE_PAGE_DIAGNOSTICS_TABS);
23+
24+
export function getTenantPageForDiagnosticsTab(
25+
tab: TenantDiagnosticsTab,
26+
isV2Enabled: boolean,
27+
): TenantPage {
28+
if (!isV2Enabled) {
29+
return TENANT_PAGES_IDS.diagnostics;
30+
}
31+
return V2_DATABASE_PAGE_TABS.has(tab)
32+
? TENANT_PAGES_IDS.database
33+
: TENANT_PAGES_IDS.diagnostics;
34+
}

src/containers/Tenant/utils/schemaActions.tsx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import {transformPath} from '../ObjectSummary/transformPath';
2121
import type {SchemaData} from '../Schema/SchemaViewer/types';
2222
import i18n from '../i18n';
2323

24+
import {getTenantPageForDiagnosticsTab} from './diagnosticsNavigation';
2425
import type {TemplateFn} from './schemaQueryTemplates';
2526
import {
2627
addFulltextIndex,
@@ -80,6 +81,7 @@ interface ActionsAdditionalParams {
8081
schemaData?: SchemaData[];
8182
isSchemaDataLoading?: boolean;
8283
hasMonitoring?: boolean;
84+
isV2NavigationEnabled?: boolean;
8385
streamingQueryData?: IQueryResult;
8486
showCreateTableData?: string;
8587
isStreamingQueryTextLoading?: boolean;
@@ -161,7 +163,12 @@ const bindActions = (
161163
showCompactionDialog?.(params.path);
162164
},
163165
openMonitoring: () => {
164-
setTenantPage(TENANT_PAGES_IDS.diagnostics);
166+
setTenantPage(
167+
getTenantPageForDiagnosticsTab(
168+
TENANT_DIAGNOSTICS_TABS_IDS.monitoring,
169+
Boolean(additionalEffects.isV2NavigationEnabled),
170+
),
171+
);
165172
dispatch(setDiagnosticsTab(TENANT_DIAGNOSTICS_TABS_IDS.monitoring));
166173
setActivePath(params.path);
167174
},

tests/suites/tenant/summary/objectSummary.test.ts

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
dsVslotsSchema,
1010
dsVslotsTableName,
1111
} from '../../../utils/constants';
12+
import {setupMonitoringGenericErrorMock} from '../../errorDisplay/errorDisplayMocks';
1213
import {TenantPage} from '../TenantPage';
1314
import {QueryEditor} from '../queryEditor/models/QueryEditor';
1415

@@ -191,6 +192,57 @@ test.describe('Object Summary', async () => {
191192
expect(clipboardContent).toBe('.sys/ds_vslots');
192193
});
193194

195+
test('Monitoring action opens monitoring tab with new navigation', async ({page}) => {
196+
await page.addInitScript(() => {
197+
localStorage.setItem('enableTenantNavigationV2', JSON.stringify(true));
198+
localStorage.setItem('isV2NavigationAlertSeen', JSON.stringify(true));
199+
});
200+
await page.route(`${backend}/viewer/json/whoami*`, async (route) => {
201+
await route.fulfill({
202+
status: 200,
203+
contentType: 'application/json',
204+
body: JSON.stringify({
205+
UserSID: 'test-user',
206+
UserID: 'test-user-id',
207+
AuthType: 'Login',
208+
IsViewerAllowed: true,
209+
IsMonitoringAllowed: true,
210+
}),
211+
});
212+
});
213+
await page.route(`${backend}/viewer/capabilities*`, async (route) => {
214+
await route.fulfill({
215+
status: 200,
216+
contentType: 'application/json',
217+
body: JSON.stringify({
218+
Database: database,
219+
Capabilities: {},
220+
}),
221+
});
222+
});
223+
await setupMonitoringGenericErrorMock(page);
224+
225+
const tenantPage = new TenantPage(page);
226+
await tenantPage.goto({
227+
schema: database,
228+
database,
229+
databasePage: 'query',
230+
});
231+
232+
const objectSummary = new ObjectSummary(page);
233+
await objectSummary.clickActionMenuItem('local', 'Monitoring');
234+
235+
await tenantPage.isDiagnosticsVisible();
236+
237+
await expect
238+
.poll(() => new URL(page.url()).searchParams.get('databasePage'))
239+
.toBe('database');
240+
await expect
241+
.poll(() => new URL(page.url()).searchParams.get('diagnosticsTab'))
242+
.toBe('monitoring');
243+
await expect(page.locator('a[data-tab="monitoring"]')).toBeVisible();
244+
});
245+
194246
test('Create directory in local node', async ({page}) => {
195247
const pageQueryParams = {
196248
schema: database,

0 commit comments

Comments
 (0)