ydb-embedded-ui 5.0.0 → 5.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (147) hide show
  1. package/dist/components/BasicNodeViewer/BasicNodeViewer.d.ts +2 -2
  2. package/dist/components/BasicNodeViewer/BasicNodeViewer.js +1 -1
  3. package/dist/components/ComponentsProvider/ComponentsProvider.d.ts +4 -0
  4. package/dist/components/ComponentsProvider/componentsRegistry.d.ts +3 -0
  5. package/dist/components/ComponentsProvider/componentsRegistry.js +3 -1
  6. package/dist/components/EntityStatus/EntityStatus.scss +1 -1
  7. package/dist/components/ErrorBoundary/ErrorBoundary.d.ts +11 -1
  8. package/dist/components/ErrorBoundary/ErrorBoundary.js +11 -3
  9. package/dist/components/FullNodeViewer/FullNodeViewer.d.ts +2 -2
  10. package/dist/components/FullNodeViewer/FullNodeViewer.js +1 -1
  11. package/dist/components/LagImages/LagImages.js +2 -2
  12. package/dist/components/ProgressViewer/ProgressViewer.js +6 -5
  13. package/dist/components/ProgressViewer/ProgressViewer.scss +33 -17
  14. package/dist/components/TabletsOverall/TabletsOverall.js +6 -6
  15. package/dist/containers/App/App.js +2 -1
  16. package/dist/containers/App/Content.js +6 -12
  17. package/dist/containers/App/Providers.js +2 -1
  18. package/dist/containers/App/appSlots.d.ts +7 -7
  19. package/dist/containers/AppIcons/AppIcons.js +1 -1
  20. package/dist/containers/Cluster/Cluster.js +45 -27
  21. package/dist/containers/Cluster/Cluster.scss +15 -0
  22. package/dist/containers/Cluster/ClusterInfo/ClusterInfo.js +4 -18
  23. package/dist/containers/Cluster/ClusterInfo/ClusterInfo.scss +0 -40
  24. package/dist/containers/Cluster/utils.d.ts +6 -1
  25. package/dist/containers/Cluster/utils.js +11 -3
  26. package/dist/containers/ClusterModeGuard/ClusterModeGuard.d.ts +6 -0
  27. package/dist/containers/ClusterModeGuard/ClusterModeGuard.js +6 -0
  28. package/dist/containers/ClusterModeGuard/index.d.ts +1 -0
  29. package/dist/containers/ClusterModeGuard/index.js +1 -0
  30. package/dist/containers/Clusters/Clusters.js +4 -3
  31. package/dist/containers/Clusters/columns.js +1 -1
  32. package/dist/containers/Clusters/constants.d.ts +1 -1
  33. package/dist/containers/Clusters/i18n/en.json +2 -1
  34. package/dist/containers/Clusters/i18n/index.d.ts +1 -1
  35. package/dist/containers/Clusters/i18n/index.js +2 -4
  36. package/dist/containers/Clusters/i18n/ru.json +2 -1
  37. package/dist/containers/Node/Node.js +11 -13
  38. package/dist/containers/Node/NodePages.js +4 -1
  39. package/dist/containers/Node/i18n/index.d.ts +1 -1
  40. package/dist/containers/Node/i18n/index.js +2 -4
  41. package/dist/containers/Nodes/getNodesColumns.js +2 -1
  42. package/dist/containers/Storage/StorageGroups/getStorageGroupsColumns.d.ts +1 -1
  43. package/dist/containers/Storage/StorageNodes/getStorageNodesColumns.d.ts +1 -1
  44. package/dist/containers/Storage/StorageNodes/getStorageNodesColumns.js +2 -1
  45. package/dist/containers/Tablet/Tablet.js +24 -20
  46. package/dist/containers/Tablet/i18n/index.d.ts +1 -1
  47. package/dist/containers/Tablet/i18n/index.js +2 -4
  48. package/dist/containers/TabletsFilters/TabletsFilters.d.ts +2 -0
  49. package/dist/containers/TabletsFilters/TabletsFilters.js +25 -19
  50. package/dist/containers/TabletsFilters/i18n/en.json +3 -0
  51. package/dist/containers/TabletsFilters/i18n/index.d.ts +2 -0
  52. package/dist/containers/TabletsFilters/i18n/index.js +5 -0
  53. package/dist/containers/TabletsFilters/i18n/ru.json +3 -0
  54. package/dist/containers/Tenant/Diagnostics/Diagnostics.js +12 -11
  55. package/dist/containers/Tenant/Diagnostics/DiagnosticsPages.d.ts +19 -0
  56. package/dist/containers/Tenant/Diagnostics/DiagnosticsPages.js +2 -1
  57. package/dist/containers/Tenant/Diagnostics/HotKeys/HotKeys.d.ts +7 -25
  58. package/dist/containers/Tenant/Diagnostics/HotKeys/HotKeys.js +88 -92
  59. package/dist/containers/Tenant/Diagnostics/HotKeys/HotKeys.scss +1 -33
  60. package/dist/containers/Tenant/Diagnostics/HotKeys/i18n/en.json +4 -0
  61. package/dist/containers/Tenant/Diagnostics/HotKeys/i18n/index.d.ts +2 -0
  62. package/dist/containers/Tenant/Diagnostics/HotKeys/i18n/index.js +5 -0
  63. package/dist/containers/Tenant/Diagnostics/TenantOverview/MetricsCards/MetricCard/MetricCard.js +4 -1
  64. package/dist/containers/Tenant/Diagnostics/TenantOverview/MetricsCards/MetricsCards.js +3 -4
  65. package/dist/containers/Tenant/Diagnostics/TenantOverview/TenantOverview.js +12 -5
  66. package/dist/containers/Tenant/Diagnostics/TenantOverview/TenantStorage/TenantStorage.d.ts +2 -2
  67. package/dist/containers/Tenant/Diagnostics/TenantOverview/TenantStorage/TenantStorage.js +7 -10
  68. package/dist/containers/Tenant/Diagnostics/TenantOverview/i18n/en.json +7 -5
  69. package/dist/containers/Tenant/Diagnostics/TenantOverview/i18n/index.js +0 -2
  70. package/dist/containers/Tenant/Diagnostics/TopQueries/getTopQueriesColumns.js +10 -0
  71. package/dist/containers/Tenant/ObjectGeneral/ObjectGeneral.d.ts +1 -1
  72. package/dist/containers/Tenant/Query/Query.d.ts +2 -2
  73. package/dist/containers/Tenant/Query/Query.js +5 -2
  74. package/dist/containers/Tenant/Query/QueryEditor/QueryEditor.d.ts +29 -31
  75. package/dist/containers/Tenant/Query/QueryEditor/QueryEditor.js +150 -167
  76. package/dist/containers/Tenant/Query/QueryEditorControls/QueryEditorControls.d.ts +2 -2
  77. package/dist/containers/Tenant/Query/QueryEditorControls/QueryEditorControls.js +3 -3
  78. package/dist/containers/Tenant/Query/QueryTabs/QueryTabs.d.ts +10 -0
  79. package/dist/containers/Tenant/Query/QueryTabs/QueryTabs.js +1 -1
  80. package/dist/containers/Tenant/Query/utils/getPreparedResult.d.ts +1 -1
  81. package/dist/containers/Tenant/Query/utils/getPreparedResult.js +18 -16
  82. package/dist/containers/Tenant/Tenant.js +4 -1
  83. package/dist/containers/Tenant/i18n/en.json +1 -0
  84. package/dist/containers/Tenant/i18n/index.d.ts +1 -1
  85. package/dist/containers/Tenant/i18n/index.js +2 -4
  86. package/dist/containers/Tenant/i18n/ru.json +1 -0
  87. package/dist/containers/UserSettings/Setting.d.ts +2 -1
  88. package/dist/containers/UserSettings/Setting.js +2 -2
  89. package/dist/containers/UserSettings/i18n/en.json +2 -0
  90. package/dist/containers/UserSettings/i18n/index.d.ts +1 -1
  91. package/dist/containers/UserSettings/i18n/index.js +2 -6
  92. package/dist/containers/UserSettings/settings.d.ts +1 -0
  93. package/dist/containers/UserSettings/settings.js +9 -2
  94. package/dist/containers/Versions/NodesTreeTitle/NodesTreeTitle.scss +1 -1
  95. package/dist/lib.d.ts +2 -1
  96. package/dist/lib.js +2 -1
  97. package/dist/routes.d.ts +5 -0
  98. package/dist/routes.js +4 -0
  99. package/dist/services/api.d.ts +2 -1
  100. package/dist/services/api.js +10 -3
  101. package/dist/services/settings.d.ts +0 -1
  102. package/dist/services/settings.js +2 -14
  103. package/dist/store/index.d.ts +1 -1
  104. package/dist/store/reducers/cluster/cluster.d.ts +8 -2
  105. package/dist/store/reducers/cluster/cluster.js +29 -1
  106. package/dist/store/reducers/cluster/types.d.ts +4 -2
  107. package/dist/store/reducers/executeQuery.d.ts +1 -10
  108. package/dist/store/reducers/executeQuery.js +26 -29
  109. package/dist/store/reducers/executeTopQueries/executeTopQueries.js +2 -1
  110. package/dist/store/reducers/executeTopQueries/utils.js +7 -4
  111. package/dist/store/reducers/hotKeys/hotKeys.d.ts +25 -0
  112. package/dist/store/reducers/hotKeys/hotKeys.js +49 -0
  113. package/dist/store/reducers/hotKeys/types.d.ts +10 -0
  114. package/dist/store/reducers/hotKeys/types.js +1 -0
  115. package/dist/store/reducers/index.d.ts +2 -6
  116. package/dist/store/reducers/index.js +1 -1
  117. package/dist/store/reducers/node/node.d.ts +1 -1
  118. package/dist/store/reducers/node/node.js +2 -0
  119. package/dist/store/reducers/node/selectors.js +1 -1
  120. package/dist/store/reducers/node/types.d.ts +7 -3
  121. package/dist/store/reducers/node/utils.d.ts +3 -0
  122. package/dist/store/reducers/node/utils.js +8 -0
  123. package/dist/store/reducers/nodes/types.d.ts +1 -1
  124. package/dist/store/reducers/nodes/utils.js +3 -3
  125. package/dist/store/reducers/storage/types.d.ts +2 -0
  126. package/dist/store/reducers/storage/utils.js +3 -3
  127. package/dist/store/reducers/tenants/utils.d.ts +4 -3
  128. package/dist/store/reducers/tenants/utils.js +17 -12
  129. package/dist/store/reducers/tooltip.d.ts +1 -1
  130. package/dist/types/api/hotkeys.d.ts +7 -0
  131. package/dist/types/api/hotkeys.js +1 -0
  132. package/dist/types/api/nodes.d.ts +2 -1
  133. package/dist/types/store/executeQuery.d.ts +3 -6
  134. package/dist/types/store/explainQuery.d.ts +1 -0
  135. package/dist/utils/constants.d.ts +2 -1
  136. package/dist/utils/constants.js +2 -1
  137. package/dist/utils/diagnostics.d.ts +1 -0
  138. package/dist/utils/diagnostics.js +1 -0
  139. package/dist/utils/i18n/i18n.d.ts +2 -1
  140. package/dist/utils/i18n/i18n.js +15 -2
  141. package/dist/utils/monitoring.js +1 -3
  142. package/dist/utils/versions/getVersionsColors.js +1 -1
  143. package/package.json +9 -8
  144. package/dist/containers/Tenant/Diagnostics/TenantOverview/i18n/ru.json +0 -26
  145. package/dist/containers/UserSettings/i18n/ru.json +0 -20
  146. package/dist/store/reducers/hotKeys.d.ts +0 -11
  147. package/dist/store/reducers/hotKeys.js +0 -34
