ydb-embedded-ui 21.0.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.
Files changed (272) hide show
  1. package/dist/components/ComponentsProvider/ComponentsProvider.d.ts +0 -4
  2. package/dist/components/ComponentsProvider/componentsRegistry.d.ts +0 -2
  3. package/dist/components/ComponentsProvider/componentsRegistry.js +1 -3
  4. package/dist/components/ComponentsProvider/componentsRegistry.js.map +1 -1
  5. package/dist/components/ContentWithPopup/ContentWithPopup.d.ts +1 -1
  6. package/dist/components/ContentWithPopup/ContentWithPopup.js +4 -2
  7. package/dist/components/ContentWithPopup/ContentWithPopup.js.map +1 -1
  8. package/dist/components/CriticalActionDialog/CriticalActionDialog.js +10 -6
  9. package/dist/components/CriticalActionDialog/CriticalActionDialog.js.map +1 -1
  10. package/dist/components/CriticalActionDialog/i18n/en.json +1 -2
  11. package/dist/components/CriticalActionDialog/i18n/index.d.ts +1 -1
  12. package/dist/components/DropdownMenu/DropdownMenu.d.ts +2 -1
  13. package/dist/components/DropdownMenu/DropdownMenu.js +1 -1
  14. package/dist/components/DropdownMenu/DropdownMenu.js.map +1 -1
  15. package/dist/components/FullNodeViewer/i18n/index.d.ts +1 -1
  16. package/dist/components/HoverPopup/HoverPopup.js +27 -4
  17. package/dist/components/HoverPopup/HoverPopup.js.map +1 -1
  18. package/dist/components/HoverPopup/getPopupScrollContainer.d.ts +1 -0
  19. package/dist/components/HoverPopup/getPopupScrollContainer.js +20 -0
  20. package/dist/components/HoverPopup/getPopupScrollContainer.js.map +1 -0
  21. package/dist/components/MetricChart/reducer.d.ts +2 -2
  22. package/dist/components/SegmentedProgress/SegmentedProgress.d.ts +22 -1
  23. package/dist/components/SegmentedProgress/SegmentedProgress.js +44 -3
  24. package/dist/components/SegmentedProgress/SegmentedProgress.js.map +1 -1
  25. package/dist/components/SegmentedProgress/SegmentedProgress.scss +5 -0
  26. package/dist/components/StorageGroupInfo/StorageGroupInfo.js +1 -13
  27. package/dist/components/StorageGroupInfo/StorageGroupInfo.js.map +1 -1
  28. package/dist/components/StorageGroupInfo/i18n/en.json +0 -1
  29. package/dist/components/StorageGroupInfo/i18n/index.d.ts +1 -1
  30. package/dist/components/nodesColumns/i18n/index.d.ts +1 -1
  31. package/dist/containers/App/App.js +3 -3
  32. package/dist/containers/App/App.js.map +1 -1
  33. package/dist/containers/Cluster/ClusterInfo/ClusterInfo.js +8 -5
  34. package/dist/containers/Cluster/ClusterInfo/ClusterInfo.js.map +1 -1
  35. package/dist/containers/Cluster/ClusterInfo/ClusterInfo.scss +8 -0
  36. package/dist/containers/Cluster/ClusterInfo/components/DiskGroupsStatsBars/DiskGroupsStats.d.ts +4 -3
  37. package/dist/containers/Cluster/ClusterInfo/components/DiskGroupsStatsBars/DiskGroupsStats.js +62 -25
  38. package/dist/containers/Cluster/ClusterInfo/components/DiskGroupsStatsBars/DiskGroupsStats.js.map +1 -1
  39. package/dist/containers/Cluster/ClusterInfo/components/DiskGroupsStatsBars/DiskGroupsStats.scss +18 -0
  40. package/dist/containers/Cluster/ClusterInfo/components/DiskGroupsStatsBars/utils.d.ts +22 -0
  41. package/dist/containers/Cluster/ClusterInfo/components/DiskGroupsStatsBars/utils.js +49 -0
  42. package/dist/containers/Cluster/ClusterInfo/components/DiskGroupsStatsBars/utils.js.map +1 -0
  43. package/dist/containers/Cluster/i18n/en.json +13 -4
  44. package/dist/containers/Cluster/i18n/index.d.ts +1 -1
  45. package/dist/containers/Header/HeaderActionsMenu.js +19 -3
  46. package/dist/containers/Header/HeaderActionsMenu.js.map +1 -1
  47. package/dist/containers/Header/hooks/useSharedDatabasePath.d.ts +4 -1
  48. package/dist/containers/Header/hooks/useSharedDatabasePath.js +14 -10
  49. package/dist/containers/Header/hooks/useSharedDatabasePath.js.map +1 -1
  50. package/dist/containers/Header/i18n/en.json +1 -0
  51. package/dist/containers/Header/i18n/index.d.ts +1 -1
  52. package/dist/containers/Node/Node.js +20 -17
  53. package/dist/containers/Node/Node.js.map +1 -1
  54. package/dist/containers/Node/NodePages.d.ts +3 -9
  55. package/dist/containers/Node/NodePages.js +2 -10
  56. package/dist/containers/Node/NodePages.js.map +1 -1
  57. package/dist/containers/Node/i18n/en.json +0 -3
  58. package/dist/containers/Node/i18n/index.d.ts +1 -1
  59. package/dist/containers/Nodes/NodesTable.js +2 -2
  60. package/dist/containers/Nodes/NodesTable.js.map +1 -1
  61. package/dist/containers/Operations/columns.js +2 -2
  62. package/dist/containers/Operations/columns.js.map +1 -1
  63. package/dist/containers/Operations/i18n/en.json +2 -2
  64. package/dist/containers/PDiskPage/DecommissionButton/DecommissionButton.js +1 -1
  65. package/dist/containers/PDiskPage/DecommissionButton/DecommissionButton.js.map +1 -1
  66. package/dist/containers/PDiskPage/PDiskPage.js +1 -1
  67. package/dist/containers/PDiskPage/PDiskPage.js.map +1 -1
  68. package/dist/containers/PDiskPage/i18n/en.json +3 -3
  69. package/dist/containers/Storage/PDisks/PDisks.js +1 -1
  70. package/dist/containers/Storage/PDisks/PDisks.js.map +1 -1
  71. package/dist/containers/Storage/PaginatedStorageGroups/GroupedStorageGroupsComponent.js +0 -1
  72. package/dist/containers/Storage/PaginatedStorageGroups/GroupedStorageGroupsComponent.js.map +1 -1
  73. package/dist/containers/Storage/PaginatedStorageGroupsTable/PaginatedStorageGroupsTable.js +2 -3
  74. package/dist/containers/Storage/PaginatedStorageGroupsTable/PaginatedStorageGroupsTable.js.map +1 -1
  75. package/dist/containers/Storage/PaginatedStorageGroupsTable/columns/constants.d.ts +2 -2
  76. package/dist/containers/Storage/PaginatedStorageGroupsTable/getGroups.d.ts +1 -1
  77. package/dist/containers/Storage/PaginatedStorageGroupsTable/getGroups.js +2 -3
  78. package/dist/containers/Storage/PaginatedStorageGroupsTable/getGroups.js.map +1 -1
  79. package/dist/containers/StorageGroupPage/StorageGroupPage.js +2 -3
  80. package/dist/containers/StorageGroupPage/StorageGroupPage.js.map +1 -1
  81. package/dist/containers/Tablet/components/TabletControls/TabletControls.js +1 -1
  82. package/dist/containers/Tablet/components/TabletControls/TabletControls.js.map +1 -1
  83. package/dist/containers/Tablet/i18n/en.json +3 -3
  84. package/dist/containers/Tablets/TabletsTable.js +1 -1
  85. package/dist/containers/Tablets/TabletsTable.js.map +1 -1
  86. package/dist/containers/Tablets/i18n/en.json +1 -1
  87. package/dist/containers/Tenant/Diagnostics/Partitions/utils/constants.d.ts +2 -2
  88. package/dist/containers/Tenant/Diagnostics/TenantOverview/Healthcheck/HealthcheckPreview.js +3 -1
  89. package/dist/containers/Tenant/Diagnostics/TenantOverview/Healthcheck/HealthcheckPreview.js.map +1 -1
  90. package/dist/containers/Tenant/Diagnostics/TenantOverview/TenantOverview.js +2 -2
  91. package/dist/containers/Tenant/Diagnostics/TenantOverview/TenantOverview.js.map +1 -1
  92. package/dist/containers/Tenant/Diagnostics/TenantOverview/TenantStorage/TopGroups.js +1 -3
  93. package/dist/containers/Tenant/Diagnostics/TenantOverview/TenantStorage/TopGroups.js.map +1 -1
  94. package/dist/containers/Tenant/Diagnostics/TenantOverview/TenantStorage/useTenantStorageNewData.d.ts +5 -5
  95. package/dist/containers/Tenant/Diagnostics/useDiagnosticsPages.js +2 -4
  96. package/dist/containers/Tenant/Diagnostics/useDiagnosticsPages.js.map +1 -1
  97. package/dist/containers/Tenant/Healthcheck/components/HealthcheckDrawer.js +10 -2
  98. package/dist/containers/Tenant/Healthcheck/components/HealthcheckDrawer.js.map +1 -1
  99. package/dist/routes.d.ts +1 -0
  100. package/dist/routes.js.map +1 -1
  101. package/dist/services/api/viewer.d.ts +1 -2
  102. package/dist/services/api/viewer.js +0 -11
  103. package/dist/services/api/viewer.js.map +1 -1
  104. package/dist/store/configureStore.d.ts +12 -12
  105. package/dist/store/defaultStore.d.ts +6 -6
  106. package/dist/store/reducers/api.d.ts +1 -1
  107. package/dist/store/reducers/api.js +3 -0
  108. package/dist/store/reducers/api.js.map +1 -1
  109. package/dist/store/reducers/authentication/authentication.d.ts +4 -4
  110. package/dist/store/reducers/cancelQuery.d.ts +2 -2
  111. package/dist/store/reducers/capabilities/capabilities.d.ts +43 -43
  112. package/dist/store/reducers/capabilities/hooks.d.ts +5 -6
  113. package/dist/store/reducers/capabilities/hooks.js +0 -3
  114. package/dist/store/reducers/capabilities/hooks.js.map +1 -1
  115. package/dist/store/reducers/cluster/cluster.d.ts +5 -5
  116. package/dist/store/reducers/cluster/cluster.js +3 -2
  117. package/dist/store/reducers/cluster/cluster.js.map +1 -1
  118. package/dist/store/reducers/clusters/clusters.d.ts +2 -2
  119. package/dist/store/reducers/clusters/clusters.js +2 -1
  120. package/dist/store/reducers/clusters/clusters.js.map +1 -1
  121. package/dist/store/reducers/codeAssist/codeAssist.d.ts +6 -6
  122. package/dist/store/reducers/configs.d.ts +3 -3
  123. package/dist/store/reducers/entityDataTags.d.ts +21 -0
  124. package/dist/store/reducers/entityDataTags.js +24 -0
  125. package/dist/store/reducers/entityDataTags.js.map +1 -0
  126. package/dist/store/reducers/environments/environments.d.ts +2 -2
  127. package/dist/store/reducers/executeTopQueries/executeTopQueries.d.ts +4 -4
  128. package/dist/store/reducers/healthcheckInfo/healthcheckInfo.d.ts +111 -111
  129. package/dist/store/reducers/heatmap.d.ts +2 -2
  130. package/dist/store/reducers/hotKeys/hotKeys.d.ts +2 -2
  131. package/dist/store/reducers/index.d.ts +8 -8
  132. package/dist/store/reducers/network/network.d.ts +2 -2
  133. package/dist/store/reducers/node/node.d.ts +2 -5
  134. package/dist/store/reducers/node/node.js +0 -12
  135. package/dist/store/reducers/node/node.js.map +1 -1
  136. package/dist/store/reducers/node/types.d.ts +0 -14
  137. package/dist/store/reducers/nodes/nodes.d.ts +2 -2
  138. package/dist/store/reducers/nodesList.d.ts +12 -12
  139. package/dist/store/reducers/operations.d.ts +5 -5
  140. package/dist/store/reducers/overview/overview.d.ts +2 -2
  141. package/dist/store/reducers/partitions/partitions.d.ts +3 -3
  142. package/dist/store/reducers/pdisk/pdisk.d.ts +2 -2
  143. package/dist/store/reducers/planToSvg.d.ts +2 -2
  144. package/dist/store/reducers/preview.d.ts +2 -2
  145. package/dist/store/reducers/query/api.d.ts +4 -4
  146. package/dist/store/reducers/replication.d.ts +2 -2
  147. package/dist/store/reducers/schema/schema.d.ts +16 -16
  148. package/dist/store/reducers/schemaAcl/schemaAcl.d.ts +40 -40
  149. package/dist/store/reducers/settings/api.d.ts +4 -4
  150. package/dist/store/reducers/settings/settings.d.ts +1 -1
  151. package/dist/store/reducers/shardsWorkload/shardsWorkload.d.ts +2 -2
  152. package/dist/store/reducers/showCreateTable/showCreateTable.d.ts +2 -2
  153. package/dist/store/reducers/storage/requestStorageData.d.ts +2 -4
  154. package/dist/store/reducers/storage/requestStorageData.js +4 -10
  155. package/dist/store/reducers/storage/requestStorageData.js.map +1 -1
  156. package/dist/store/reducers/storage/storage.d.ts +4 -6
  157. package/dist/store/reducers/storage/storage.js.map +1 -1
  158. package/dist/store/reducers/storage/types.d.ts +0 -9
  159. package/dist/store/reducers/storage/utils.d.ts +1 -2
  160. package/dist/store/reducers/storage/utils.js +3 -114
  161. package/dist/store/reducers/storage/utils.js.map +1 -1
  162. package/dist/store/reducers/storageUsage/StorageUsage.d.ts +2 -2
  163. package/dist/store/reducers/streamingQuery/streamingQuery.d.ts +2 -2
  164. package/dist/store/reducers/table/table.d.ts +4 -4
  165. package/dist/store/reducers/tableData.d.ts +1 -1
  166. package/dist/store/reducers/tablePartitioning/tablePartitioning.d.ts +2 -2
  167. package/dist/store/reducers/tableSchemaData.d.ts +2 -2
  168. package/dist/store/reducers/tablet.d.ts +8 -8
  169. package/dist/store/reducers/tablets.d.ts +3 -3
  170. package/dist/store/reducers/tenant/tenant.d.ts +2 -2
  171. package/dist/store/reducers/tenant/tenant.js +14 -1
  172. package/dist/store/reducers/tenant/tenant.js.map +1 -1
  173. package/dist/store/reducers/tenantOverview/executeTopTables/executeTopTables.d.ts +2 -2
  174. package/dist/store/reducers/tenantOverview/storage/tenantOverviewStorage.d.ts +2 -2
  175. package/dist/store/reducers/tenantOverview/topShards/tenantOverviewTopShards.d.ts +2 -2
  176. package/dist/store/reducers/tenants/tenants.d.ts +3 -3
  177. package/dist/store/reducers/tenants/tenants.js +2 -1
  178. package/dist/store/reducers/tenants/tenants.js.map +1 -1
  179. package/dist/store/reducers/topic/topic.d.ts +84 -84
  180. package/dist/store/reducers/vdisk/vdisk.d.ts +3 -3
  181. package/dist/store/reducers/viewSchema/viewSchema.d.ts +2 -2
  182. package/dist/store/state-url-mapping.js +5 -1
  183. package/dist/store/state-url-mapping.js.map +1 -1
  184. package/dist/types/api/storage.d.ts +2 -111
  185. package/dist/types/api/storage.js.map +1 -1
  186. package/dist/uiFactory/types.d.ts +8 -0
  187. package/dist/uiFactory/uiFactory.js +5 -2
  188. package/dist/uiFactory/uiFactory.js.map +1 -1
  189. package/dist/utils/hooks/useWhoami.d.ts +5 -5
  190. package/package.json +2 -2
  191. package/src/components/ComponentsProvider/componentsRegistry.ts +1 -4
  192. package/src/components/ContentWithPopup/ContentWithPopup.tsx +7 -0
  193. package/src/components/CriticalActionDialog/CriticalActionDialog.tsx +12 -25
  194. package/src/components/CriticalActionDialog/i18n/en.json +1 -2
  195. package/src/components/DropdownMenu/DropdownMenu.tsx +3 -2
  196. package/src/components/HoverPopup/HoverPopup.tsx +32 -3
  197. package/src/components/HoverPopup/getPopupScrollContainer.ts +20 -0
  198. package/src/components/SegmentedProgress/SegmentedProgress.scss +5 -0
  199. package/src/components/SegmentedProgress/SegmentedProgress.tsx +99 -10
  200. package/src/components/StorageGroupInfo/StorageGroupInfo.tsx +0 -13
  201. package/src/components/StorageGroupInfo/i18n/en.json +0 -1
  202. package/src/containers/App/App.tsx +3 -3
  203. package/src/containers/Cluster/ClusterInfo/ClusterInfo.scss +8 -0
  204. package/src/containers/Cluster/ClusterInfo/ClusterInfo.tsx +12 -11
  205. package/src/containers/Cluster/ClusterInfo/components/DiskGroupsStatsBars/DiskGroupsStats.scss +18 -0
  206. package/src/containers/Cluster/ClusterInfo/components/DiskGroupsStatsBars/DiskGroupsStats.tsx +143 -58
  207. package/src/containers/Cluster/ClusterInfo/components/DiskGroupsStatsBars/utils.ts +89 -0
  208. package/src/containers/Cluster/i18n/en.json +13 -4
  209. package/src/containers/Header/HeaderActionsMenu.tsx +22 -2
  210. package/src/containers/Header/hooks/useSharedDatabasePath.ts +33 -26
  211. package/src/containers/Header/i18n/en.json +1 -0
  212. package/src/containers/Node/Node.tsx +32 -18
  213. package/src/containers/Node/NodePages.ts +5 -10
  214. package/src/containers/Node/i18n/en.json +0 -4
  215. package/src/containers/Nodes/NodesTable.tsx +7 -1
  216. package/src/containers/Operations/columns.tsx +4 -0
  217. package/src/containers/Operations/i18n/en.json +2 -2
  218. package/src/containers/PDiskPage/DecommissionButton/DecommissionButton.tsx +2 -0
  219. package/src/containers/PDiskPage/PDiskPage.tsx +3 -1
  220. package/src/containers/PDiskPage/i18n/en.json +3 -3
  221. package/src/containers/Storage/PDisks/PDisks.tsx +1 -1
  222. package/src/containers/Storage/PaginatedStorageGroups/GroupedStorageGroupsComponent.tsx +0 -1
  223. package/src/containers/Storage/PaginatedStorageGroupsTable/PaginatedStorageGroupsTable.tsx +2 -6
  224. package/src/containers/Storage/PaginatedStorageGroupsTable/columns/constants.ts +2 -2
  225. package/src/containers/Storage/PaginatedStorageGroupsTable/getGroups.ts +40 -47
  226. package/src/containers/StorageGroupPage/StorageGroupPage.tsx +2 -6
  227. package/src/containers/Tablet/components/TabletControls/TabletControls.tsx +7 -1
  228. package/src/containers/Tablet/i18n/en.json +3 -3
  229. package/src/containers/Tablets/TabletsTable.tsx +3 -1
  230. package/src/containers/Tablets/i18n/en.json +1 -1
  231. package/src/containers/Tenant/Diagnostics/TenantOverview/Healthcheck/HealthcheckPreview.tsx +3 -1
  232. package/src/containers/Tenant/Diagnostics/TenantOverview/TenantOverview.tsx +2 -2
  233. package/src/containers/Tenant/Diagnostics/TenantOverview/TenantStorage/TopGroups.tsx +1 -6
  234. package/src/containers/Tenant/Diagnostics/useDiagnosticsPages.ts +1 -4
  235. package/src/containers/Tenant/Healthcheck/components/HealthcheckDrawer.tsx +16 -1
  236. package/src/routes.ts +1 -1
  237. package/src/services/api/viewer.ts +1 -25
  238. package/src/store/reducers/api.ts +4 -0
  239. package/src/store/reducers/capabilities/hooks.ts +0 -4
  240. package/src/store/reducers/cluster/cluster.ts +3 -2
  241. package/src/store/reducers/clusters/clusters.ts +2 -1
  242. package/src/store/reducers/entityDataTags.ts +34 -0
  243. package/src/store/reducers/node/node.ts +0 -11
  244. package/src/store/reducers/node/types.ts +0 -18
  245. package/src/store/reducers/storage/requestStorageData.ts +5 -17
  246. package/src/store/reducers/storage/storage.ts +2 -6
  247. package/src/store/reducers/storage/types.ts +0 -9
  248. package/src/store/reducers/storage/utils.ts +5 -178
  249. package/src/store/reducers/tenant/tenant.ts +17 -1
  250. package/src/store/reducers/tenants/tenants.ts +2 -1
  251. package/src/store/state-url-mapping.ts +5 -1
  252. package/src/types/api/storage.ts +7 -131
  253. package/src/uiFactory/types.ts +9 -0
  254. package/src/uiFactory/uiFactory.ts +12 -2
  255. package/dist/containers/Node/NodeStructure/NodeStructure.d.ts +0 -7
  256. package/dist/containers/Node/NodeStructure/NodeStructure.js +0 -76
  257. package/dist/containers/Node/NodeStructure/NodeStructure.js.map +0 -1
  258. package/dist/containers/Node/NodeStructure/NodeStructure.scss +0 -155
  259. package/dist/containers/Node/NodeStructure/PDiskTitleBadge.d.ts +0 -7
  260. package/dist/containers/Node/NodeStructure/PDiskTitleBadge.js +0 -7
  261. package/dist/containers/Node/NodeStructure/PDiskTitleBadge.js.map +0 -1
  262. package/dist/containers/Node/NodeStructure/Pdisk.d.ts +0 -10
  263. package/dist/containers/Node/NodeStructure/Pdisk.js +0 -125
  264. package/dist/containers/Node/NodeStructure/Pdisk.js.map +0 -1
  265. package/dist/store/reducers/node/selectors.d.ts +0 -47
  266. package/dist/store/reducers/node/selectors.js +0 -43
  267. package/dist/store/reducers/node/selectors.js.map +0 -1
  268. package/src/containers/Node/NodeStructure/NodeStructure.scss +0 -155
  269. package/src/containers/Node/NodeStructure/NodeStructure.tsx +0 -121
  270. package/src/containers/Node/NodeStructure/PDiskTitleBadge.tsx +0 -18
  271. package/src/containers/Node/NodeStructure/Pdisk.tsx +0 -274
  272. package/src/store/reducers/node/selectors.ts +0 -68
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
2
 
