ydb-embedded-ui 21.1.0 → 22.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/ComponentsProvider/ComponentsProvider.d.ts +0 -4
- package/dist/components/ComponentsProvider/componentsRegistry.d.ts +0 -2
- package/dist/components/ComponentsProvider/componentsRegistry.js +1 -3
- package/dist/components/ComponentsProvider/componentsRegistry.js.map +1 -1
- package/dist/components/ContentWithPopup/ContentWithPopup.d.ts +1 -1
- package/dist/components/ContentWithPopup/ContentWithPopup.js +4 -2
- package/dist/components/ContentWithPopup/ContentWithPopup.js.map +1 -1
- package/dist/components/FullNodeViewer/i18n/index.d.ts +1 -1
- package/dist/components/HoverPopup/HoverPopup.js +27 -4
- package/dist/components/HoverPopup/HoverPopup.js.map +1 -1
- package/dist/components/HoverPopup/getPopupScrollContainer.d.ts +1 -0
- package/dist/components/HoverPopup/getPopupScrollContainer.js +20 -0
- package/dist/components/HoverPopup/getPopupScrollContainer.js.map +1 -0
- package/dist/components/MetricChart/reducer.d.ts +2 -2
- package/dist/components/SegmentedProgress/SegmentedProgress.d.ts +22 -1
- package/dist/components/SegmentedProgress/SegmentedProgress.js +44 -3
- package/dist/components/SegmentedProgress/SegmentedProgress.js.map +1 -1
- package/dist/components/SegmentedProgress/SegmentedProgress.scss +5 -0
- package/dist/components/StorageGroupInfo/StorageGroupInfo.js +1 -13
- package/dist/components/StorageGroupInfo/StorageGroupInfo.js.map +1 -1
- package/dist/components/StorageGroupInfo/i18n/en.json +0 -1
- package/dist/components/StorageGroupInfo/i18n/index.d.ts +1 -1
- package/dist/components/nodesColumns/i18n/index.d.ts +1 -1
- package/dist/containers/App/App.js +3 -3
- package/dist/containers/App/App.js.map +1 -1
- package/dist/containers/Cluster/ClusterInfo/ClusterInfo.js +8 -5
- package/dist/containers/Cluster/ClusterInfo/ClusterInfo.js.map +1 -1
- package/dist/containers/Cluster/ClusterInfo/ClusterInfo.scss +8 -0
- package/dist/containers/Cluster/ClusterInfo/components/DiskGroupsStatsBars/DiskGroupsStats.d.ts +4 -3
- package/dist/containers/Cluster/ClusterInfo/components/DiskGroupsStatsBars/DiskGroupsStats.js +62 -25
- package/dist/containers/Cluster/ClusterInfo/components/DiskGroupsStatsBars/DiskGroupsStats.js.map +1 -1
- package/dist/containers/Cluster/ClusterInfo/components/DiskGroupsStatsBars/DiskGroupsStats.scss +18 -0
- package/dist/containers/Cluster/ClusterInfo/components/DiskGroupsStatsBars/utils.d.ts +22 -0
- package/dist/containers/Cluster/ClusterInfo/components/DiskGroupsStatsBars/utils.js +49 -0
- package/dist/containers/Cluster/ClusterInfo/components/DiskGroupsStatsBars/utils.js.map +1 -0
- package/dist/containers/Cluster/i18n/en.json +13 -4
- package/dist/containers/Cluster/i18n/index.d.ts +1 -1
- package/dist/containers/Node/Node.js +20 -17
- package/dist/containers/Node/Node.js.map +1 -1
- package/dist/containers/Node/NodePages.d.ts +3 -9
- package/dist/containers/Node/NodePages.js +2 -10
- package/dist/containers/Node/NodePages.js.map +1 -1
- package/dist/containers/Node/i18n/en.json +0 -3
- package/dist/containers/Node/i18n/index.d.ts +1 -1
- package/dist/containers/Nodes/NodesTable.js +2 -2
- package/dist/containers/Nodes/NodesTable.js.map +1 -1
- package/dist/containers/Storage/PaginatedStorageGroups/GroupedStorageGroupsComponent.js +0 -1
- package/dist/containers/Storage/PaginatedStorageGroups/GroupedStorageGroupsComponent.js.map +1 -1
- package/dist/containers/Storage/PaginatedStorageGroupsTable/PaginatedStorageGroupsTable.js +2 -3
- package/dist/containers/Storage/PaginatedStorageGroupsTable/PaginatedStorageGroupsTable.js.map +1 -1
- package/dist/containers/Storage/PaginatedStorageGroupsTable/columns/constants.d.ts +2 -2
- package/dist/containers/Storage/PaginatedStorageGroupsTable/getGroups.d.ts +1 -1
- package/dist/containers/Storage/PaginatedStorageGroupsTable/getGroups.js +2 -3
- package/dist/containers/Storage/PaginatedStorageGroupsTable/getGroups.js.map +1 -1
- package/dist/containers/StorageGroupPage/StorageGroupPage.js +2 -3
- package/dist/containers/StorageGroupPage/StorageGroupPage.js.map +1 -1
- package/dist/containers/Tenant/Diagnostics/Partitions/utils/constants.d.ts +2 -2
- package/dist/containers/Tenant/Diagnostics/TenantOverview/TenantStorage/TopGroups.js +1 -3
- package/dist/containers/Tenant/Diagnostics/TenantOverview/TenantStorage/TopGroups.js.map +1 -1
- package/dist/containers/Tenant/Diagnostics/TenantOverview/TenantStorage/useTenantStorageNewData.d.ts +5 -5
- package/dist/containers/Tenant/Diagnostics/useDiagnosticsPages.js +2 -4
- package/dist/containers/Tenant/Diagnostics/useDiagnosticsPages.js.map +1 -1
- package/dist/routes.d.ts +1 -0
- package/dist/routes.js.map +1 -1
- package/dist/services/api/viewer.d.ts +1 -2
- package/dist/services/api/viewer.js +0 -11
- package/dist/services/api/viewer.js.map +1 -1
- package/dist/store/configureStore.d.ts +12 -12
- package/dist/store/defaultStore.d.ts +6 -6
- package/dist/store/reducers/api.d.ts +1 -1
- package/dist/store/reducers/api.js +3 -0
- package/dist/store/reducers/api.js.map +1 -1
- package/dist/store/reducers/authentication/authentication.d.ts +4 -4
- package/dist/store/reducers/cancelQuery.d.ts +2 -2
- package/dist/store/reducers/capabilities/capabilities.d.ts +43 -43
- package/dist/store/reducers/capabilities/hooks.d.ts +5 -6
- package/dist/store/reducers/capabilities/hooks.js +0 -3
- package/dist/store/reducers/capabilities/hooks.js.map +1 -1
- package/dist/store/reducers/cluster/cluster.d.ts +5 -5
- package/dist/store/reducers/cluster/cluster.js +3 -2
- package/dist/store/reducers/cluster/cluster.js.map +1 -1
- package/dist/store/reducers/clusters/clusters.d.ts +2 -2
- package/dist/store/reducers/clusters/clusters.js +2 -1
- package/dist/store/reducers/clusters/clusters.js.map +1 -1
- package/dist/store/reducers/codeAssist/codeAssist.d.ts +6 -6
- package/dist/store/reducers/configs.d.ts +3 -3
- package/dist/store/reducers/entityDataTags.d.ts +21 -0
- package/dist/store/reducers/entityDataTags.js +24 -0
- package/dist/store/reducers/entityDataTags.js.map +1 -0
- package/dist/store/reducers/environments/environments.d.ts +2 -2
- package/dist/store/reducers/executeTopQueries/executeTopQueries.d.ts +4 -4
- package/dist/store/reducers/healthcheckInfo/healthcheckInfo.d.ts +111 -111
- package/dist/store/reducers/heatmap.d.ts +2 -2
- package/dist/store/reducers/hotKeys/hotKeys.d.ts +2 -2
- package/dist/store/reducers/index.d.ts +8 -8
- package/dist/store/reducers/network/network.d.ts +2 -2
- package/dist/store/reducers/node/node.d.ts +2 -5
- package/dist/store/reducers/node/node.js +0 -12
- package/dist/store/reducers/node/node.js.map +1 -1
- package/dist/store/reducers/node/types.d.ts +0 -14
- package/dist/store/reducers/nodes/nodes.d.ts +2 -2
- package/dist/store/reducers/nodesList.d.ts +12 -12
- package/dist/store/reducers/operations.d.ts +5 -5
- package/dist/store/reducers/overview/overview.d.ts +2 -2
- package/dist/store/reducers/partitions/partitions.d.ts +3 -3
- package/dist/store/reducers/pdisk/pdisk.d.ts +2 -2
- package/dist/store/reducers/planToSvg.d.ts +2 -2
- package/dist/store/reducers/preview.d.ts +2 -2
- package/dist/store/reducers/query/api.d.ts +4 -4
- package/dist/store/reducers/replication.d.ts +2 -2
- package/dist/store/reducers/schema/schema.d.ts +16 -16
- package/dist/store/reducers/schemaAcl/schemaAcl.d.ts +40 -40
- package/dist/store/reducers/settings/api.d.ts +4 -4
- package/dist/store/reducers/settings/settings.d.ts +1 -1
- package/dist/store/reducers/shardsWorkload/shardsWorkload.d.ts +2 -2
- package/dist/store/reducers/showCreateTable/showCreateTable.d.ts +2 -2
- package/dist/store/reducers/storage/requestStorageData.d.ts +2 -4
- package/dist/store/reducers/storage/requestStorageData.js +4 -10
- package/dist/store/reducers/storage/requestStorageData.js.map +1 -1
- package/dist/store/reducers/storage/storage.d.ts +4 -6
- package/dist/store/reducers/storage/storage.js.map +1 -1
- package/dist/store/reducers/storage/types.d.ts +0 -9
- package/dist/store/reducers/storage/utils.d.ts +1 -2
- package/dist/store/reducers/storage/utils.js +0 -111
- package/dist/store/reducers/storage/utils.js.map +1 -1
- package/dist/store/reducers/storageUsage/StorageUsage.d.ts +2 -2
- package/dist/store/reducers/streamingQuery/streamingQuery.d.ts +2 -2
- package/dist/store/reducers/table/table.d.ts +4 -4
- package/dist/store/reducers/tableData.d.ts +1 -1
- package/dist/store/reducers/tablePartitioning/tablePartitioning.d.ts +2 -2
- package/dist/store/reducers/tableSchemaData.d.ts +2 -2
- package/dist/store/reducers/tablet.d.ts +8 -8
- package/dist/store/reducers/tablets.d.ts +3 -3
- package/dist/store/reducers/tenant/tenant.d.ts +2 -2
- package/dist/store/reducers/tenant/tenant.js +14 -1
- package/dist/store/reducers/tenant/tenant.js.map +1 -1
- package/dist/store/reducers/tenantOverview/executeTopTables/executeTopTables.d.ts +2 -2
- package/dist/store/reducers/tenantOverview/storage/tenantOverviewStorage.d.ts +2 -2
- package/dist/store/reducers/tenantOverview/topShards/tenantOverviewTopShards.d.ts +2 -2
- package/dist/store/reducers/tenants/tenants.d.ts +3 -3
- package/dist/store/reducers/tenants/tenants.js +2 -1
- package/dist/store/reducers/tenants/tenants.js.map +1 -1
- package/dist/store/reducers/topic/topic.d.ts +84 -84
- package/dist/store/reducers/vdisk/vdisk.d.ts +3 -3
- package/dist/store/reducers/viewSchema/viewSchema.d.ts +2 -2
- package/dist/store/state-url-mapping.js +5 -1
- package/dist/store/state-url-mapping.js.map +1 -1
- package/dist/types/api/storage.d.ts +2 -111
- package/dist/types/api/storage.js.map +1 -1
- package/dist/uiFactory/types.d.ts +2 -0
- package/dist/utils/hooks/useWhoami.d.ts +5 -5
- package/package.json +1 -1
- package/src/components/ComponentsProvider/componentsRegistry.ts +1 -4
- package/src/components/ContentWithPopup/ContentWithPopup.tsx +7 -0
- package/src/components/HoverPopup/HoverPopup.tsx +32 -3
- package/src/components/HoverPopup/getPopupScrollContainer.ts +20 -0
- package/src/components/SegmentedProgress/SegmentedProgress.scss +5 -0
- package/src/components/SegmentedProgress/SegmentedProgress.tsx +99 -10
- package/src/components/StorageGroupInfo/StorageGroupInfo.tsx +0 -13
- package/src/components/StorageGroupInfo/i18n/en.json +0 -1
- package/src/containers/App/App.tsx +3 -3
- package/src/containers/Cluster/ClusterInfo/ClusterInfo.scss +8 -0
- package/src/containers/Cluster/ClusterInfo/ClusterInfo.tsx +12 -11
- package/src/containers/Cluster/ClusterInfo/components/DiskGroupsStatsBars/DiskGroupsStats.scss +18 -0
- package/src/containers/Cluster/ClusterInfo/components/DiskGroupsStatsBars/DiskGroupsStats.tsx +143 -58
- package/src/containers/Cluster/ClusterInfo/components/DiskGroupsStatsBars/utils.ts +89 -0
- package/src/containers/Cluster/i18n/en.json +13 -4
- package/src/containers/Node/Node.tsx +32 -18
- package/src/containers/Node/NodePages.ts +5 -10
- package/src/containers/Node/i18n/en.json +0 -4
- package/src/containers/Nodes/NodesTable.tsx +7 -1
- package/src/containers/Storage/PaginatedStorageGroups/GroupedStorageGroupsComponent.tsx +0 -1
- package/src/containers/Storage/PaginatedStorageGroupsTable/PaginatedStorageGroupsTable.tsx +2 -6
- package/src/containers/Storage/PaginatedStorageGroupsTable/columns/constants.ts +2 -2
- package/src/containers/Storage/PaginatedStorageGroupsTable/getGroups.ts +40 -47
- package/src/containers/StorageGroupPage/StorageGroupPage.tsx +2 -6
- package/src/containers/Tenant/Diagnostics/TenantOverview/TenantStorage/TopGroups.tsx +1 -6
- package/src/containers/Tenant/Diagnostics/useDiagnosticsPages.ts +1 -4
- package/src/routes.ts +1 -1
- package/src/services/api/viewer.ts +1 -25
- package/src/store/reducers/api.ts +4 -0
- package/src/store/reducers/capabilities/hooks.ts +0 -4
- package/src/store/reducers/cluster/cluster.ts +3 -2
- package/src/store/reducers/clusters/clusters.ts +2 -1
- package/src/store/reducers/entityDataTags.ts +34 -0
- package/src/store/reducers/node/node.ts +0 -11
- package/src/store/reducers/node/types.ts +0 -18
- package/src/store/reducers/storage/requestStorageData.ts +5 -17
- package/src/store/reducers/storage/storage.ts +2 -6
- package/src/store/reducers/storage/types.ts +0 -9
- package/src/store/reducers/storage/utils.ts +2 -175
- package/src/store/reducers/tenant/tenant.ts +17 -1
- package/src/store/reducers/tenants/tenants.ts +2 -1
- package/src/store/state-url-mapping.ts +5 -1
- package/src/types/api/storage.ts +7 -131
- package/src/uiFactory/types.ts +3 -0
- package/dist/containers/Node/NodeStructure/NodeStructure.d.ts +0 -7
- package/dist/containers/Node/NodeStructure/NodeStructure.js +0 -76
- package/dist/containers/Node/NodeStructure/NodeStructure.js.map +0 -1
- package/dist/containers/Node/NodeStructure/NodeStructure.scss +0 -155
- package/dist/containers/Node/NodeStructure/PDiskTitleBadge.d.ts +0 -7
- package/dist/containers/Node/NodeStructure/PDiskTitleBadge.js +0 -7
- package/dist/containers/Node/NodeStructure/PDiskTitleBadge.js.map +0 -1
- package/dist/containers/Node/NodeStructure/Pdisk.d.ts +0 -10
- package/dist/containers/Node/NodeStructure/Pdisk.js +0 -125
- package/dist/containers/Node/NodeStructure/Pdisk.js.map +0 -1
- package/dist/store/reducers/node/selectors.d.ts +0 -47
- package/dist/store/reducers/node/selectors.js +0 -43
- package/dist/store/reducers/node/selectors.js.map +0 -1
- package/src/containers/Node/NodeStructure/NodeStructure.scss +0 -155
- package/src/containers/Node/NodeStructure/NodeStructure.tsx +0 -121
- package/src/containers/Node/NodeStructure/PDiskTitleBadge.tsx +0 -18
- package/src/containers/Node/NodeStructure/Pdisk.tsx +0 -274
- package/src/store/reducers/node/selectors.ts +0 -68
|
@@ -43,7 +43,6 @@ export function StorageGroupInfo({data, className, ...infoViewerProps}: StorageG
|
|
|
43
43
|
Read,
|
|
44
44
|
Write,
|
|
45
45
|
GroupGeneration,
|
|
46
|
-
Latency,
|
|
47
46
|
AllocationUnits,
|
|
48
47
|
State,
|
|
49
48
|
MissingDisks,
|
|
@@ -140,12 +139,6 @@ export function StorageGroupInfo({data, className, ...infoViewerProps}: StorageG
|
|
|
140
139
|
});
|
|
141
140
|
}
|
|
142
141
|
runtimeInfo.push(...toInfoViewerItems(getStorageGroupCapacityInfoItems(data)));
|
|
143
|
-
if (valueIsDefined(Latency)) {
|
|
144
|
-
runtimeInfo.push({
|
|
145
|
-
label: storageGroupInfoKeyset('latency'),
|
|
146
|
-
value: <StatusIcon status={Latency} />,
|
|
147
|
-
});
|
|
148
|
-
}
|
|
149
142
|
if (valueIsDefined(LatencyPutTabletLogMs)) {
|
|
150
143
|
runtimeInfo.push({
|
|
151
144
|
label: storageGroupInfoKeyset('latency-put-tablet-log'),
|
|
@@ -258,12 +251,6 @@ export function StorageGroupInfo({data, className, ...infoViewerProps}: StorageG
|
|
|
258
251
|
value: <StatusIcon status={DiskSpace} />,
|
|
259
252
|
});
|
|
260
253
|
}
|
|
261
|
-
if (valueIsDefined(Latency)) {
|
|
262
|
-
storageGroupInfoSecondColumn.push({
|
|
263
|
-
label: storageGroupInfoKeyset('latency'),
|
|
264
|
-
value: <StatusIcon status={Latency} />,
|
|
265
|
-
});
|
|
266
|
-
}
|
|
267
254
|
if (valueIsDefined(LatencyPutTabletLogMs)) {
|
|
268
255
|
storageGroupInfoSecondColumn.push({
|
|
269
256
|
label: storageGroupInfoKeyset('latency-put-tablet-log'),
|
|
@@ -12,7 +12,6 @@
|
|
|
12
12
|
"yes": "Yes",
|
|
13
13
|
"no": "No",
|
|
14
14
|
"group-generation": "Group Generation",
|
|
15
|
-
"latency": "Latency",
|
|
16
15
|
"allocation-units": "Allocation Units",
|
|
17
16
|
"context_allocation-units": "The number of channels used by tablets to write data to the storage group.",
|
|
18
17
|
"state": "State",
|
|
@@ -4,9 +4,9 @@ import type {Store} from '@reduxjs/toolkit';
|
|
|
4
4
|
import type {History} from 'history';
|
|
5
5
|
import {Helmet} from 'react-helmet-async';
|
|
6
6
|
|
|
7
|
-
import {componentsRegistry} from '../../components/ComponentsProvider/componentsRegistry';
|
|
8
7
|
import {FullscreenProvider} from '../../components/Fullscreen/FullscreenContext';
|
|
9
|
-
import {
|
|
8
|
+
import {uiFactory} from '../../uiFactory/uiFactory';
|
|
9
|
+
import {useTypedSelector} from '../../utils/hooks/useTypedSelector';
|
|
10
10
|
import type {YDBEmbeddedUISettings} from '../UserSettings/settings';
|
|
11
11
|
|
|
12
12
|
import {useAppTitle} from './AppTitleContext';
|
|
@@ -27,7 +27,7 @@ export interface AppProps {
|
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
function App({store, history, children, userSettings, appTitle = defaultAppTitle}: AppProps) {
|
|
30
|
-
const ChatPanel =
|
|
30
|
+
const ChatPanel = uiFactory.renderChatPanel;
|
|
31
31
|
|
|
32
32
|
return (
|
|
33
33
|
<Providers store={store} history={history} appTitle={appTitle}>
|
|
@@ -53,6 +53,14 @@
|
|
|
53
53
|
|
|
54
54
|
&__storage-section {
|
|
55
55
|
--g-card-border-radius: var(--g-border-radius-s);
|
|
56
|
+
|
|
57
|
+
width: 100%;
|
|
58
|
+
|
|
59
|
+
@container overview-wrapper (min-width: 804px) {
|
|
60
|
+
width: var(--cluster-overview-section);
|
|
61
|
+
min-width: var(--cluster-overview-section);
|
|
62
|
+
}
|
|
63
|
+
|
|
56
64
|
@container overview-wrapper (min-width: 1104px) {
|
|
57
65
|
grid-area: storage;
|
|
58
66
|
}
|
|
@@ -15,6 +15,7 @@ import {BridgeInfoTable} from '../ClusterOverview/components/BridgeInfoTable';
|
|
|
15
15
|
import i18n from '../i18n';
|
|
16
16
|
|
|
17
17
|
import {StorageGroupStats} from './components/DiskGroupsStatsBars/DiskGroupsStats';
|
|
18
|
+
import {prepareClusterGroupsStats} from './components/DiskGroupsStatsBars/utils';
|
|
18
19
|
import {b} from './shared';
|
|
19
20
|
|
|
20
21
|
import './ClusterInfo.scss';
|
|
@@ -35,12 +36,16 @@ export const ClusterInfo = ({
|
|
|
35
36
|
loading,
|
|
36
37
|
error,
|
|
37
38
|
additionalClusterProps = {},
|
|
38
|
-
groupStats
|
|
39
|
+
groupStats,
|
|
39
40
|
bridgePiles,
|
|
40
41
|
}: ClusterInfoProps) => {
|
|
41
42
|
const {info = [], links = []} = additionalClusterProps;
|
|
42
43
|
|
|
43
44
|
const clusterLinks = useClusterLinks(links);
|
|
45
|
+
const preparedGroupStats = React.useMemo(
|
|
46
|
+
() => prepareClusterGroupsStats(groupStats ?? {}),
|
|
47
|
+
[groupStats],
|
|
48
|
+
);
|
|
44
49
|
|
|
45
50
|
const noDetails = (error && !cluster) || (!info.length && !clusterLinks.length);
|
|
46
51
|
|
|
@@ -106,17 +111,12 @@ export const ClusterInfo = ({
|
|
|
106
111
|
};
|
|
107
112
|
|
|
108
113
|
const renderStorageGroupsSection = () => {
|
|
109
|
-
if (loading ||
|
|
114
|
+
if (loading || preparedGroupStats.disks.length === 0) {
|
|
110
115
|
return null;
|
|
111
116
|
}
|
|
112
117
|
return (
|
|
113
|
-
<InfoSection className={b('storage-section')}>
|
|
114
|
-
<
|
|
115
|
-
{i18n('title_storage-groups')}
|
|
116
|
-
</Text>
|
|
117
|
-
<Card view="filled" className={b('section', {compact: true})}>
|
|
118
|
-
<StorageGroupStats groupStats={groupStats} />
|
|
119
|
-
</Card>
|
|
118
|
+
<InfoSection className={b('storage-section')} dataQa="cluster-storage-groups">
|
|
119
|
+
<StorageGroupStats stats={preparedGroupStats} />
|
|
120
120
|
</InfoSection>
|
|
121
121
|
);
|
|
122
122
|
};
|
|
@@ -157,11 +157,12 @@ export const ClusterInfo = ({
|
|
|
157
157
|
interface InfoSectionProps {
|
|
158
158
|
children: React.ReactNode;
|
|
159
159
|
className?: string;
|
|
160
|
+
dataQa?: string;
|
|
160
161
|
}
|
|
161
162
|
|
|
162
|
-
function InfoSection({children, className}: InfoSectionProps) {
|
|
163
|
+
function InfoSection({children, className, dataQa}: InfoSectionProps) {
|
|
163
164
|
return (
|
|
164
|
-
<Flex direction="column" gap={2} className={className}>
|
|
165
|
+
<Flex direction="column" gap={2} className={className} qa={dataQa}>
|
|
165
166
|
{children}
|
|
166
167
|
</Flex>
|
|
167
168
|
);
|
package/src/containers/Cluster/ClusterInfo/components/DiskGroupsStatsBars/DiskGroupsStats.scss
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
.ydb-disk-groups-stats {
|
|
2
|
+
&__card {
|
|
3
|
+
padding: var(--g-spacing-3) var(--g-spacing-4);
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
&__available-help {
|
|
7
|
+
color: inherit;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
&__legend-dot {
|
|
11
|
+
flex: 0 0 8px;
|
|
12
|
+
|
|
13
|
+
width: 8px;
|
|
14
|
+
height: 8px;
|
|
15
|
+
|
|
16
|
+
border-radius: 50%;
|
|
17
|
+
}
|
|
18
|
+
}
|
package/src/containers/Cluster/ClusterInfo/components/DiskGroupsStatsBars/DiskGroupsStats.tsx
CHANGED
|
@@ -1,81 +1,166 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
|
|
3
|
-
import {Flex, Label, Text} from '@gravity-ui/uikit';
|
|
3
|
+
import {Card, Flex, HelpMark, Label, Text} from '@gravity-ui/uikit';
|
|
4
4
|
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
} from '../../../../../
|
|
5
|
+
import {
|
|
6
|
+
SegmentedProgress,
|
|
7
|
+
defaultNormalizePercent,
|
|
8
|
+
} from '../../../../../components/SegmentedProgress/SegmentedProgress';
|
|
9
|
+
import {cn} from '../../../../../utils/cn';
|
|
10
10
|
import {formatNumber} from '../../../../../utils/dataFormatters/dataFormatters';
|
|
11
11
|
import i18n from '../../../i18n';
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
import type {
|
|
14
|
+
PreparedClusterGroupsStats,
|
|
15
|
+
PreparedDiskGroupsStats,
|
|
16
|
+
PreparedErasureGroupsStats,
|
|
17
|
+
} from './utils';
|
|
18
|
+
|
|
19
|
+
import './DiskGroupsStats.scss';
|
|
20
|
+
|
|
21
|
+
const b = cn('ydb-disk-groups-stats');
|
|
22
|
+
|
|
23
|
+
const ERASURE_COLORS: Record<string, string> = {
|
|
24
|
+
'block-4-2': 'var(--g-color-base-info-heavy)',
|
|
25
|
+
'mirror-3-dc': 'var(--g-color-base-utility-heavy)',
|
|
26
|
+
'mirror-3of4': 'var(--g-color-base-utility-heavy)',
|
|
27
|
+
none: 'var(--g-color-base-neutral-heavy)',
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
function getErasureColor(erasure: string) {
|
|
31
|
+
return ERASURE_COLORS[erasure] ?? 'var(--g-color-base-neutral-heavy)';
|
|
16
32
|
}
|
|
17
33
|
|
|
18
|
-
function
|
|
19
|
-
|
|
34
|
+
function formatGroups(count: number) {
|
|
35
|
+
return i18n('value_groups', {
|
|
36
|
+
count,
|
|
37
|
+
formattedCount: formatNumber(count),
|
|
38
|
+
});
|
|
39
|
+
}
|
|
20
40
|
|
|
21
|
-
|
|
41
|
+
function formatAvailableGroups({min, max}: PreparedDiskGroupsStats['availableGroups']) {
|
|
42
|
+
if (min === max) {
|
|
43
|
+
return formatGroups(min);
|
|
44
|
+
}
|
|
22
45
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
46
|
+
return i18n('value_available-groups-range', {
|
|
47
|
+
min: formatNumber(min),
|
|
48
|
+
max: formatNumber(max),
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function getErasureTooltip(stats: PreparedErasureGroupsStats) {
|
|
53
|
+
return i18n('context_available-groups-by-erasure', {
|
|
54
|
+
count: stats.availableGroups,
|
|
55
|
+
formattedCount: formatNumber(stats.availableGroups),
|
|
56
|
+
erasure: stats.erasure,
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function DiskGroupStats({stats}: {stats: PreparedDiskGroupsStats}) {
|
|
61
|
+
const legendId = React.useId();
|
|
62
|
+
const {allocatedGroups, availableGroups, diskType, erasures, progressTotalGroups} = stats;
|
|
63
|
+
const progressValue = progressTotalGroups > 0 ? allocatedGroups / progressTotalGroups : 0;
|
|
64
|
+
const progressPercent = progressValue * 100;
|
|
65
|
+
const progressLabel = i18n('context_storage-group-allocation-progress', {
|
|
66
|
+
diskType,
|
|
67
|
+
percent: defaultNormalizePercent(progressPercent),
|
|
68
|
+
});
|
|
69
|
+
const availableGroupsContext = i18n('context_available-groups');
|
|
70
|
+
|
|
71
|
+
const segments = erasures.map((erasureStats, index) => ({
|
|
72
|
+
id: erasureStats.erasure,
|
|
73
|
+
value: erasureStats.createdGroups,
|
|
74
|
+
minWidth: 10,
|
|
75
|
+
color: getErasureColor(erasureStats.erasure),
|
|
76
|
+
className: b('progress-segment'),
|
|
77
|
+
dataQa: 'cluster-storage-group-segment',
|
|
78
|
+
tooltip: getErasureTooltip(erasureStats),
|
|
79
|
+
ariaLabelledBy: `${legendId}-${index}`,
|
|
80
|
+
}));
|
|
29
81
|
|
|
30
82
|
return (
|
|
31
|
-
<
|
|
32
|
-
<Flex
|
|
33
|
-
<
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
83
|
+
<Card view="filled" className={b('card')} qa="cluster-storage-group-card">
|
|
84
|
+
<Flex direction="column" gap={1}>
|
|
85
|
+
<Flex direction="column" gap={2}>
|
|
86
|
+
<Flex justifyContent="space-between" alignItems="center" gap={2}>
|
|
87
|
+
<Text variant="subheader-1">{diskType}</Text>
|
|
88
|
+
<Label
|
|
89
|
+
theme="info"
|
|
90
|
+
value={
|
|
91
|
+
<Flex alignItems="center" gap={1}>
|
|
92
|
+
{formatAvailableGroups(availableGroups)}
|
|
93
|
+
<HelpMark
|
|
94
|
+
iconSize="s"
|
|
95
|
+
aria-label={i18n('action_show-available-groups-info', {
|
|
96
|
+
diskType,
|
|
97
|
+
})}
|
|
98
|
+
className={b('available-help')}
|
|
99
|
+
popoverProps={{placement: ['top', 'bottom']}}
|
|
100
|
+
>
|
|
101
|
+
{availableGroupsContext}
|
|
102
|
+
</HelpMark>
|
|
103
|
+
</Flex>
|
|
104
|
+
}
|
|
105
|
+
>
|
|
106
|
+
{i18n('title_available')}
|
|
107
|
+
</Label>
|
|
108
|
+
</Flex>
|
|
109
|
+
<div role="group" aria-label={progressLabel}>
|
|
110
|
+
<SegmentedProgress
|
|
111
|
+
segments={segments}
|
|
112
|
+
total={progressTotalGroups}
|
|
113
|
+
ariaLabel={progressLabel}
|
|
114
|
+
hideLabels
|
|
115
|
+
/>
|
|
116
|
+
</div>
|
|
117
|
+
</Flex>
|
|
118
|
+
<Flex justifyContent="space-between" alignItems="center" gap={2} wrap="wrap">
|
|
119
|
+
<Flex alignItems="center" gap={4} wrap="wrap">
|
|
120
|
+
{erasures.map((erasureStats, index) => (
|
|
121
|
+
<Flex
|
|
122
|
+
key={erasureStats.erasure}
|
|
123
|
+
id={`${legendId}-${index}`}
|
|
124
|
+
alignItems="center"
|
|
125
|
+
gap={2}
|
|
126
|
+
>
|
|
127
|
+
<span
|
|
128
|
+
aria-hidden="true"
|
|
129
|
+
className={b('legend-dot')}
|
|
130
|
+
style={{backgroundColor: getErasureColor(erasureStats.erasure)}}
|
|
131
|
+
/>
|
|
132
|
+
<Text>{erasureStats.erasure}</Text>
|
|
133
|
+
<Text color="secondary">
|
|
134
|
+
{formatGroups(erasureStats.createdGroups)}
|
|
135
|
+
</Text>
|
|
136
|
+
</Flex>
|
|
137
|
+
))}
|
|
138
|
+
</Flex>
|
|
139
|
+
<Text color="secondary">{formatGroups(allocatedGroups)}</Text>
|
|
42
140
|
</Flex>
|
|
43
141
|
</Flex>
|
|
44
|
-
|
|
45
|
-
value={stats.createdGroups}
|
|
46
|
-
total={stats.totalGroups}
|
|
47
|
-
labelStart={erasure}
|
|
48
|
-
ariaLabel={i18n('context_storage-group-allocation-progress')}
|
|
49
|
-
/>
|
|
50
|
-
</Flex>
|
|
142
|
+
</Card>
|
|
51
143
|
);
|
|
52
144
|
}
|
|
53
145
|
|
|
54
146
|
interface StorageGroupStatsProps {
|
|
55
|
-
|
|
147
|
+
stats: PreparedClusterGroupsStats;
|
|
56
148
|
}
|
|
57
149
|
|
|
58
|
-
export function StorageGroupStats({
|
|
59
|
-
const stats = React.useMemo(() => {
|
|
60
|
-
const result: React.ReactNode[] = [];
|
|
61
|
-
|
|
62
|
-
Object.entries(groupStats).forEach(([storageType, stats]) => {
|
|
63
|
-
Object.values(stats).forEach((erasureStats) => {
|
|
64
|
-
result.push(
|
|
65
|
-
<DiskGroupStats
|
|
66
|
-
key={`${storageType}|${erasureStats.erasure}`}
|
|
67
|
-
stats={erasureStats}
|
|
68
|
-
storageType={storageType}
|
|
69
|
-
/>,
|
|
70
|
-
);
|
|
71
|
-
});
|
|
72
|
-
});
|
|
73
|
-
return result;
|
|
74
|
-
}, [groupStats]);
|
|
75
|
-
|
|
150
|
+
export function StorageGroupStats({stats}: StorageGroupStatsProps) {
|
|
76
151
|
return (
|
|
77
|
-
<
|
|
78
|
-
|
|
79
|
-
|
|
152
|
+
<React.Fragment>
|
|
153
|
+
<Text as="div" variant="subheader-2">
|
|
154
|
+
{i18n('title_storage-groups')}{' '}
|
|
155
|
+
<Text color="secondary" variant="subheader-2">
|
|
156
|
+
{formatNumber(stats.allocatedGroups)}
|
|
157
|
+
</Text>
|
|
158
|
+
</Text>
|
|
159
|
+
<Flex direction="column" gap={1}>
|
|
160
|
+
{stats.disks.map((diskStats) => (
|
|
161
|
+
<DiskGroupStats key={diskStats.diskType} stats={diskStats} />
|
|
162
|
+
))}
|
|
163
|
+
</Flex>
|
|
164
|
+
</React.Fragment>
|
|
80
165
|
);
|
|
81
166
|
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import type {ClusterGroupsStats} from '../../../../../store/reducers/cluster/types';
|
|
2
|
+
|
|
3
|
+
const DISK_TYPE_ORDER = ['HDD', 'SSD'];
|
|
4
|
+
const ERASURE_ORDER = ['block-4-2', 'mirror-3-dc', 'mirror-3of4', 'none'];
|
|
5
|
+
|
|
6
|
+
export interface PreparedErasureGroupsStats {
|
|
7
|
+
erasure: string;
|
|
8
|
+
createdGroups: number;
|
|
9
|
+
availableGroups: number;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface PreparedDiskGroupsStats {
|
|
13
|
+
diskType: string;
|
|
14
|
+
erasures: PreparedErasureGroupsStats[];
|
|
15
|
+
allocatedGroups: number;
|
|
16
|
+
availableGroups: {
|
|
17
|
+
min: number;
|
|
18
|
+
max: number;
|
|
19
|
+
average: number;
|
|
20
|
+
};
|
|
21
|
+
progressTotalGroups: number;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface PreparedClusterGroupsStats {
|
|
25
|
+
disks: PreparedDiskGroupsStats[];
|
|
26
|
+
allocatedGroups: number;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function getErasureOrder(erasure: string) {
|
|
30
|
+
const index = ERASURE_ORDER.indexOf(erasure);
|
|
31
|
+
|
|
32
|
+
return index === -1 ? ERASURE_ORDER.length : index;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function getDiskTypeOrder(diskType: string) {
|
|
36
|
+
const index = DISK_TYPE_ORDER.indexOf(diskType);
|
|
37
|
+
|
|
38
|
+
return index === -1 ? DISK_TYPE_ORDER.length : index;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export function prepareClusterGroupsStats(
|
|
42
|
+
groupStats: ClusterGroupsStats,
|
|
43
|
+
): PreparedClusterGroupsStats {
|
|
44
|
+
let allocatedGroups = 0;
|
|
45
|
+
|
|
46
|
+
const disks = Object.entries(groupStats)
|
|
47
|
+
.flatMap(([diskType, diskStats]) => {
|
|
48
|
+
const erasures = Object.values(diskStats)
|
|
49
|
+
.filter(({createdGroups}) => createdGroups > 0)
|
|
50
|
+
.map((stats) => ({
|
|
51
|
+
erasure: stats.erasure,
|
|
52
|
+
createdGroups: stats.createdGroups,
|
|
53
|
+
availableGroups: stats.totalGroups - stats.createdGroups,
|
|
54
|
+
}))
|
|
55
|
+
.sort((a, b) => getErasureOrder(a.erasure) - getErasureOrder(b.erasure));
|
|
56
|
+
|
|
57
|
+
if (erasures.length === 0) {
|
|
58
|
+
return [];
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const diskAllocatedGroups = erasures.reduce(
|
|
62
|
+
(sum, stats) => sum + stats.createdGroups,
|
|
63
|
+
0,
|
|
64
|
+
);
|
|
65
|
+
const availableValues = erasures.map((stats) => stats.availableGroups);
|
|
66
|
+
const minAvailableGroups = Math.min(...availableValues);
|
|
67
|
+
const maxAvailableGroups = Math.max(...availableValues);
|
|
68
|
+
const averageAvailableGroups = (minAvailableGroups + maxAvailableGroups) / 2;
|
|
69
|
+
|
|
70
|
+
allocatedGroups += diskAllocatedGroups;
|
|
71
|
+
|
|
72
|
+
return [
|
|
73
|
+
{
|
|
74
|
+
diskType,
|
|
75
|
+
erasures,
|
|
76
|
+
allocatedGroups: diskAllocatedGroups,
|
|
77
|
+
availableGroups: {
|
|
78
|
+
min: minAvailableGroups,
|
|
79
|
+
max: maxAvailableGroups,
|
|
80
|
+
average: averageAvailableGroups,
|
|
81
|
+
},
|
|
82
|
+
progressTotalGroups: diskAllocatedGroups + averageAvailableGroups,
|
|
83
|
+
},
|
|
84
|
+
];
|
|
85
|
+
})
|
|
86
|
+
.sort((a, b) => getDiskTypeOrder(a.diskType) - getDiskTypeOrder(b.diskType));
|
|
87
|
+
|
|
88
|
+
return {disks, allocatedGroups};
|
|
89
|
+
}
|
|
@@ -1,8 +1,17 @@
|
|
|
1
1
|
{
|
|
2
|
-
"
|
|
3
|
-
"
|
|
4
|
-
|
|
5
|
-
|
|
2
|
+
"title_available": "Available",
|
|
3
|
+
"value_groups": {
|
|
4
|
+
"one": "{{formattedCount}} group",
|
|
5
|
+
"other": "{{formattedCount}} groups"
|
|
6
|
+
},
|
|
7
|
+
"value_available-groups-range": "{{min}}–{{max}} groups",
|
|
8
|
+
"context_available-groups": "Estimated number of free groups available for allocation.",
|
|
9
|
+
"action_show-available-groups-info": "About available {{diskType}} storage groups",
|
|
10
|
+
"context_available-groups-by-erasure": {
|
|
11
|
+
"one": "{{formattedCount}} group available if only {{erasure}} is used",
|
|
12
|
+
"other": "{{formattedCount}} groups available if only {{erasure}} is used"
|
|
13
|
+
},
|
|
14
|
+
"context_storage-group-allocation-progress": "{{diskType}} storage group allocation: {{percent}}%",
|
|
6
15
|
"title_cpu": "CPU",
|
|
7
16
|
"title_storage-groups": "Allocated Storage Groups",
|
|
8
17
|
"title_memory": "Memory",
|
|
@@ -16,7 +16,6 @@ import routes, {getDefaultNodePath} from '../../routes';
|
|
|
16
16
|
import {
|
|
17
17
|
useCapabilitiesLoaded,
|
|
18
18
|
useConfigAvailable,
|
|
19
|
-
useDiskPagesAvailable,
|
|
20
19
|
useViewerPeersHandlerAvailable,
|
|
21
20
|
} from '../../store/reducers/capabilities/hooks';
|
|
22
21
|
import {setHeaderBreadcrumbs} from '../../store/reducers/header/header';
|
|
@@ -34,7 +33,6 @@ import {Tablets} from '../Tablets/Tablets';
|
|
|
34
33
|
|
|
35
34
|
import type {NodeTab} from './NodePages';
|
|
36
35
|
import {NODE_TABS, nodePageQueryParams, nodePageTabSchema} from './NodePages';
|
|
37
|
-
import NodeStructure from './NodeStructure/NodeStructure';
|
|
38
36
|
import {Threads} from './Threads/Threads';
|
|
39
37
|
import i18n from './i18n';
|
|
40
38
|
|
|
@@ -52,12 +50,14 @@ export function Node() {
|
|
|
52
50
|
const dispatch = useTypedDispatch();
|
|
53
51
|
const history = useHistory();
|
|
54
52
|
|
|
55
|
-
const match = useRouteMatch<{id: string; activeTab: string}>(routes.node);
|
|
53
|
+
const match = useRouteMatch<{id: string; activeTab: string; environment?: string}>(routes.node);
|
|
56
54
|
|
|
57
55
|
const nodeId = match?.params.id;
|
|
58
56
|
const activeTabIdFromQuery = match?.params.activeTab;
|
|
57
|
+
const environment = match?.params.environment;
|
|
59
58
|
|
|
60
|
-
const [{database: tenantNameFromQuery}] =
|
|
59
|
+
const [{database: tenantNameFromQuery, clusterName, backend}] =
|
|
60
|
+
useQueryParams(nodePageQueryParams);
|
|
61
61
|
const database = tenantNameFromQuery?.toString();
|
|
62
62
|
|
|
63
63
|
const activeTabId = nodePageTabSchema.parse(activeTabIdFromQuery);
|
|
@@ -72,7 +72,6 @@ export function Node() {
|
|
|
72
72
|
} = nodeApi.useGetNodeInfoQuery(params, {pollingInterval: autoRefreshInterval});
|
|
73
73
|
|
|
74
74
|
const capabilitiesLoaded = useCapabilitiesLoaded();
|
|
75
|
-
const isDiskPagesAvailable = useDiskPagesAvailable();
|
|
76
75
|
const isPeersHandlerAvailable = useViewerPeersHandlerAvailable();
|
|
77
76
|
|
|
78
77
|
const pageLoading = isLoading || !capabilitiesLoaded;
|
|
@@ -89,9 +88,6 @@ export function Node() {
|
|
|
89
88
|
if (!configsAvailable) {
|
|
90
89
|
skippedTabs.push('configs');
|
|
91
90
|
}
|
|
92
|
-
if (isDiskPagesAvailable) {
|
|
93
|
-
skippedTabs.push('structure');
|
|
94
|
-
}
|
|
95
91
|
if ((!database && !isViewerUser) || !hasThreads) {
|
|
96
92
|
skippedTabs.push('threads');
|
|
97
93
|
}
|
|
@@ -111,7 +107,6 @@ export function Node() {
|
|
|
111
107
|
return {activeTab: actualActiveTab, nodeTabs: actualNodeTabs};
|
|
112
108
|
}, [
|
|
113
109
|
isStorageNode,
|
|
114
|
-
isDiskPagesAvailable,
|
|
115
110
|
isPeersHandlerAvailable,
|
|
116
111
|
activeTabId,
|
|
117
112
|
hasThreads,
|
|
@@ -142,12 +137,26 @@ export function Node() {
|
|
|
142
137
|
return;
|
|
143
138
|
}
|
|
144
139
|
|
|
145
|
-
if (activeTab.id !== activeTabId) {
|
|
146
|
-
const path = getDefaultNodePath(
|
|
140
|
+
if (activeTab.id !== activeTabId || activeTabIdFromQuery === 'structure') {
|
|
141
|
+
const path = getDefaultNodePath(
|
|
142
|
+
{id: nodeId, activeTab: activeTab.id, environment},
|
|
143
|
+
{database, clusterName: clusterName ?? undefined, backend: backend ?? undefined},
|
|
144
|
+
);
|
|
147
145
|
|
|
148
146
|
history.replace(path);
|
|
149
147
|
}
|
|
150
|
-
}, [
|
|
148
|
+
}, [
|
|
149
|
+
nodeId,
|
|
150
|
+
database,
|
|
151
|
+
clusterName,
|
|
152
|
+
backend,
|
|
153
|
+
environment,
|
|
154
|
+
activeTab.id,
|
|
155
|
+
activeTabId,
|
|
156
|
+
activeTabIdFromQuery,
|
|
157
|
+
history,
|
|
158
|
+
activeTab,
|
|
159
|
+
]);
|
|
151
160
|
|
|
152
161
|
return (
|
|
153
162
|
<div className={b(null)} ref={container}>
|
|
@@ -160,6 +169,9 @@ export function Node() {
|
|
|
160
169
|
<NodePageContent
|
|
161
170
|
nodeId={nodeId}
|
|
162
171
|
database={database}
|
|
172
|
+
clusterName={clusterName ?? undefined}
|
|
173
|
+
backend={backend ?? undefined}
|
|
174
|
+
environment={environment}
|
|
163
175
|
activeTabId={activeTab.id}
|
|
164
176
|
tabs={nodeTabs}
|
|
165
177
|
parentContainer={container}
|
|
@@ -233,6 +245,9 @@ function NodePageInfo({node, loading}: NodePageInfoProps) {
|
|
|
233
245
|
interface NodePageContentProps {
|
|
234
246
|
nodeId: string;
|
|
235
247
|
database?: string;
|
|
248
|
+
clusterName?: string;
|
|
249
|
+
backend?: string;
|
|
250
|
+
environment?: string;
|
|
236
251
|
|
|
237
252
|
activeTabId: NodeTab;
|
|
238
253
|
tabs: {id: string; title: string}[];
|
|
@@ -243,6 +258,9 @@ interface NodePageContentProps {
|
|
|
243
258
|
function NodePageContent({
|
|
244
259
|
nodeId,
|
|
245
260
|
database,
|
|
261
|
+
clusterName,
|
|
262
|
+
backend,
|
|
263
|
+
environment,
|
|
246
264
|
activeTabId,
|
|
247
265
|
tabs,
|
|
248
266
|
parentContainer,
|
|
@@ -254,8 +272,8 @@ function NodePageContent({
|
|
|
254
272
|
<TabList className={b('tab-list')} size="l">
|
|
255
273
|
{tabs.map(({id, title}) => {
|
|
256
274
|
const path = getDefaultNodePath(
|
|
257
|
-
{id: nodeId, activeTab: id as NodeTab},
|
|
258
|
-
{database},
|
|
275
|
+
{id: nodeId, activeTab: id as NodeTab, environment},
|
|
276
|
+
{database, clusterName, backend},
|
|
259
277
|
);
|
|
260
278
|
return (
|
|
261
279
|
<Tab value={id} key={id}>
|
|
@@ -296,10 +314,6 @@ function NodePageContent({
|
|
|
296
314
|
);
|
|
297
315
|
}
|
|
298
316
|
|
|
299
|
-
case 'structure': {
|
|
300
|
-
return <NodeStructure nodeId={nodeId} />;
|
|
301
|
-
}
|
|
302
|
-
|
|
303
317
|
case 'threads': {
|
|
304
318
|
return (
|
|
305
319
|
<Threads
|
|
@@ -9,7 +9,6 @@ import i18n from './i18n';
|
|
|
9
9
|
const NODE_TABS_IDS = {
|
|
10
10
|
storage: 'storage',
|
|
11
11
|
tablets: 'tablets',
|
|
12
|
-
structure: 'structure',
|
|
13
12
|
threads: 'threads',
|
|
14
13
|
network: 'network',
|
|
15
14
|
configs: 'configs',
|
|
@@ -24,12 +23,6 @@ export const NODE_TABS = [
|
|
|
24
23
|
return i18n('tabs.storage');
|
|
25
24
|
},
|
|
26
25
|
},
|
|
27
|
-
{
|
|
28
|
-
id: NODE_TABS_IDS.structure,
|
|
29
|
-
get title() {
|
|
30
|
-
return i18n('tabs.structure');
|
|
31
|
-
},
|
|
32
|
-
},
|
|
33
26
|
{
|
|
34
27
|
id: NODE_TABS_IDS.tablets,
|
|
35
28
|
get title() {
|
|
@@ -56,13 +49,15 @@ export const NODE_TABS = [
|
|
|
56
49
|
},
|
|
57
50
|
];
|
|
58
51
|
|
|
59
|
-
export const nodePageTabSchema = z.
|
|
52
|
+
export const nodePageTabSchema = z.preprocess(
|
|
53
|
+
(value) => (value === 'structure' ? NODE_TABS_IDS.storage : value),
|
|
54
|
+
z.nativeEnum(NODE_TABS_IDS).catch(NODE_TABS_IDS.tablets),
|
|
55
|
+
);
|
|
60
56
|
|
|
61
57
|
export const nodePageQueryParams = {
|
|
62
58
|
database: StringParam,
|
|
63
|
-
pdiskId: StringParam,
|
|
64
|
-
vdiskId: StringParam,
|
|
65
59
|
clusterName: StringParam,
|
|
60
|
+
backend: StringParam,
|
|
66
61
|
};
|
|
67
62
|
|
|
68
63
|
export type NodePageQuery = QueryParamsTypeFromQueryObject<typeof nodePageQueryParams>;
|