@@ -3,6 +3,7 @@ import { useEffect, useMemo, useRef } from 'react';
3
3
  import { useLocation, useRouteMatch } from 'react-router';
4
4
  import cn from 'bem-cn-lite';
5
5
  import { useDispatch } from 'react-redux';
6
+ import { Helmet } from 'react-helmet-async';
6
7
  import { Tabs } from '@gravity-ui/uikit';
7
8
  import { Link } from 'react-router-dom';
8
9
  import { TABLETS, STORAGE, NODE_PAGES, OVERVIEW, STRUCTURE } from './NodePages';
@@ -17,39 +18,36 @@ import routes, { createHref, parseQuery } from '../../routes';
17
18
  import { setHeaderBreadcrumbs } from '../../store/reducers/header/header';
18
19
  import { AutoFetcher } from '../../utils/autofetcher';
19
20
  import { useTypedSelector } from '../../utils/hooks';
20
- import { clusterTabsIds } from '../Cluster/utils';
21
21
  import './Node.scss';
22
22
  const b = cn('node');
23
23
  export const STORAGE_ROLE = 'Storage';
24
24
  const autofetcher = new AutoFetcher();
25
25
  function Node(props) {
26
- var _a, _b;
26
+ var _a;
27
27
  const container = useRef(null);
28
28
  const dispatch = useDispatch();
29
29
  const location = useLocation();
30
- const { loading, wasLoaded, error, data } = useTypedSelector((state) => state.node);
31
- const node = (_a = data === null || data === void 0 ? void 0 : data.SystemStateInfo) === null || _a === void 0 ? void 0 : _a[0];
32
- const match = (_b = useRouteMatch(routes.node)) !== null && _b !== void 0 ? _b : Object.create(null);
30
+ const { loading, wasLoaded, error, data: node } = useTypedSelector((state) => state.node);
31
+ const match = (_a = useRouteMatch(routes.node)) !== null && _a !== void 0 ? _a : Object.create(null);
33
32
  const { id: nodeId, activeTab } = match.params;
34
33
  const { tenantName: tenantNameFromQuery } = parseQuery(location);
35
34
  const { activeTabVerified, nodeTabs } = useMemo(() => {
36
35
  var _a;
37
36
  const hasStorage = (_a = node === null || node === void 0 ? void 0 : node.Roles) === null || _a === void 0 ? void 0 : _a.find((el) => el === STORAGE_ROLE);
38
- let actualActiveTab = activeTab;
39
- if (!hasStorage && activeTab === STORAGE) {
40
- actualActiveTab = OVERVIEW;
41
- }
42
37
  const nodePages = hasStorage ? NODE_PAGES : NODE_PAGES.filter((el) => el.id !== STORAGE);
43
38
  const actualNodeTabs = nodePages.map((page) => {
44
39
  return Object.assign(Object.assign({}, page), { title: page.name });
45
40
  });
41
+ let actualActiveTab = actualNodeTabs.find(({ id }) => id === activeTab);
42
+ if (!actualActiveTab) {
43
+ actualActiveTab = actualNodeTabs[0];
44
+ }
46
45
  return { activeTabVerified: actualActiveTab, nodeTabs: actualNodeTabs };
47
46
  }, [activeTab, node]);
48
47
  useEffect(() => {
49
48
  var _a;
50
49
  const tenantName = ((_a = node === null || node === void 0 ? void 0 : node.Tenants) === null || _a === void 0 ? void 0 : _a[0]) || (tenantNameFromQuery === null || tenantNameFromQuery === void 0 ? void 0 : tenantNameFromQuery.toString());
51
50
  dispatch(setHeaderBreadcrumbs('node', {
52
- clusterTab: clusterTabsIds.nodes,
53
51
  tenantName,
54
52
  nodeId,
55
53
  }));
@@ -65,10 +63,10 @@ function Node(props) {
65
63
  };
66
64
  }, [dispatch, nodeId]);
67
65
  const renderTabs = () => {
68
- return (_jsx("div", Object.assign({ className: b('tabs') }, { children: _jsx(Tabs, { size: "l", items: nodeTabs, activeTab: activeTabVerified, wrapTo: ({ id }, tabNode) => (_jsx(Link, Object.assign({ to: createHref(routes.node, { id: nodeId, activeTab: id }), className: b('tab') }, { children: tabNode }), id)), allowNotSelected: true }) })));
66
+ return (_jsx("div", Object.assign({ className: b('tabs') }, { children: _jsx(Tabs, { size: "l", items: nodeTabs, activeTab: activeTabVerified.id, wrapTo: ({ id }, tabNode) => (_jsx(Link, Object.assign({ to: createHref(routes.node, { id: nodeId, activeTab: id }), className: b('tab') }, { children: tabNode }), id)), allowNotSelected: true }) })));
69
67
  };
70
68
  const renderTabContent = () => {
71
- switch (activeTab) {
69
+ switch (activeTabVerified.id) {
72
70
  case STORAGE: {
73
71
  return (_jsx("div", Object.assign({ className: b('storage') }, { children: _jsx(StorageWrapper, { nodeId: nodeId, parentContainer: container.current }) })));
74
72
  }
@@ -93,7 +91,7 @@ function Node(props) {
93
91
  }
94
92
  else {
95
93
  if (node) {
96
- return (_jsxs("div", Object.assign({ className: b(null, props.className), ref: container }, { children: [_jsx(BasicNodeViewer, { node: node, additionalNodesProps: props.additionalNodesProps, className: b('header') }), renderTabs(), _jsx("div", Object.assign({ className: b('content') }, { children: renderTabContent() }))] })));
94
+ return (_jsxs("div", Object.assign({ className: b(null, props.className), ref: container }, { children: [_jsx(Helmet, Object.assign({ titleTemplate: `%s — ${node.Host} — YDB Monitoring`, defaultTitle: `${node.Host} — YDB Monitoring` }, { children: _jsx("title", { children: activeTabVerified.title }) })), _jsx(BasicNodeViewer, { node: node, additionalNodesProps: props.additionalNodesProps, className: b('header') }), renderTabs(), _jsx("div", Object.assign({ className: b('content') }, { children: renderTabContent() }))] })));
97
95
  }
98
96
  return _jsx("div", Object.assign({ className: "error" }, { children: "no node data" }));
99
97
  }
@@ -12,7 +12,10 @@ export const NODE_PAGES = [
12
12
  id: STORAGE,
13
13
  name: 'Storage',
14
14
  },
15
- { id: STRUCTURE, name: 'Structure' },
15
+ {
16
+ id: STRUCTURE,
17
+ name: 'Structure',
18
+ },
16
19
  {
17
20
  id: TABLETS,
18
21
  name: 'Tablets',
@@ -1,2 +1,2 @@
1
- declare const _default: (key: string, params?: import("@gravity-ui/i18n").Params | undefined) => string;
1
+ declare const _default: (key: "pdisk.developer-ui-button-title" | "vdisk.developer-ui-button-title", params?: import("@gravity-ui/i18n").Params | undefined) => string;
2
2
  export default _default;
@@ -1,7 +1,5 @@
1
- import { i18n, Lang } from '../../../utils/i18n';
1
+ import { registerKeysets } from '../../../utils/i18n';
2
2
  import en from './en.json';
3
3
  import ru from './ru.json';
4
4
  const COMPONENT = 'ydb-node-page';
5
- i18n.registerKeyset(Lang.En, COMPONENT, en);
6
- i18n.registerKeyset(Lang.Ru, COMPONENT, ru);
7
- export default i18n.keyset(COMPONENT);
5
+ export default registerKeysets(COMPONENT, { en, ru });
@@ -8,6 +8,7 @@ import { formatBytesToGigabyte, formatStorageValuesToGb, } from '../../utils/dat
8
8
  import { getLoadSeverityForNode } from '../../store/reducers/nodes/utils';
9
9
  import { UsageLabel } from '../../components/UsageLabel/UsageLabel';
10
10
  import { CellWithPopover } from '../../components/CellWithPopover/CellWithPopover';
11
+ import { EMPTY_DATA_PLACEHOLDER } from '../../utils/constants';
11
12
  const NODES_COLUMNS_IDS = {
12
13
  NodeId: 'NodeId',
13
14
  Host: 'Host',
@@ -49,7 +50,7 @@ const dataCenterColumn = {
49
50
  name: NODES_COLUMNS_IDS.DC,
50
51
  header: 'DC',
51
52
  align: DataTable.LEFT,
52
- render: ({ row }) => (row.DataCenter ? row.DataCenter : '—'),
53
+ render: ({ row }) => row.DC || EMPTY_DATA_PLACEHOLDER,
53
54
  width: 60,
54
55
  };
55
56
  const rackColumn = {
@@ -46,7 +46,7 @@ export declare const getPreparedStorageGroupsColumns: (nodesMap: NodesMap | unde
46
46
  index: number;
47
47
  footer?: boolean | undefined;
48
48
  headerData?: boolean | undefined;
49
- }, column: DataTableColumn<PreparedStorageGroup>) => void) | undefined;
49
+ }, column: DataTableColumn<PreparedStorageGroup>, event: import("react").MouseEvent<HTMLTableCellElement, MouseEvent>) => void) | undefined;
50
50
  defaultOrder?: import("@gravity-ui/react-data-table").OrderType | undefined;
51
51
  sortAccessor?: string | ((row: PreparedStorageGroup) => any) | undefined;
52
52
  sortAscending?: import("@gravity-ui/react-data-table").Comparator<PreparedStorageGroup> | undefined;
@@ -37,7 +37,7 @@ export declare const getPreparedStorageNodesColumns: (additionalNodesProps: Addi
37
37
  index: number;
38
38
  footer?: boolean | undefined;
39
39
  headerData?: boolean | undefined;
40
- }, column: DataTableColumn<PreparedStorageNode>) => void) | undefined;
40
+ }, column: DataTableColumn<PreparedStorageNode>, event: import("react").MouseEvent<HTMLTableCellElement, MouseEvent>) => void) | undefined;
41
41
  defaultOrder?: import("@gravity-ui/react-data-table").OrderType | undefined;