3
- import {Flex, Text} from '@gravity-ui/uikit';
3
+ import {Flex, Text, Tooltip} from '@gravity-ui/uikit';
4
4
 
5
5
  import {cn} from '../../utils/cn';
6
6
 
@@ -28,6 +28,7 @@ interface SegmentedProgressByValueProps extends SegmentedProgressBaseProps {
28
28
  total: number;
29
29
  fillPercent?: never;
30
30
  displayNoLimit?: DisplayNoLimit;
31
+ segments?: never;
31
32
  }
32
33
 
33
34
  interface SegmentedProgressByFillPercentProps extends SegmentedProgressBaseProps {
@@ -35,11 +36,33 @@ interface SegmentedProgressByFillPercentProps extends SegmentedProgressBaseProps
35
36
  value?: never;
36
37
  total?: never;
37
38
  displayNoLimit?: never;
39
+ segments?: never;
40
+ }
41
+
42
+ export interface SegmentedProgressSegment {
43
+ id: string;
44
+ value: number;
45
+ /** Minimum width in pixels. A positive value keeps zero-value segments visible. */
46
+ minWidth?: number;
47
+ color?: string;
48
+ className?: string;
49
+ dataQa?: string;
50
+ tooltip?: string;
51
+ ariaLabelledBy?: string;
52
+ }
53
+
54
+ interface SegmentedProgressBySegmentsProps extends SegmentedProgressBaseProps {
55
+ segments: SegmentedProgressSegment[];
56
+ total: number;
57
+ value?: never;
58
+ fillPercent?: never;
59
+ displayNoLimit?: never;
38
60
  }