42
42
  sortAccessor?: string | ((row: PreparedStorageNode) => any) | undefined;
43
43
  sortAscending?: import("@gravity-ui/react-data-table").Comparator<PreparedStorageNode> | undefined;
@@ -3,6 +3,7 @@ import DataTable from '@gravity-ui/react-data-table';
3
3
  import { VISIBLE_ENTITIES } from '../../../store/reducers/storage/constants';
4
4
  import { NodeHostWrapper } from '../../../components/NodeHostWrapper/NodeHostWrapper';
5
5
  import { isSortableNodesProperty } from '../../../utils/nodes';
6
+ import { EMPTY_DATA_PLACEHOLDER } from '../../../utils/constants';
6
7
  import { PDisk } from '../PDisk/PDisk';
7
8
  import { b } from './shared';
8
9
  export const STORAGE_NODES_COLUMNS_IDS = {
@@ -37,7 +38,7 @@ const getStorageNodesColumns = (additionalNodesProps) => {
37
38
  name: STORAGE_NODES_COLUMNS_IDS.DC,
38
39
  header: 'DC',
39
40
  width: 100,
40
- render: ({ row }) => row.DataCenter || '—',
41
+ render: ({ row }) => row.DC || EMPTY_DATA_PLACEHOLDER,
41
42
  align: DataTable.LEFT,
42
43
  },
43
44
  {
@@ -1,14 +1,15 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import { useCallback, useEffect, useRef } from 'react';
3
3
  import { useLocation, useParams } from 'react-router';
4
4
  import { useDispatch } from 'react-redux';
5
5
  import cn from 'bem-cn-lite';
6
6
  import { Link as ExternalLink } from '@gravity-ui/uikit';
7
+ import { Helmet } from 'react-helmet-async';
7
8
  import { backend } from '../../store';
8
9
  import { getTablet, getTabletDescribe, clearTabletData } from '../../store/reducers/tablet';
9
10
  import { setHeaderBreadcrumbs } from '../../store/reducers/header/header';
10
11
  import { useAutofetcher, useTypedSelector } from '../../utils/hooks';
11
- import { DEVELOPER_UI_TITLE } from '../../utils/constants';
12
+ import { CLUSTER_DEFAULT_TITLE, DEVELOPER_UI_TITLE } from '../../utils/constants';
12
13
  import { parseQuery } from '../../routes';
13
14
  import EntityStatus from '../../components/EntityStatus/EntityStatus';
14
15
  import { ResponseError } from '../../components/Errors/ResponseError';
@@ -30,7 +31,7 @@ export const Tablet = () => {
30
31
  const params = useParams();
31
32
  const { id } = params;
32
33
  const { data: tablet = {}, loading, id: tabletId, history = [], tenantPath, error, } = useTypedSelector((state) => state.tablet);
33
- const { nodeId: queryNodeId, tenantName: queryTenantName, type: queryTabletType, } = parseQuery(location);
34
+ const { nodeId: queryNodeId, tenantName: queryTenantName, type: queryTabletType, clusterName: queryClusterName, } = parseQuery(location);
34
35
  const nodeId = ((_a = tablet.NodeId) === null || _a === void 0 ? void 0 : _a.toString()) || (queryNodeId === null || queryNodeId === void 0 ? void 0 : queryNodeId.toString());
35
36
  const tenantName = tenantPath || (queryTenantName === null || queryTenantName === void 0 ? void 0 : queryTenantName.toString());
36
37
  const type = tablet.Type || (queryTabletType === null || queryTabletType === void 0 ? void 0 : queryTabletType.toString());
@@ -61,21 +62,24 @@ export const Tablet = () => {
61
62
  const renderExternalLinks = (link, index) => {
62
63
  return (_jsx("li", Object.assign({ className: b('link', { external: true }) }, { children: _jsx(ExternalLink, Object.assign({ href: `${backend}${link.path}`, target: "_blank" }, { children: link.name })) }), index));
63
64
  };
64
- if (loading && id !== tabletId && isFirstDataFetchRef.current) {
65
- return _jsx(Loader, { size: "l" });
66
- }
67
- if (error) {
68
- return _jsx(ResponseError, { error: error });
69
- }
70
- if (!tablet || !Object.keys(tablet).length) {
71
- return (_jsx("div", Object.assign({ className: b('placeholder') }, { children: _jsx(EmptyState, { title: i18n('emptyState') }) })));
72
- }
73
- const { TabletId, Overall, Leader } = tablet;
74
- const externalLinks = [
75
- {
76
- name: `${DEVELOPER_UI_TITLE} - tablet`,
77
- path: `/tablets?TabletID=${TabletId}`,
78
- },
79
- ];
80
- return (_jsx("div", Object.assign({ className: b() }, { children: _jsxs("div", Object.assign({ className: b('pane-wrapper') }, { children: [_jsxs("div", Object.assign({ className: b('left-pane') }, { children: [_jsx("ul", Object.assign({ className: b('links') }, { children: externalLinks.map(renderExternalLinks) })), _jsxs("div", Object.assign({ className: b('row', { header: true }) }, { children: [_jsx("span", Object.assign({ className: b('title') }, { children: i18n('tablet.header') })), _jsx(EntityStatus, { status: Overall, name: TabletId }), _jsx("a", Object.assign({ rel: "noopener noreferrer", className: b('link', { external: true }), href: `${backend}/tablets?TabletID=${TabletId}`, target: "_blank" }, { children: _jsx(Icon, { name: "external" }) })), Leader && _jsx(Tag, { text: "Leader", type: "blue" }), _jsx("span", Object.assign({ className: b('loader') }, { children: loading && _jsx(Loader, { size: "s" }) }))] })), _jsx(TabletInfo, { tablet: tablet, tenantPath: tenantName }), _jsx(TabletControls, { tablet: tablet, fetchData: fetchData })] })), _jsx("div", Object.assign({ className: b('rigth-pane') }, { children: _jsx(TabletTable, { history: history }) }))] })) })));
65
+ const renderView = () => {
66
+ if (loading && id !== tabletId && isFirstDataFetchRef.current) {
67
+ return _jsx(Loader, { size: "l" });
68
+ }
69
+ if (error) {
70
+ return _jsx(ResponseError, { error: error });
71
+ }
72
+ if (!tablet || !Object.keys(tablet).length) {
73
+ return (_jsx("div", Object.assign({ className: b('placeholder') }, { children: _jsx(EmptyState, { title: i18n('emptyState') }) })));
74
+ }
75
+ const { TabletId, Overall, Leader } = tablet;
76
+ const externalLinks = [
77
+ {
78
+ name: `${DEVELOPER_UI_TITLE} - tablet`,
79
+ path: `/tablets?TabletID=${TabletId}`,
80
+ },
81
+ ];
82
+ return (_jsx("div", Object.assign({ className: b() }, { children: _jsxs("div", Object.assign({ className: b('pane-wrapper') }, { children: [_jsxs("div", Object.assign({ className: b('left-pane') }, { children: [_jsx("ul", Object.assign({ className: b('links') }, { children: externalLinks.map(renderExternalLinks) })), _jsxs("div", Object.assign({ className: b('row', { header: true }) }, { children: [_jsx("span", Object.assign({ className: b('title') }, { children: i18n('tablet.header') })), _jsx(EntityStatus, { status: Overall, name: TabletId }), _jsx("a", Object.assign({ rel: "noopener noreferrer", className: b('link', { external: true }), href: `${backend}/tablets?TabletID=${TabletId}`, target: "_blank" }, { children: _jsx(Icon, { name: "external" }) })), Leader && _jsx(Tag, { text: "Leader", type: "blue" }), _jsx("span", Object.assign({ className: b('loader') }, { children: loading && _jsx(Loader, { size: "s" }) }))] })), _jsx(TabletInfo, { tablet: tablet, tenantPath: tenantName }), _jsx(TabletControls, { tablet: tablet, fetchData: fetchData })] })), _jsx("div", Object.assign({ className: b('rigth-pane') }, { children: _jsx(TabletTable, { history: history }) }))] })) })));
83
+ };
84
+ return (_jsxs(_Fragment, { children: [_jsx(Helmet, { children: _jsx("title", { children: `${id} — ${i18n('tablet.header')} — ${tenantName || queryClusterName || CLUSTER_DEFAULT_TITLE}` }) }), renderView()] }));
81
85
  };
@@ -1,2 +1,2 @@
1
- declare const _default: (key: string, params?: import("@gravity-ui/i18n").Params | undefined) => string;
1
+ declare const _default: (key: "emptyState" | "tablet.header" | "controls.kill" | "controls.stop" | "controls.resume" | "dialog.kill" | "dialog.stop" | "dialog.resume", params?: import("@gravity-ui/i18n").Params | undefined) => string;
2
2
  export default _default;
@@ -1,7 +1,5 @@
1
- import { i18n, Lang } from '../../../utils/i18n';
1
+ import { registerKeysets } from '../../../utils/i18n';
2
2
  import en from './en.json';
3
3
  import ru from './ru.json';
4
4
  const COMPONENT = 'ydb-tablet-page';
5
- i18n.registerKeyset(Lang.En, COMPONENT, en);
6
- i18n.registerKeyset(Lang.Ru, COMPONENT, ru);
7
- export default i18n.keyset(COMPONENT);
5
+ export default registerKeysets(COMPONENT, { en, ru });
@@ -26,6 +26,7 @@ export class TabletsFilters extends React.Component<any, any, any> {
26
26
  state: {
27
27
  nodeFilter: never[];
28
28
  tenantPath: string;
29
+ clusterName: string;
29
30
  };
30
31
  reloadDescriptor: number;
31
32
  componentDidMount(): void;
@@ -38,6 +39,7 @@ export class TabletsFilters extends React.Component<any, any, any> {
38
39
  handleTypeFilterChange: (typeFilter: any) => void;
39
40
  renderTablet: (index: any, key: any) => JSX.Element;
40
41
  renderContent: () => JSX.Element;
42
+ renderView: () => JSX.Element;
41
43
  render(): JSX.Element;
42
44
  }
43
45
  declare var _default: import("react-redux").ConnectedComponent<typeof TabletsFilters, import("react-redux").Omit<PropTypes.InferProps<{
@@ -3,8 +3,8 @@ import React from 'react';
3
3
  import PropTypes from 'prop-types';
4
4
  import { connect } from 'react-redux';
5
5
  import cn from 'bem-cn-lite';
6
- import qs from 'qs';
7
6
  import _ from 'lodash';
7
+ import { Helmet } from 'react-helmet-async';
8
8
  import { Loader, Select } from '@gravity-ui/uikit';
9
9
  import ReactList from 'react-list';
10
10
  import { Tablet } from '../../components/Tablet';
@@ -12,6 +12,9 @@ import { AccessDenied } from '../../components/Errors/403';
12
12
  import { setHeaderBreadcrumbs } from '../../store/reducers/header/header';
13
13
  import { tabletColorToTabletState, tabletStates } from '../../utils/tablet';
14
14
  import { getTabletsInfo, clearWasLoadingFlag, setStateFilter, setTypeFilter, getFilteredTablets, getTablets, } from '../../store/reducers/tabletsFilters';
15
+ import { parseQuery } from '../../routes';
16
+ import { CLUSTER_DEFAULT_TITLE } from '../../utils/constants';
17
+ import i18n from './i18n';
15
18
  import './TabletsFilters.scss';
16
19
  const b = cn('tablets-filters');
17
20
  export class TabletsFilters extends React.Component {
@@ -20,6 +23,7 @@ export class TabletsFilters extends React.Component {
20
23
  this.state = {
21
24
  nodeFilter: [],
22
25
  tenantPath: '',
26
+ clusterName: '',
23
27
  };
24
28
  this.reloadDescriptor = -1;
25
29
  this.makeRequest = () => {
@@ -67,16 +71,29 @@ export class TabletsFilters extends React.Component {
67
71
  }));
68
72
  return (_jsxs("div", Object.assign({ className: b() }, { children: [tenantPath ? (_jsx("div", Object.assign({ className: b('tenant') }, { children: _jsxs(_Fragment, { children: [_jsx("span", Object.assign({ className: b('label') }, { children: "Database: " })), " ", tenantPath] }) }))) : null, _jsx(MemoizedFilters, { nodesForSelect: nodesForSelect, nodeFilter: nodeFilter, onChangeNodes: this.handleNodeFilterChange, states: states, stateFilter: stateFilter, onChangeStates: this.handleStateFilterChange, types: types, typeFilter: typeFilter, onChangeTypes: this.handleTypeFilterChange }), error && _jsx("div", Object.assign({ className: "error" }, { children: error })), filteredTablets.length > 0 ? (_jsx("div", Object.assign({ className: b('items') }, { children: _jsx(ReactList, { itemRenderer: this.renderTablet, length: filteredTablets.length, type: "uniform" }) }))) : (!error && _jsx("div", Object.assign({ className: b('empty-message') }, { children: "no tablets" })))] })));
69
73
  };
74
+ this.renderView = () => {
75
+ const { loading, wasLoaded, error } = this.props;
76
+ if (loading && !wasLoaded) {
77
+ return TabletsFilters.renderLoader();
78
+ }
79
+ else if (error && typeof error === 'object') {
80
+ if (error.status === 403) {
81
+ return _jsx(AccessDenied, {});
82
+ }
83
+ return _jsx("div", { children: error.statusText });
84
+ }
85
+ else {
86
+ return this.renderContent();
87
+ }
88
+ };
70
89
  }
71
90
  static renderLoader() {
72
91
  return (_jsx("div", Object.assign({ className: 'loader' }, { children: _jsx(Loader, { size: "l" }) })));
73
92
  }
74
93
  componentDidMount() {
75
94
  const { setStateFilter, setTypeFilter, setHeaderBreadcrumbs } = this.props;
76
- const queryParams = qs.parse(this.props.location.search, {
77
- ignoreQueryPrefix: true,
78
- });
79
- const { nodeIds, type, path, state } = queryParams;
95
+ const queryParams = parseQuery(this.props.location);
96
+ const { nodeIds, type, path, state, clusterName } = queryParams;
80
97
  const nodes = TabletsFilters.parseNodes(nodeIds);
81
98
  if (state) {
82
99
  const stateFilter = TabletsFilters.getStateFiltersFromColor(state);
@@ -85,7 +102,7 @@ export class TabletsFilters extends React.Component {
85
102
  if (type) {
86
103
  setTypeFilter([type]);
87
104
  }
88
- this.setState({ nodeFilter: nodes, tenantPath: path }, () => {
105
+ this.setState({ nodeFilter: nodes, tenantPath: path, clusterName }, () => {
89
106
  this.makeRequest();
90
107
  });
91
108
  setHeaderBreadcrumbs('tablets', {
@@ -106,19 +123,8 @@ export class TabletsFilters extends React.Component {
106
123
  clearInterval(this.reloadDescriptor);
107
124
  }
108
125
  render() {
109
- const { loading, wasLoaded, error } = this.props;
110
- if (loading && !wasLoaded) {
111
- return TabletsFilters.renderLoader();
112
- }
113
- else if (error && typeof error === 'object') {
114
- if (error.status === 403) {
115
- return _jsx(AccessDenied, {});
116
- }
117
- return _jsx("div", { children: error.statusText });
118
- }
119
- else {
120
- return this.renderContent();
121
- }
126
+ const { tenantPath, clusterName } = this.state;
127
+ return (_jsxs(_Fragment, { children: [_jsx(Helmet, { children: _jsx("title", { children: `${i18n('page.title')} — ${tenantPath || clusterName || CLUSTER_DEFAULT_TITLE}` }) }), this.renderView()] }));
122
128
  }
123
129
  }
124
130
  TabletsFilters.propTypes = {
@@ -0,0 +1,3 @@
1
+ {
2
+ "page.title": "Tablets"
3
+ }
@@ -0,0 +1,2 @@
1
+ declare const _default: (key: "page.title", params?: import("@gravity-ui/i18n").Params | undefined) => string;
2
+ export default _default;
@@ -0,0 +1,5 @@
1
+ import { registerKeysets } from '../../../utils/i18n';
2
+ import en from './en.json';
3
+ import ru from './ru.json';
4
+ const COMPONENT = 'ydb-tablets-filters-page';
5
+ export default registerKeysets(COMPONENT, { en, ru });
@@ -0,0 +1,3 @@
1
+ {
2
+ "page.title": "Таблетки"
3
+ }
@@ -5,6 +5,7 @@ import cn from 'bem-cn-lite';
5
5
  import { Link } from 'react-router-dom';
6
6
  import { useDispatch, useSelector } from 'react-redux';
7
7
  import { useLocation } from 'react-router';
8
+ import { Helmet } from 'react-helmet-async';
8
9
  import { Switch, Tabs } from '@gravity-ui/uikit';
9
10
  import { useTypedSelector } from '../../../utils/hooks';
10
11
  import routes, { createHref } from '../../../routes';
@@ -17,7 +18,7 @@ import { NodesWrapper } from '../../Nodes/NodesWrapper';
17
18
  import { StorageWrapper } from '../../Storage/StorageWrapper';
18
19
  import { Tablets } from '../../Tablets';
19
20
  import Describe from './Describe/Describe';
20
- import HotKeys from './HotKeys/HotKeys';
21
+ import { HotKeys } from './HotKeys/HotKeys';
21
22
  import Network from './Network/Network';
22
23
  import { Partitions } from './Partitions/Partitions';
23
24
  import { Consumers } from './Consumers';
@@ -52,14 +53,14 @@ function Diagnostics(props) {
52
53
  };
53
54
  const activeTab = useMemo(() => {
54
55
  if (wasLoaded) {
55
- if (pages.find((el) => el.id === diagnosticsTab)) {
56
- return diagnosticsTab;
56
+ let page = pages.find((el) => el.id === diagnosticsTab);
57
+ if (!page) {
58
+ page = pages[0];
57
59
  }
58
- else {
59
- const newPage = pages[0].id;
60
- forwardToDiagnosticTab(newPage);
61
- return newPage;
60
+ if (page && page.id !== diagnosticsTab) {
61
+ forwardToDiagnosticTab(page.id);
62
62
  }
63
+ return page;
63
64
  }
64
65
  return undefined;
65
66
  }, [pages, diagnosticsTab, wasLoaded]);
@@ -74,7 +75,7 @@ function Diagnostics(props) {
74
75
  const renderTabContent = () => {
75
76
  const { type } = props;
76
77
  const tenantNameString = tenantName;
77
- switch (diagnosticsTab) {
78
+ switch (activeTab === null || activeTab === void 0 ? void 0 : activeTab.id) {
78
79
  case TENANT_DIAGNOSTICS_TABS_IDS.overview: {
79
80
  return (_jsx(DetailedOverview, { type: type, tenantName: tenantNameString, additionalTenantProps: props.additionalTenantProps, additionalNodesProps: props.additionalNodesProps }));
80
81
  }
@@ -100,7 +101,7 @@ function Diagnostics(props) {
100
101
  return _jsx(Describe, { tenant: tenantNameString, type: type });
101
102
  }
102
103
  case TENANT_DIAGNOSTICS_TABS_IDS.hotKeys: {
103
- return _jsx(HotKeys, { type: type });
104
+ return _jsx(HotKeys, { path: currentSchemaPath });
104
105
  }
105
106
  case TENANT_DIAGNOSTICS_TABS_IDS.graph: {
106
107
  return _jsx(Heatmap, { path: currentSchemaPath });
@@ -117,7 +118,7 @@ function Diagnostics(props) {
117
118
  }
118
119
  };
119
120
  const renderTabs = () => {
120
- return (_jsx("div", Object.assign({ className: b('header-wrapper') }, { children: _jsxs("div", Object.assign({ className: b('tabs') }, { children: [_jsx(Tabs, { size: "l", items: pages, activeTab: activeTab, wrapTo: ({ id }, node) => {
121
+ return (_jsx("div", Object.assign({ className: b('header-wrapper') }, { children: _jsxs("div", Object.assign({ className: b('tabs') }, { children: [_jsx(Tabs, { size: "l", items: pages, activeTab: activeTab === null || activeTab === void 0 ? void 0 : activeTab.id, wrapTo: ({ id }, node) => {
121
122
  const path = createHref(routes.tenant, undefined, Object.assign(Object.assign({}, queryParams), { [TenantTabsGroups.diagnosticsTab]: id }));
122
123
  return (_jsx(Link, Object.assign({ to: path, className: b('tab') }, { children: node }), id));
123
124
  }, allowNotSelected: true }), _jsx(Switch, { checked: autorefresh, onUpdate: onAutorefreshToggle, content: "Autorefresh" })] })) })));
@@ -128,6 +129,6 @@ function Diagnostics(props) {
128
129
  if (!wasLoaded) {
129
130
  return _jsx(Loader, { size: "l" });
130
131
  }
131
- return (_jsxs("div", Object.assign({ className: b(), ref: container }, { children: [renderTabs(), _jsx("div", Object.assign({ className: b('page-wrapper') }, { children: renderTabContent() }))] })));
132
+ return (_jsxs("div", Object.assign({ className: b(), ref: container }, { children: [activeTab ? (_jsx(Helmet, { children: _jsx("title", { children: activeTab.title }) })) : null, renderTabs(), _jsx("div", Object.assign({ className: b('page-wrapper') }, { children: renderTabContent() }))] })));
132
133
  }
133
134
  export default Diagnostics;
@@ -51,6 +51,25 @@ export declare const TABLE_PAGES: ({
51
51
  id: "graph";
52
52
  title: string;
53
53
  })[];
54
+ export declare const COLUMN_TABLE_PAGES: ({
55
+ id: "overview";
56
+ title: string;
57
+ } | {
58
+ id: "topShards";
59
+ title: string;
60
+ } | {
61
+ id: "nodes";
62
+ title: string;
63
+ } | {
64
+ id: "tablets";
65
+ title: string;
66
+ } | {
67
+ id: "describe";
68
+ title: string;
69
+ } | {
70
+ id: "graph";
71
+ title: string;
72
+ })[];
54
73
  export declare const DIR_PAGES: ({
55
74
  id: "overview";
56
75
  title: string;
@@ -59,6 +59,7 @@ export const DATABASE_PAGES = [
59
59
  describe,
60
60
  ];
61
61
  export const TABLE_PAGES = [overview, topShards, nodes, graph, tablets, hotKeys, describe];
62
+ export const COLUMN_TABLE_PAGES = [overview, topShards, nodes, graph, tablets, describe];
62
63
  export const DIR_PAGES = [overview, topShards, nodes, describe];
63
64
  export const CDC_STREAM_PAGES = [overview, consumers, partitions, nodes, describe];
64
65
  export const TOPIC_PAGES = [overview, consumers, partitions, nodes, describe];
@@ -72,7 +73,7 @@ const pathTypeToPages = {
72
73
  [EPathType.EPathTypeExtSubDomain]: DATABASE_PAGES,
73
74
  [EPathType.EPathTypeColumnStore]: DATABASE_PAGES,
74
75
  [EPathType.EPathTypeTable]: TABLE_PAGES,
75
- [EPathType.EPathTypeColumnTable]: TABLE_PAGES,
76
+ [EPathType.EPathTypeColumnTable]: COLUMN_TABLE_PAGES,
76
77
  [EPathType.EPathTypeDir]: DIR_PAGES,
77
78
  [EPathType.EPathTypeTableIndex]: DIR_PAGES,
78
79
  [EPathType.EPathTypeCdcStream]: CDC_STREAM_PAGES,
@@ -1,25 +1,7 @@
1
- declare var _default: import("react-redux").ConnectedComponent<typeof HotKeys, import("react-redux").Omit<{
2
- getHotKeys: any;
3
- currentSchemaPath: any;
4
- loading: any;
5
- wasLoaded: any;
6
- error: any;
7
- data: any;
8
- autorefresh: any;
9
- setHotKeysOptions: any;
10
- currentSchema: any;
11
- type: any;
12
- }, "data" | "error" | "loading" | "wasLoaded" | "currentSchemaPath" | "autorefresh" | "currentSchema" | "getHotKeys" | "setHotKeysOptions">>;
13
- export default _default;
14
- declare function HotKeys({ getHotKeys, currentSchemaPath, loading, wasLoaded, error, data, autorefresh, setHotKeysOptions, currentSchema, type, }: {
15
- getHotKeys: any;
16
- currentSchemaPath: any;
17
- loading: any;
18
- wasLoaded: any;
19
- error: any;
20
- data: any;
21
- autorefresh: any;
22
- setHotKeysOptions: any;
23
- currentSchema: any;
24
- type: any;
25
- }): JSX.Element;
1
+ /// <reference types="react" />
2
+ import './HotKeys.scss';
3
+ interface HotKeysProps {
4
+ path: string;
5
+ }
6
+ export declare function HotKeys({ path }: HotKeysProps): JSX.Element;
7
+ export {};