39
61
 
40
62
  export type SegmentedProgressProps =
41
63
  | SegmentedProgressByValueProps
42
- | SegmentedProgressByFillPercentProps;
64
+ | SegmentedProgressByFillPercentProps
65
+ | SegmentedProgressBySegmentsProps;
43
66
 
44
67
  function clampPercent(percent: number) {
45
68
  if (!Number.isFinite(percent) || percent <= 0) {
@@ -51,7 +74,7 @@ function clampPercent(percent: number) {
51
74
  return percent;
52
75
  }
53
76
 
54
- function defaultNormalizePercent(percent: number) {
77
+ export function defaultNormalizePercent(percent: number) {
55
78
  if (percent < 1) {
56
79
  return Math.round(percent * 10) / 10;
57
80
  }
@@ -64,11 +87,25 @@ function isFillPercentMode(
64
87
  return typeof props.fillPercent === 'number';
65
88
  }
66
89
 
90
+ function isSegmentsMode(props: SegmentedProgressProps): props is SegmentedProgressBySegmentsProps {
91
+ return Array.isArray(props.segments);
92
+ }
93
+
67
94
  function getPercentUsed(props: SegmentedProgressProps) {
68
95
  if (isFillPercentMode(props)) {
69
96
  return props.fillPercent;
70
97
  }
71
98
 
99
+ if (isSegmentsMode(props)) {
100
+ if (props.total > 0) {
101
+ const value = props.segments.reduce((sum, segment) => sum + segment.value, 0);
102
+
103
+ return (value / props.total) * 100;
104
+ }
105
+
106
+ return 0;
107
+ }
108
+
72
109
  if (props.total > 0) {
73
110
  return (props.value / props.total) * 100;
74
111
  }
@@ -110,9 +147,57 @@ export function SegmentedProgress(props: SegmentedProgressProps) {
110
147
  [normalizePercent, percentUsed],
111
148
  );
112
149
  const fillWidth = getFillWidth(props, normalizedUsed);
113
-
114
- return (
115
- <Flex direction="column" gap={1}>
150
+ const segmentSections = isSegmentsMode(props)
151
+ ? props.segments.map((segment) => ({
152
+ ...segment,
153
+ width: props.total > 0 ? clampPercent((segment.value / props.total) * 100) : 0,
154
+ }))
155
+ : undefined;
156
+ const hasEmptySection = (segmentSections ? percentUsed : fillWidth) < 100;
157
+
158
+ const renderSections = () => {
159
+ if (segmentSections) {
160
+ return segmentSections
161
+ .filter((segment) => segment.width > 0 || (segment.minWidth ?? 0) > 0)
162
+ .map((segment) => {
163
+ const section = (
164
+ <div
165
+ key={segment.id}
166
+ aria-label={segment.tooltip}
167
+ aria-labelledby={segment.ariaLabelledBy}
168
+ className={b('section', {used: true}, segment.className)}
169
+ data-qa={segment.dataQa}
170
+ role={segment.tooltip ? 'img' : undefined}
171
+ style={{
172
+ width: `${segment.width}%`,
173
+ minWidth: segment.minWidth,
174
+ backgroundColor: segment.color,
175
+ }}
176
+ tabIndex={segment.tooltip ? 0 : undefined}
177
+ />
178
+ );
179
+
180
+ if (!segment.tooltip) {
181
+ return section;
182
+ }
183
+
184
+ return (
185
+ <Tooltip key={segment.id} content={segment.tooltip}>
186
+ {section}
187
+ </Tooltip>
188
+ );
189
+ });
190
+ }
191
+
192
+ if (fillWidth > 0) {
193
+ return <div className={b('section', {used: true})} style={{width: `${fillWidth}%`}} />;
194
+ }
195
+
196
+ return null;
197
+ };
198
+
199
+ const renderProgress = () => {
200
+ return (
116
201
  <div
117
202
  className={b({theme}, className)}
118
203
  data-qa={dataQa}
@@ -122,11 +207,15 @@ export function SegmentedProgress(props: SegmentedProgressProps) {
122
207
  aria-valuemax={100}
123
208
  aria-valuenow={normalizedUsed}
124
209
  >
125
- {fillWidth > 0 && (
126
- <div className={b('section', {used: true})} style={{width: `${fillWidth}%`}} />
127
- )}
128
- {100 - fillWidth > 0 && <div className={b('section')} style={{flexGrow: 1}} />}
210
+ {renderSections()}
211
+ {hasEmptySection && <div className={b('section')} style={{flexGrow: 1}} />}
129
212
  </div>
213
+ );
214
+ };
215
+
216
+ return (
217
+ <Flex direction="column" gap={1}>
218
+ {renderProgress()}
130
219
  {!hideLabels && (
131
220
  <Flex width="100%">
132
221
  {labelStart && <Text color="secondary">{labelStart}</Text>}
@@ -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 {useTypedSelector} from '../../utils/hooks';
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 = componentsRegistry.get('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 || Object.keys(groupStats).length === 0) {
114
+ if (loading || preparedGroupStats.disks.length === 0) {
110
115
  return null;
111
116
  }
112
117
  return (
113
- <InfoSection className={b('storage-section')}>
114
- <Text as="div" variant="subheader-2" className={b('section-title')}>
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
  );
@@ -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
+ }
@@ -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 {SegmentedProgress} from '../../../../../components/SegmentedProgress/SegmentedProgress';
6
- import type {
7
- ClusterGroupsStats,
8
- DiskErasureGroupsStats,
9
- } from '../../../../../store/reducers/cluster/types';
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
- interface GroupsStatsPopupContentProps {
14
- stats: DiskErasureGroupsStats;
15
- storageType: string;
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 DiskGroupStats({stats, storageType}: GroupsStatsPopupContentProps) {
19
- const {erasure} = stats;
34
+ function formatGroups(count: number) {
35
+ return i18n('value_groups', {
36
+ count,
37
+ formattedCount: formatNumber(count),
38
+ });
39
+ }
20
40
 
21
- const availableGroups = stats.totalGroups - stats.createdGroups;
41
+ function formatAvailableGroups({min, max}: PreparedDiskGroupsStats['availableGroups']) {
42
+ if (min === max) {
43
+ return formatGroups(min);
44
+ }
22
45
 
23
- const availableGroupsString =
24
- availableGroups === 1
25
- ? i18n('title_available-one')
26
- : i18n('title_available-other', {
27
- count: formatNumber(availableGroups),
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
- <Flex direction="column" gap={2}>
32
- <Flex justifyContent="space-between" alignItems="center">
33
- <Text variant="subheader-1">{storageType}</Text>
34
- <Flex gap={4} wrap="nowrap" alignItems="center">
35
- <Label theme="info">{availableGroupsString}</Label>
36
- <Text color="secondary">
37
- {i18n('title_allocated', {
38
- used: formatNumber(stats.createdGroups),
39
- total: formatNumber(stats.totalGroups),
40
- })}
41
- </Text>
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
- <SegmentedProgress
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
- groupStats: ClusterGroupsStats;
147
+ stats: PreparedClusterGroupsStats;
56
148
  }
57
149
 
58
- export function StorageGroupStats({groupStats}: StorageGroupStatsProps) {
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
- <Flex direction="column" gap={5}>
78
- {stats}
79
- </Flex>
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
- "title_allocated": "Allocated : {{used}} of {{total}} groups",
3
- "title_available-one": "Available : 1 group",
4
- "title_available-other": "Available : {{count}} groups",
5
- "context_storage-group-allocation-progress": "Storage group allocation progress",
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",