ydb-embedded-ui 22.4.0 → 22.6.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 (337) hide show
  1. package/dist/components/AutoRefreshControl/StickyAutoRefreshControl.d.ts +2 -0
  2. package/dist/components/AutoRefreshControl/StickyAutoRefreshControl.js +9 -0
  3. package/dist/components/AutoRefreshControl/StickyAutoRefreshControl.js.map +1 -0
  4. package/dist/components/AutoRefreshControl/StickyAutoRefreshControl.scss +18 -0
  5. package/dist/components/ButtonWithConfirmDialog/ButtonWithConfirmDialog.d.ts +3 -2
  6. package/dist/components/ButtonWithConfirmDialog/ButtonWithConfirmDialog.js +19 -4
  7. package/dist/components/ButtonWithConfirmDialog/ButtonWithConfirmDialog.js.map +1 -1
  8. package/dist/components/CopyableValue/CopyableValue.d.ts +10 -0
  9. package/dist/components/CopyableValue/CopyableValue.js +10 -0
  10. package/dist/components/CopyableValue/CopyableValue.js.map +1 -0
  11. package/dist/components/CopyableValue/CopyableValue.scss +16 -0
  12. package/dist/components/CopyableValue/i18n/en.json +3 -0
  13. package/dist/components/CopyableValue/i18n/index.d.ts +2 -0
  14. package/dist/components/CopyableValue/i18n/index.js +6 -0
  15. package/dist/components/CopyableValue/i18n/index.js.map +1 -0
  16. package/dist/components/CriticalActionDialog/CriticalActionDialog.d.ts +2 -1
  17. package/dist/components/CriticalActionDialog/CriticalActionDialog.js +2 -1
  18. package/dist/components/CriticalActionDialog/CriticalActionDialog.js.map +1 -1
  19. package/dist/components/DiskCapacityInfo/DiskCapacityInfo.d.ts +1 -21
  20. package/dist/components/DiskCapacityInfo/DiskCapacityInfo.js +40 -126
  21. package/dist/components/DiskCapacityInfo/DiskCapacityInfo.js.map +1 -1
  22. package/dist/components/DiskCapacityInfo/i18n/en.json +0 -1
  23. package/dist/components/DiskCapacityInfo/i18n/index.d.ts +1 -1
  24. package/dist/components/EntityStatus/EntityStatus.d.ts +18 -6
  25. package/dist/components/EntityStatus/EntityStatus.js +5 -1
  26. package/dist/components/EntityStatus/EntityStatus.js.map +1 -1
  27. package/dist/components/EntityStatus/EntityStatus.scss +5 -0
  28. package/dist/components/EvictVDiskButton/EvictVDiskButton.d.ts +5 -2
  29. package/dist/components/EvictVDiskButton/EvictVDiskButton.js +3 -2
  30. package/dist/components/EvictVDiskButton/EvictVDiskButton.js.map +1 -1
  31. package/dist/components/EvictVDiskButton/i18n/en.json +2 -2
  32. package/dist/components/FullNodeViewer/FullNodeViewer.js +4 -7
  33. package/dist/components/FullNodeViewer/FullNodeViewer.js.map +1 -1
  34. package/dist/components/FullNodeViewer/i18n/index.d.ts +1 -1
  35. package/dist/components/HideUnavailableNodesSwitch/HideUnavailableNodesSwitch.d.ts +3 -0
  36. package/dist/components/HideUnavailableNodesSwitch/HideUnavailableNodesSwitch.js +12 -0
  37. package/dist/components/HideUnavailableNodesSwitch/HideUnavailableNodesSwitch.js.map +1 -0
  38. package/dist/components/HideUnavailableNodesSwitch/i18n/en.json +3 -0
  39. package/dist/components/HideUnavailableNodesSwitch/i18n/index.d.ts +2 -0
  40. package/dist/components/HideUnavailableNodesSwitch/i18n/index.js +6 -0
  41. package/dist/components/HideUnavailableNodesSwitch/i18n/index.js.map +1 -0
  42. package/dist/components/HideUnavailableNodesSwitch/i18n/ru.json +3 -0
  43. package/dist/components/HoverPopup/HoverPopup.d.ts +1 -0
  44. package/dist/components/HoverPopup/HoverPopup.js +87 -16
  45. package/dist/components/HoverPopup/HoverPopup.js.map +1 -1
  46. package/dist/components/MemoryViewer/MemoryViewer.d.ts +3 -1
  47. package/dist/components/MemoryViewer/MemoryViewer.js +25 -16
  48. package/dist/components/MemoryViewer/MemoryViewer.js.map +1 -1
  49. package/dist/components/MemoryViewer/i18n/en.json +4 -3
  50. package/dist/components/MemoryViewer/i18n/index.d.ts +1 -1
  51. package/dist/components/MemoryViewer/utils.d.ts +4 -2
  52. package/dist/components/MemoryViewer/utils.js +11 -11
  53. package/dist/components/MemoryViewer/utils.js.map +1 -1
  54. package/dist/components/PDiskInfo/PDiskInfo.d.ts +4 -9
  55. package/dist/components/PDiskInfo/PDiskInfo.js +32 -144
  56. package/dist/components/PDiskInfo/PDiskInfo.js.map +1 -1
  57. package/dist/components/PDiskInfo/PDiskInfo.scss +15 -0
  58. package/dist/components/PDiskInfo/PDiskLogSize.js +1 -1
  59. package/dist/components/PDiskInfo/PDiskLogSize.js.map +1 -1
  60. package/dist/components/PDiskInfo/i18n/en.json +6 -3
  61. package/dist/components/PDiskInfo/i18n/index.d.ts +1 -1
  62. package/dist/components/PDiskInfo/statuses.js +12 -3
  63. package/dist/components/PDiskInfo/statuses.js.map +1 -1
  64. package/dist/components/PageMeta/PageMeta.d.ts +0 -2
  65. package/dist/components/PageMeta/PageMeta.js +1 -6
  66. package/dist/components/PageMeta/PageMeta.js.map +1 -1
  67. package/dist/components/Search/Search.js +3 -1
  68. package/dist/components/Search/Search.js.map +1 -1
  69. package/dist/components/StorageGroupInfo/StorageGroupInfo.js +4 -9
  70. package/dist/components/StorageGroupInfo/StorageGroupInfo.js.map +1 -1
  71. package/dist/components/StorageGroupInfo/i18n/index.d.ts +1 -1
  72. package/dist/components/TenantNameWrapper/i18n/index.d.ts +1 -1
  73. package/dist/components/VDisk/VDisk.js +2 -2
  74. package/dist/components/VDisk/VDisk.js.map +1 -1
  75. package/dist/components/VDiskInfo/VDiskInfo.d.ts +3 -7
  76. package/dist/components/VDiskInfo/VDiskInfo.js +57 -235
  77. package/dist/components/VDiskInfo/VDiskInfo.js.map +1 -1
  78. package/dist/components/VDiskInfo/VDiskInfo.scss +19 -3
  79. package/dist/components/VDiskInfo/getVDiskDetails.d.ts +7 -1
  80. package/dist/components/VDiskInfo/getVDiskDetails.js +14 -1
  81. package/dist/components/VDiskInfo/getVDiskDetails.js.map +1 -1
  82. package/dist/components/VDiskInfo/i18n/en.json +4 -13
  83. package/dist/components/VDiskInfo/i18n/index.d.ts +1 -1
  84. package/dist/components/VDiskPopup/VDiskPopup.d.ts +2 -1
  85. package/dist/components/VDiskPopup/VDiskPopup.js +10 -26
  86. package/dist/components/VDiskPopup/VDiskPopup.js.map +1 -1
  87. package/dist/components/VDiskPopup/i18n/en.json +0 -2
  88. package/dist/components/VDiskPopup/i18n/index.d.ts +1 -1
  89. package/dist/components/VDiskStatus/VDiskReplicationStatus.js +1 -1
  90. package/dist/components/VDiskStatus/VDiskReplicationStatus.js.map +1 -1
  91. package/dist/components/VDiskStatus/VDiskStatus.js +2 -2
  92. package/dist/components/VDiskStatus/VDiskStatus.js.map +1 -1
  93. package/dist/components/VDiskStatus/VDiskStatus.scss +4 -0
  94. package/dist/components/VDiskStatus/statuses.js +2 -2
  95. package/dist/components/VDiskStatus/statuses.js.map +1 -1
  96. package/dist/components/nodesColumns/columns.d.ts +1 -0
  97. package/dist/components/nodesColumns/columns.js +13 -6
  98. package/dist/components/nodesColumns/columns.js.map +1 -1
  99. package/dist/containers/Clusters/Clusters.js +35 -6
  100. package/dist/containers/Clusters/Clusters.js.map +1 -1
  101. package/dist/containers/Clusters/Clusters.scss +24 -6
  102. package/dist/containers/Clusters/columns.js +9 -4
  103. package/dist/containers/Clusters/columns.js.map +1 -1
  104. package/dist/containers/Clusters/i18n/en.json +6 -0
  105. package/dist/containers/Clusters/i18n/index.d.ts +1 -1
  106. package/dist/containers/Header/Header.js +8 -0
  107. package/dist/containers/Header/Header.js.map +1 -1
  108. package/dist/containers/Header/HeaderLeftControls.js +3 -1
  109. package/dist/containers/Header/HeaderLeftControls.js.map +1 -1
  110. package/dist/containers/Header/PDiskLeftControls.d.ts +1 -0
  111. package/dist/containers/Header/PDiskLeftControls.js +24 -0
  112. package/dist/containers/Header/PDiskLeftControls.js.map +1 -0
  113. package/dist/containers/Header/VDiskLeftControls.d.ts +1 -0
  114. package/dist/containers/Header/VDiskLeftControls.js +23 -0
  115. package/dist/containers/Header/VDiskLeftControls.js.map +1 -0
  116. package/dist/containers/Header/breadcrumbs.js +5 -2
  117. package/dist/containers/Header/breadcrumbs.js.map +1 -1
  118. package/dist/containers/Header/i18n/en.json +4 -1
  119. package/dist/containers/Header/i18n/index.d.ts +1 -1
  120. package/dist/containers/Node/Node.js +4 -3
  121. package/dist/containers/Node/Node.js.map +1 -1
  122. package/dist/containers/Node/Node.scss +14 -2
  123. package/dist/containers/Nodes/NodesControls/NodesControls.js +2 -1
  124. package/dist/containers/Nodes/NodesControls/NodesControls.js.map +1 -1
  125. package/dist/containers/Nodes/NodesTable.js +4 -0
  126. package/dist/containers/Nodes/NodesTable.js.map +1 -1
  127. package/dist/containers/Nodes/PaginatedNodes/GroupedNodesComponent.js +8 -3
  128. package/dist/containers/Nodes/PaginatedNodes/GroupedNodesComponent.js.map +1 -1
  129. package/dist/containers/Nodes/PaginatedNodes/NodesComponent.js +12 -2
  130. package/dist/containers/Nodes/PaginatedNodes/NodesComponent.js.map +1 -1
  131. package/dist/containers/Nodes/getNodes.js +2 -1
  132. package/dist/containers/Nodes/getNodes.js.map +1 -1
  133. package/dist/containers/Nodes/useDebouncedSearch.d.ts +2 -0
  134. package/dist/containers/Nodes/useDebouncedSearch.js +11 -0
  135. package/dist/containers/Nodes/useDebouncedSearch.js.map +1 -0
  136. package/dist/containers/PDiskPage/PDiskPage.js +24 -34
  137. package/dist/containers/PDiskPage/PDiskPage.js.map +1 -1
  138. package/dist/containers/PDiskPage/PDiskPage.scss +29 -11
  139. package/dist/containers/PDiskPage/PDiskSpaceDistribution/PDiskSpaceDistribution.js +3 -3
  140. package/dist/containers/PDiskPage/PDiskSpaceDistribution/PDiskSpaceDistribution.js.map +1 -1
  141. package/dist/containers/PDiskPage/PDiskStorageDetails.d.ts +6 -0
  142. package/dist/containers/PDiskPage/PDiskStorageDetails.js +28 -0
  143. package/dist/containers/PDiskPage/PDiskStorageDetails.js.map +1 -0
  144. package/dist/containers/PDiskPage/PDiskStorageDetails.scss +51 -0
  145. package/dist/containers/PDiskPage/i18n/en.json +1 -0
  146. package/dist/containers/PDiskPage/i18n/index.d.ts +1 -1
  147. package/dist/containers/Storage/PaginatedStorageGroupsTable/columns/i18n/index.d.ts +1 -1
  148. package/dist/containers/Storage/PaginatedStorageNodes/GroupedStorageNodesComponent.js +3 -0
  149. package/dist/containers/Storage/PaginatedStorageNodes/GroupedStorageNodesComponent.js.map +1 -1
  150. package/dist/containers/Storage/PaginatedStorageNodes/StorageNodesComponent.js +8 -1
  151. package/dist/containers/Storage/PaginatedStorageNodes/StorageNodesComponent.js.map +1 -1
  152. package/dist/containers/Storage/PaginatedStorageNodes/StorageNodesControls.js +2 -1
  153. package/dist/containers/Storage/PaginatedStorageNodes/StorageNodesControls.js.map +1 -1
  154. package/dist/containers/Storage/PaginatedStorageNodesTable/PaginatedStorageNodesTable.js +4 -0
  155. package/dist/containers/Storage/PaginatedStorageNodesTable/PaginatedStorageNodesTable.js.map +1 -1
  156. package/dist/containers/Storage/PaginatedStorageNodesTable/getNodes.js +2 -1
  157. package/dist/containers/Storage/PaginatedStorageNodesTable/getNodes.js.map +1 -1
  158. package/dist/containers/Storage/Storage.scss +4 -0
  159. package/dist/containers/Storage/StorageExpertModePanel/constants.d.ts +1 -1
  160. package/dist/containers/Storage/StorageExpertModePanel/i18n/index.d.ts +1 -1
  161. package/dist/containers/Storage/useStorageQueryParams.d.ts +4 -4
  162. package/dist/containers/StorageGroupPage/StorageGroupPage.js +5 -14
  163. package/dist/containers/StorageGroupPage/StorageGroupPage.js.map +1 -1
  164. package/dist/containers/StorageGroupPage/StorageGroupPage.scss +19 -4
  165. package/dist/containers/StorageGroupPage/i18n/en.json +0 -2
  166. package/dist/containers/StorageGroupPage/i18n/index.d.ts +1 -1
  167. package/dist/containers/Tablet/Tablet.js +3 -2
  168. package/dist/containers/Tablet/Tablet.js.map +1 -1
  169. package/dist/containers/Tablet/Tablet.scss +15 -1
  170. package/dist/containers/Tenant/Diagnostics/Overview/TableInfo/ManagePartitioningDialog/i18n/index.d.ts +1 -1
  171. package/dist/containers/Tenant/Diagnostics/TenantOverview/TenantOverview.js +5 -12
  172. package/dist/containers/Tenant/Diagnostics/TenantOverview/TenantOverview.js.map +1 -1
  173. package/dist/containers/Tenant/Diagnostics/TopQueries/columns/i18n/index.d.ts +1 -1
  174. package/dist/containers/Tenant/Healthcheck/Healthcheck.scss +6 -1
  175. package/dist/containers/Tenant/Healthcheck/components/HealthcheckIssue.js +2 -2
  176. package/dist/containers/Tenant/Healthcheck/components/HealthcheckIssue.js.map +1 -1
  177. package/dist/containers/Tenant/TenantDrawerHealthcheck.js +10 -2
  178. package/dist/containers/Tenant/TenantDrawerHealthcheck.js.map +1 -1
  179. package/dist/containers/VDiskPage/VDiskPage.js +27 -36
  180. package/dist/containers/VDiskPage/VDiskPage.js.map +1 -1
  181. package/dist/containers/VDiskPage/VDiskPage.scss +39 -7
  182. package/dist/containers/VDiskPage/VDiskStorageDetails.js +27 -29
  183. package/dist/containers/VDiskPage/VDiskStorageDetails.js.map +1 -1
  184. package/dist/containers/VDiskPage/VDiskStorageDetails.scss +24 -93
  185. package/dist/containers/VDiskPage/i18n/en.json +2 -12
  186. package/dist/containers/VDiskPage/i18n/index.d.ts +1 -1
  187. package/dist/store/reducers/capabilities/hooks.d.ts +1 -0
  188. package/dist/store/reducers/capabilities/hooks.js +3 -0
  189. package/dist/store/reducers/capabilities/hooks.js.map +1 -1
  190. package/dist/store/reducers/cluster/parseFields.js +1 -0
  191. package/dist/store/reducers/cluster/parseFields.js.map +1 -1
  192. package/dist/store/reducers/clusters/clusters.js +1 -0
  193. package/dist/store/reducers/clusters/clusters.js.map +1 -1
  194. package/dist/store/reducers/clusters/selectors.d.ts +1 -0
  195. package/dist/store/reducers/clusters/selectors.js +4 -1
  196. package/dist/store/reducers/clusters/selectors.js.map +1 -1
  197. package/dist/store/reducers/clusters/types.d.ts +2 -0
  198. package/dist/store/reducers/nodes/types.d.ts +1 -0
  199. package/dist/store/reducers/storage/prepareGroupsDisks.d.ts +1 -1
  200. package/dist/store/reducers/storage/prepareGroupsDisks.js +2 -1
  201. package/dist/store/reducers/storage/prepareGroupsDisks.js.map +1 -1
  202. package/dist/store/reducers/storage/types.d.ts +1 -0
  203. package/dist/store/reducers/storage/utils.js +10 -3
  204. package/dist/store/reducers/storage/utils.js.map +1 -1
  205. package/dist/store/reducers/vdisk/types.d.ts +1 -1
  206. package/dist/store/reducers/vdisk/utils.js +5 -5
  207. package/dist/store/reducers/vdisk/utils.js.map +1 -1
  208. package/dist/types/api/capabilities.d.ts +1 -1
  209. package/dist/types/api/meta.d.ts +1 -0
  210. package/dist/types/api/nodes.d.ts +2 -0
  211. package/dist/types/api/nodesList.d.ts +2 -0
  212. package/dist/utils/hooks/useDatabaseHealthcheckAvailable.d.ts +2 -0
  213. package/dist/utils/hooks/useDatabaseHealthcheckAvailable.js +6 -0
  214. package/dist/utils/hooks/useDatabaseHealthcheckAvailable.js.map +1 -0
  215. package/dist/utils/hooks/useHideUnavailableNodes.d.ts +5 -0
  216. package/dist/utils/hooks/useHideUnavailableNodes.js +21 -0
  217. package/dist/utils/hooks/useHideUnavailableNodes.js.map +1 -0
  218. package/dist/utils/memory.d.ts +5 -0
  219. package/dist/utils/memory.js +9 -0
  220. package/dist/utils/memory.js.map +1 -0
  221. package/dist/utils/nodes.js +3 -3
  222. package/dist/utils/nodes.js.map +1 -1
  223. package/dist/utils/storageMetrics.d.ts +1 -0
  224. package/dist/utils/storageMetrics.js +8 -0
  225. package/dist/utils/storageMetrics.js.map +1 -1
  226. package/package.json +1 -1
  227. package/src/components/AutoRefreshControl/StickyAutoRefreshControl.scss +18 -0
  228. package/src/components/AutoRefreshControl/StickyAutoRefreshControl.tsx +15 -0
  229. package/src/components/ButtonWithConfirmDialog/ButtonWithConfirmDialog.tsx +22 -3
  230. package/src/components/CopyableValue/CopyableValue.scss +16 -0
  231. package/src/components/CopyableValue/CopyableValue.tsx +40 -0
  232. package/src/components/CopyableValue/i18n/en.json +3 -0
  233. package/src/components/CopyableValue/i18n/index.ts +8 -0
  234. package/src/components/CriticalActionDialog/CriticalActionDialog.tsx +3 -0
  235. package/src/components/DiskCapacityInfo/DiskCapacityInfo.tsx +40 -185
  236. package/src/components/DiskCapacityInfo/i18n/en.json +0 -1
  237. package/src/components/EntityStatus/EntityStatus.scss +5 -0
  238. package/src/components/EntityStatus/EntityStatus.tsx +38 -5
  239. package/src/components/EvictVDiskButton/EvictVDiskButton.tsx +10 -2
  240. package/src/components/EvictVDiskButton/i18n/en.json +2 -2
  241. package/src/components/FullNodeViewer/FullNodeViewer.tsx +4 -9
  242. package/src/components/HideUnavailableNodesSwitch/HideUnavailableNodesSwitch.tsx +24 -0
  243. package/src/components/HideUnavailableNodesSwitch/i18n/en.json +3 -0
  244. package/src/components/HideUnavailableNodesSwitch/i18n/index.ts +7 -0
  245. package/src/components/HideUnavailableNodesSwitch/i18n/ru.json +3 -0
  246. package/src/components/HoverPopup/HoverPopup.tsx +95 -19
  247. package/src/components/MemoryViewer/MemoryViewer.tsx +30 -17
  248. package/src/components/MemoryViewer/i18n/en.json +4 -3
  249. package/src/components/MemoryViewer/utils.ts +19 -12
  250. package/src/components/PDiskInfo/PDiskInfo.scss +15 -0
  251. package/src/components/PDiskInfo/PDiskInfo.tsx +51 -243
  252. package/src/components/PDiskInfo/PDiskLogSize.tsx +12 -8
  253. package/src/components/PDiskInfo/i18n/en.json +6 -3
  254. package/src/components/PDiskInfo/statuses.ts +16 -3
  255. package/src/components/PageMeta/PageMeta.tsx +0 -18
  256. package/src/components/Search/Search.tsx +5 -2
  257. package/src/components/StorageGroupInfo/StorageGroupInfo.tsx +8 -13
  258. package/src/components/VDisk/VDisk.tsx +3 -2
  259. package/src/components/VDiskInfo/VDiskInfo.scss +19 -3
  260. package/src/components/VDiskInfo/VDiskInfo.tsx +119 -341
  261. package/src/components/VDiskInfo/getVDiskDetails.tsx +24 -2
  262. package/src/components/VDiskInfo/i18n/en.json +4 -13
  263. package/src/components/VDiskPopup/VDiskPopup.tsx +16 -24
  264. package/src/components/VDiskPopup/i18n/en.json +0 -2
  265. package/src/components/VDiskStatus/VDiskReplicationStatus.tsx +1 -1
  266. package/src/components/VDiskStatus/VDiskStatus.scss +4 -0
  267. package/src/components/VDiskStatus/VDiskStatus.tsx +13 -2
  268. package/src/components/VDiskStatus/statuses.ts +2 -2
  269. package/src/components/nodesColumns/columns.tsx +26 -12
  270. package/src/containers/Clusters/Clusters.scss +24 -6
  271. package/src/containers/Clusters/Clusters.tsx +74 -5
  272. package/src/containers/Clusters/columns.tsx +36 -6
  273. package/src/containers/Clusters/i18n/en.json +6 -0
  274. package/src/containers/Header/Header.tsx +8 -0
  275. package/src/containers/Header/HeaderLeftControls.tsx +3 -1
  276. package/src/containers/Header/PDiskLeftControls.tsx +41 -0
  277. package/src/containers/Header/VDiskLeftControls.tsx +40 -0
  278. package/src/containers/Header/breadcrumbs.tsx +4 -2
  279. package/src/containers/Header/i18n/en.json +4 -1
  280. package/src/containers/Node/Node.scss +14 -2
  281. package/src/containers/Node/Node.tsx +6 -6
  282. package/src/containers/Nodes/NodesControls/NodesControls.tsx +3 -0
  283. package/src/containers/Nodes/NodesTable.tsx +4 -0
  284. package/src/containers/Nodes/PaginatedNodes/GroupedNodesComponent.tsx +8 -3
  285. package/src/containers/Nodes/PaginatedNodes/NodesComponent.tsx +12 -2
  286. package/src/containers/Nodes/getNodes.ts +2 -0
  287. package/src/containers/Nodes/useDebouncedSearch.ts +13 -0
  288. package/src/containers/PDiskPage/PDiskPage.scss +29 -11
  289. package/src/containers/PDiskPage/PDiskPage.tsx +69 -63
  290. package/src/containers/PDiskPage/PDiskSpaceDistribution/PDiskSpaceDistribution.tsx +3 -9
  291. package/src/containers/PDiskPage/PDiskStorageDetails.scss +51 -0
  292. package/src/containers/PDiskPage/PDiskStorageDetails.tsx +64 -0
  293. package/src/containers/PDiskPage/i18n/en.json +1 -0
  294. package/src/containers/Storage/PaginatedStorageNodes/GroupedStorageNodesComponent.tsx +3 -0
  295. package/src/containers/Storage/PaginatedStorageNodes/StorageNodesComponent.tsx +8 -1
  296. package/src/containers/Storage/PaginatedStorageNodes/StorageNodesControls.tsx +2 -0
  297. package/src/containers/Storage/PaginatedStorageNodesTable/PaginatedStorageNodesTable.tsx +4 -0
  298. package/src/containers/Storage/PaginatedStorageNodesTable/getNodes.ts +2 -0
  299. package/src/containers/Storage/Storage.scss +4 -0
  300. package/src/containers/StorageGroupPage/StorageGroupPage.scss +19 -4
  301. package/src/containers/StorageGroupPage/StorageGroupPage.tsx +25 -45
  302. package/src/containers/StorageGroupPage/i18n/en.json +0 -2
  303. package/src/containers/Tablet/Tablet.scss +15 -1
  304. package/src/containers/Tablet/Tablet.tsx +21 -15
  305. package/src/containers/Tenant/Diagnostics/TenantOverview/TenantOverview.tsx +5 -32
  306. package/src/containers/Tenant/Healthcheck/Healthcheck.scss +6 -1
  307. package/src/containers/Tenant/Healthcheck/components/HealthcheckIssue.tsx +18 -8
  308. package/src/containers/Tenant/TenantDrawerHealthcheck.tsx +14 -1
  309. package/src/containers/VDiskPage/VDiskPage.scss +39 -7
  310. package/src/containers/VDiskPage/VDiskPage.tsx +84 -72
  311. package/src/containers/VDiskPage/VDiskStorageDetails.scss +24 -93
  312. package/src/containers/VDiskPage/VDiskStorageDetails.tsx +50 -158
  313. package/src/containers/VDiskPage/i18n/en.json +2 -14
  314. package/src/store/reducers/capabilities/hooks.ts +4 -0
  315. package/src/store/reducers/cluster/parseFields.ts +1 -0
  316. package/src/store/reducers/clusters/clusters.ts +1 -0
  317. package/src/store/reducers/clusters/selectors.ts +4 -0
  318. package/src/store/reducers/clusters/types.ts +3 -0
  319. package/src/store/reducers/nodes/types.ts +1 -0
  320. package/src/store/reducers/storage/prepareGroupsDisks.ts +2 -0
  321. package/src/store/reducers/storage/types.ts +1 -0
  322. package/src/store/reducers/storage/utils.ts +13 -3
  323. package/src/store/reducers/vdisk/types.ts +2 -1
  324. package/src/store/reducers/vdisk/utils.ts +4 -5
  325. package/src/types/api/capabilities.ts +1 -0
  326. package/src/types/api/meta.ts +1 -0
  327. package/src/types/api/nodes.ts +2 -0
  328. package/src/types/api/nodesList.ts +3 -0
  329. package/src/utils/hooks/useDatabaseHealthcheckAvailable.ts +9 -0
  330. package/src/utils/hooks/useHideUnavailableNodes.ts +33 -0
  331. package/src/utils/memory.ts +16 -0
  332. package/src/utils/nodes.ts +3 -2
  333. package/src/utils/storageMetrics.ts +11 -0
  334. package/dist/components/VDiskInfo/getVDiskCapacityColumns.d.ts +0 -11
  335. package/dist/components/VDiskInfo/getVDiskCapacityColumns.js +0 -52
  336. package/dist/components/VDiskInfo/getVDiskCapacityColumns.js.map +0 -1
  337. package/src/components/VDiskInfo/getVDiskCapacityColumns.tsx +0 -83
@@ -44,31 +44,64 @@ const EFlagToStatusName: Record<EFlag, string> = {
44
44
  },
45
45
  };
46
46
 
47
- interface EntityStatusLabelProps {
47
+ interface EntityStatusLabelBaseProps {
48
48
  status: EFlag;
49
+ className?: string;
50
+ size?: LabelProps['size'];
51
+ iconSize?: number;
52
+ qa?: string;
53
+ }
54
+
55
+ interface DefaultEntityStatusLabelProps {
56
+ view?: 'default';
49
57
  note?: React.ReactNode;
50
58
  children?: React.ReactNode;
51
- className?: string;
52
59
  endContent?: React.ReactNode;
53
60
  withStatusName?: boolean;
54
- size?: LabelProps['size'];
55
- iconSize?: number;
56
61
  onClick?: (event: React.MouseEvent<HTMLElement>) => void;
57
- qa?: string;
58
62
  }
59
63
 
64
+ interface CompactEntityStatusLabelProps {
65
+ view: 'compact';
66
+ note?: never;
67
+ children?: never;
68
+ endContent?: never;
69
+ withStatusName?: never;
70
+ onClick?: never;
71
+ }
72
+
73
+ type EntityStatusLabelProps = EntityStatusLabelBaseProps &
74
+ (DefaultEntityStatusLabelProps | CompactEntityStatusLabelProps);
75
+
60
76
  function EntityStatusLabel({
61
77
  children,
62
78
  className,
63
79
  endContent,
64
80
  status,
65
81
  withStatusName = true,
82
+ view = 'default',
66
83
  note,
67
84
  size = 'm',
68
85
  iconSize = 14,
69
86
  onClick,
70
87
  qa,
71
88
  }: EntityStatusLabelProps) {
89
+ if (view === 'compact') {
90
+ const statusName = EFlagToStatusName[status];
91
+ return (
92
+ <ActionTooltip title={statusName}>
93
+ <span className={b('compact')} role="img" aria-label={statusName}>
94
+ <Label
95
+ theme={status === EFlag.Blue ? 'info' : EFlagToLabelTheme[status]}
96
+ icon={<StatusIcon size={iconSize} status={status} />}
97
+ size={size}
98
+ className={b(null, className)}
99
+ qa={qa}
100
+ />
101
+ </span>
102
+ </ActionTooltip>
103
+ );
104
+ }
72
105
  const theme = EFlagToLabelTheme[status];
73
106
  const isClickable = Boolean(onClick);
74
107
  return (
@@ -2,6 +2,7 @@ import React from 'react';
2
2
 
3
3
  import {ArrowsOppositeToDots} from '@gravity-ui/icons';
4
4
  import {Icon} from '@gravity-ui/uikit';
5
+ import type {ButtonProps} from '@gravity-ui/uikit';
5
6
  import {isNil} from 'lodash';
6
7
 
7
8
  import {
@@ -10,6 +11,7 @@ import {
10
11
  } from '../../store/reducers/capabilities/hooks';
11
12
  import type {ModifyDiskResponse} from '../../types/api/modifyDisk';
12
13
  import type {TVDiskID} from '../../types/api/vdisk';
14
+ import {BRAND_BUTTON_CLASS} from '../../utils/constants';
13
15
  import {useIsUserAllowedToMakeChanges} from '../../utils/hooks/useIsUserAllowedToMakeChanges';
14
16
  import {ButtonWithConfirmDialog} from '../ButtonWithConfirmDialog/ButtonWithConfirmDialog';
15
17
 
@@ -19,7 +21,9 @@ interface EvictVDiskButtonProps {
19
21
  vDiskId: Required<TVDiskID>;
20
22
  donorMode?: boolean;
21
23
  fullWidth?: boolean;
22
- onSuccess?: () => void;
24
+ view?: ButtonProps['view'];
25
+ onSuccess?: (isDialogOpen: boolean) => void;
26
+ onDialogOpen?: () => VoidFunction;
23
27
  }
24
28
 
25
29
  export function isAllVdiskParamsDefined(vDiskId?: TVDiskID): vDiskId is Required<TVDiskID> {
@@ -36,7 +40,9 @@ export const EvictVDiskButton = ({
36
40
  vDiskId,
37
41
  donorMode,
38
42
  fullWidth,
43
+ view = 'normal',
39
44
  onSuccess,
45
+ onDialogOpen,
40
46
  }: EvictVDiskButtonProps) => {
41
47
  const isUserAllowedToMakeChanges = useIsUserAllowedToMakeChanges();
42
48
  const newDiskApiAvailable = useDiskPagesAvailable();
@@ -79,8 +85,10 @@ export const EvictVDiskButton = ({
79
85
  <ButtonWithConfirmDialog
80
86
  onConfirmAction={handleEvictVDisk}
81
87
  onConfirmActionSuccess={onSuccess}
88
+ onDialogOpen={onDialogOpen}
82
89
  buttonDisabled={!isUserAllowedToMakeChanges || donorMode}
83
- buttonView="normal"
90
+ buttonView={view}
91
+ buttonClassName={view === 'action' ? BRAND_BUTTON_CLASS : undefined}
84
92
  buttonWidth={fullWidth ? 'max' : undefined}
85
93
  dialogHeader={evictVDiskButtonKeyset('title_evict-dialog')}
86
94
  dialogText={evictVDiskButtonKeyset('confirm_evict')}
@@ -3,8 +3,8 @@
3
3
  "action_evict-short": "Evict",
4
4
  "action_force-evict": "Evict anyway",
5
5
  "title_evict-dialog": "Evict VDisk?",
6
- "confirm_evict": "The VDisk will be evicted from the PDisk. This VDisk will be replaced by a new one in the group. Data will be replicated to the new disk. The old VDisk will serve as a donor until replication is complete, and then it will be removed.",
7
- "alert_evict": "This operation cannot be cancelled.",
6
+ "confirm_evict": "The VDisk will be evicted from the PDisk.",
7
+ "alert_evict": "This VDisk will be replaced by a new one in the group. Data will be replicated to the new disk. The old VDisk will serve as\u00a0a\u00a0donor until replication is complete, and then it will be\u00a0removed.",
8
8
  "alert_not-allowed": "You don't have enough rights to evict VDisk",
9
9
  "alert_donor-mode-impossible": "Evicting a donor VDisk is not possible"
10
10
  }
@@ -5,7 +5,7 @@ import {cn} from '../../utils/cn';
5
5
  import {EMPTY_DATA_PLACEHOLDER} from '../../utils/constants';
6
6
  import {formatStorageValues} from '../../utils/dataFormatters/dataFormatters';
7
7
  import {useNodeDeveloperUIHref} from '../../utils/hooks/useNodeDeveloperUIHref';
8
- import {isNumeric} from '../../utils/utils';
8
+ import {getNodeMemory} from '../../utils/memory';
9
9
  import {LinkWithIcon} from '../LinkWithIcon/LinkWithIcon';
10
10
  import {PoolUsage} from '../PoolUsage/PoolUsage';
11
11
  import {ProgressViewer} from '../ProgressViewer/ProgressViewer';
@@ -90,18 +90,13 @@ export const FullNodeViewer = ({node, className}: FullNodeViewerProps) => {
90
90
  return <div className="error">{i18n('no-data')}</div>;
91
91
  }
92
92
 
93
- const memoryUsed = isNumeric(node.MemoryUsed) ? Number(node.MemoryUsed) : undefined;
94
- const memoryLimit = isNumeric(node.MemoryLimit) ? Number(node.MemoryLimit) : undefined;
95
- const hasMemoryUsed =
96
- memoryUsed !== undefined && Number.isFinite(memoryUsed) && memoryUsed >= 0;
97
- const hasMemoryLimit =
98
- memoryLimit !== undefined && Number.isFinite(memoryLimit) && memoryLimit > 0;
93
+ const {memoryUsed, memoryLimit} = getNodeMemory(node);
99
94
 
100
95
  const renderMemory = () => {
101
- if (!hasMemoryUsed) {
96
+ if (memoryUsed === undefined) {
102
97
  return EMPTY_DATA_PLACEHOLDER;
103
98
  }
104
- if (!hasMemoryLimit) {
99
+ if (memoryLimit === undefined) {
105
100
  return formatMemoryValues(memoryUsed)[0];
106
101
  }
107
102
 
@@ -0,0 +1,24 @@
1
+ import {Switch} from '@gravity-ui/uikit';
2
+
3
+ import {useHideUnavailableNodes} from '../../utils/hooks/useHideUnavailableNodes';
4
+
5
+ import i18n from './i18n';
6
+
7
+ export function HideUnavailableNodesSwitch({className}: {className?: string}) {
8
+ const {available, hideUnavailable, handleHideUnavailableChange} = useHideUnavailableNodes();
9
+
10
+ if (!available) {
11
+ return null;
12
+ }
13
+
14
+ return (
15
+ <Switch
16
+ className={className}
17
+ size="m"
18
+ checked={hideUnavailable}
19
+ onUpdate={handleHideUnavailableChange}
20
+ content={i18n('action_hide-unavailable')}
21
+ qa="hide-unavailable-nodes"
22
+ />
23
+ );
24
+ }
@@ -0,0 +1,3 @@
1
+ {
2
+ "action_hide-unavailable": "Hide unavailable"
3
+ }
@@ -0,0 +1,7 @@
1
+ import {registerKeysets} from '../../../utils/i18n';
2
+
3
+ import en from './en.json';
4
+ import ru from './ru.json';
5
+
6
+ // Switch for excluding disconnected nodes from node lists.
7
+ export default registerKeysets('ydb-hide-unavailable-nodes-switch', {en, ru});
@@ -0,0 +1,3 @@
1
+ {
2
+ "action_hide-unavailable": "Скрыть недоступные"
3
+ }
@@ -44,7 +44,10 @@ function useVisibleAnchor(
44
44
 
45
45
  type HoverPopupProps = {
46
46
  children: React.ReactNode;
47
- renderPopupContent: (controls: {onClose: VoidFunction}) => React.ReactNode;
47
+ renderPopupContent: (controls: {
48
+ onClose: VoidFunction;
49
+ holdOpen: () => VoidFunction;
50
+ }) => React.ReactNode;
48
51
  showPopup?: boolean;
49
52
  anchorRef?: React.RefObject<HTMLElement>;
50
53
  onShowPopup?: VoidFunction;
@@ -72,8 +75,11 @@ export const HoverPopup = ({
72
75
  const [isPopupVisible, setIsPopupVisible] = React.useState(false);
73
76
  const [isPopupContentHovered, setIsPopupContentHovered] = React.useState(false);
74
77
  const [isFocused, setIsFocused] = React.useState(false);
78
+ const [hoverClosing, setHoverClosing] = React.useState(false);
79
+ const dialogHoldRef = React.useRef<object | null>(null);
75
80
 
76
81
  const anchor = React.useRef<HTMLSpanElement>(null);
82
+ const popupContent = React.useRef<HTMLDivElement>(null);
77
83
  const {activate, zIndex} = usePopupPriority();
78
84
  const bringToFront = useEventHandler(() => activate(anchorRef?.current || anchor.current));
79
85
 
@@ -102,32 +108,36 @@ export const HoverPopup = ({
102
108
  [delayOpen, reportOpen],
103
109
  );
104
110
 
105
- const hidePopup = React.useCallback(() => {
111
+ const hidePopup = useEventHandler(() => {
112
+ if (dialogHoldRef.current || isFocused) {
113
+ return;
114
+ }
115
+ setHoverClosing(open && visibleAnchorRef.current === anchorElement);
106
116
  setIsPopupVisible(false);
107
- }, []);
117
+ reportOpen(false);
118
+ });
108
119
 
109
120
  const debouncedHandleHidePopup = React.useMemo(
110
- () =>
111
- debounce(() => {
112
- hidePopup();
113
- reportOpen(false);
114
- }, delayClose),
115
- [delayClose, reportOpen, hidePopup],
121
+ () => debounce(hidePopup, delayClose),
122
+ [delayClose, hidePopup],
116
123
  );
117
124
 
118
125
  React.useEffect(() => {
119
126
  return () => {
120
127
  debouncedHandleShowPopup.cancel();
121
128
  debouncedHandleHidePopup.cancel();
129
+ dialogHoldRef.current = null;
122
130
  };
123
131
  }, [debouncedHandleShowPopup, debouncedHandleHidePopup]);
124
132
 
125
133
  const closePopup = React.useCallback(() => {
126
134
  debouncedHandleShowPopup.cancel();
127
135
  debouncedHandleHidePopup.cancel();
136
+ dialogHoldRef.current = null;
128
137
  setIsPopupVisible(false);
129
138
  setIsPopupContentHovered(false);
130
139
  setIsFocused(false);
140
+ setHoverClosing(false);
131
141
  reportOpen(false, true);
132
142
  onClosePopup?.();
133
143
  }, [debouncedHandleHidePopup, debouncedHandleShowPopup, onClosePopup, reportOpen]);
@@ -136,6 +146,7 @@ export const HoverPopup = ({
136
146
  debouncedHandleShowPopup.cancel();
137
147
  setIsPopupContentHovered(false);
138
148
  setIsFocused(false);
149
+ setHoverClosing(false);
139
150
  debouncedHandleHidePopup();
140
151
  });
141
152
 
@@ -146,11 +157,59 @@ export const HoverPopup = ({
146
157
  // Release only this popup's hover source; a hovered peer can keep the pair open.
147
158
  const [isAnchorVisible, visibleAnchorRef] = useVisibleAnchor(
148
159
  anchorElement,
149
- open,
160
+ open || hoverClosing,
150
161
  hideClippedPopup,
151
162
  );
152
163
  const container = getPopupScrollContainer(anchorElement);
153
164
 
165
+ React.useEffect(() => {
166
+ if (!hoverClosing || !anchorElement) {
167
+ return undefined;
168
+ }
169
+ // Escape may close this popup through its paired sibling's handler.
170
+ const preventHoverReturn = (event: KeyboardEvent) => {
171
+ if (event.key === 'Escape') {
172
+ setHoverClosing(false);
173
+ }
174
+ };
175
+ const doc = anchorElement.ownerDocument;
176
+ doc.addEventListener('keydown', preventHoverReturn, true);
177
+ return () => doc.removeEventListener('keydown', preventHoverReturn, true);
178
+ }, [anchorElement, hoverClosing]);
179
+
180
+ const resumeHover = useEventHandler(() => {
181
+ const contentHovered = Boolean(popupContent.current?.matches(':hover'));
182
+ const hovered =
183
+ visibleAnchorRef.current === anchorElement &&
184
+ (anchorElement?.matches(':hover') || contentHovered);
185
+ debouncedHandleShowPopup.cancel();
186
+ debouncedHandleHidePopup.cancel();
187
+ setIsFocused(false);
188
+ setIsPopupContentHovered(Boolean(hovered && contentHovered));
189
+ if (hovered) {
190
+ setIsPopupVisible(true);
191
+ reportOpen(true);
192
+ } else {
193
+ debouncedHandleHidePopup();
194
+ }
195
+ });
196
+
197
+ const holdOpen = () => {
198
+ const interaction = {};
199
+ dialogHoldRef.current = interaction;
200
+ debouncedHandleShowPopup.cancel();
201
+ debouncedHandleHidePopup.cancel();
202
+ setIsFocused(false);
203
+ setIsPopupVisible(true);
204
+ reportOpen(true);
205
+ return () => {
206
+ if (dialogHoldRef.current === interaction) {
207
+ dialogHoldRef.current = null;
208
+ resumeHover();
209
+ }
210
+ };
211
+ };
212
+
154
213
  const onMouseEnter = (event: React.MouseEvent<HTMLSpanElement>) => {
155
214
  if (event.buttons !== 0) {
156
215
  return;
@@ -167,18 +226,27 @@ export const HoverPopup = ({
167
226
 
168
227
  const onPopupMouseEnter = React.useCallback(
169
228
  (event: React.MouseEvent<HTMLDivElement>) => {
170
- // An exiting popup can still receive events during its close animation.
171
- if (!open || visibleAnchorRef.current !== anchorElement) {
229
+ if ((!open && !hoverClosing) || visibleAnchorRef.current !== anchorElement) {
172
230
  return;
173
231
  }
174
232
  if (event.buttons === 0) {
175
233
  bringToFront();
176
234
  }
177
235
  debouncedHandleHidePopup.cancel();
236
+ setHoverClosing(false);
237
+ setIsPopupVisible(true);
178
238
  setIsPopupContentHovered(true);
179
239
  reportOpen(true);
180
240
  },
181
- [bringToFront, reportOpen, debouncedHandleHidePopup, open, visibleAnchorRef, anchorElement],
241
+ [
242
+ bringToFront,
243
+ reportOpen,
244
+ debouncedHandleHidePopup,
245
+ open,
246
+ hoverClosing,
247
+ visibleAnchorRef,
248
+ anchorElement,
249
+ ],
182
250
  );
183
251
 
184
252
  const onPopupMouseLeave = React.useCallback(() => {
@@ -187,7 +255,7 @@ export const HoverPopup = ({
187
255
  }, [debouncedHandleHidePopup]);
188
256
 
189
257
  const onPopupContextMenu = React.useCallback(() => {
190
- if (!open || visibleAnchorRef.current !== anchorElement) {
258
+ if (dialogHoldRef.current || !open || visibleAnchorRef.current !== anchorElement) {
191
259
  return;
192
260
  }
193
261
  bringToFront();
@@ -195,12 +263,16 @@ export const HoverPopup = ({
195
263
  reportOpen(true);
196
264
  }, [bringToFront, reportOpen, open, visibleAnchorRef, anchorElement]);
197
265
 
198
- const onPopupBlur = React.useCallback(() => {
199
- setIsFocused(false);
200
- }, []);
266
+ const onPopupBlur = useEventHandler(() => {
267
+ if (isFocused && !dialogHoldRef.current) {
268
+ resumeHover();
269
+ }
270
+ });
201
271
 
202
272
  const onPopupEscapeKeyDown = React.useCallback(() => {
203
- closePopup();
273
+ if (!dialogHoldRef.current) {
274
+ closePopup();
275
+ }
204
276
  }, [closePopup]);
205
277
 
206
278
  return (
@@ -218,6 +290,8 @@ export const HoverPopup = ({
218
290
  onOpenChange={(_open, _event, reason) => {
219
291
  if (reason === 'escape-key') {
220
292
  onPopupEscapeKeyDown();
293
+ } else if (reason === 'outside-press') {
294
+ onPopupBlur();
221
295
  }
222
296
  }}
223
297
  placement={placement}
@@ -226,11 +300,13 @@ export const HoverPopup = ({
226
300
  returnFocus={false}
227
301
  hasArrow
228
302
  open={open && isAnchorVisible}
303
+ onTransitionOutComplete={() => setHoverClosing(false)}
229
304
  // bigger offset for easier switching to neighbour nodes
230
305
  // matches the default offset for popup with arrow out of a sense of beauty
231
306
  offset={offset || {mainAxis: 12, crossAxis: 0}}
232
307
  >
233
308
  <div
309
+ ref={popupContent}
234
310
  className={contentClassName}
235
311
  onContextMenu={onPopupContextMenu}
236
312
  onMouseEnter={onPopupMouseEnter}
@@ -238,7 +314,7 @@ export const HoverPopup = ({
238
314
  onBlur={onPopupBlur}
239
315
  >
240
316
  <div className={YDB_POPOVER_CLASS_NAME}>
241
- {renderPopupContent({onClose: closePopup})}
317
+ {renderPopupContent({onClose: closePopup, holdOpen})}
242
318
  </div>
243
319
  </div>
244
320
  </Popup>
@@ -3,14 +3,15 @@ import {DefinitionList, Flex, useTheme} from '@gravity-ui/uikit';
3
3
  import type {TMemoryStats} from '../../types/api/nodes';
4
4
  import {formatBytes} from '../../utils/bytesParsers';
5
5
  import {cn} from '../../utils/cn';
6
- import {GIGABYTE} from '../../utils/constants';
6
+ import {EMPTY_DATA_PLACEHOLDER, GIGABYTE} from '../../utils/constants';
7
+ import {getNodeMemory} from '../../utils/memory';
7
8
  import type {FormatProgressViewerValues} from '../../utils/progress';
8
9
  import {calculateProgressStatus} from '../../utils/progress';
9
- import {isNumeric} from '../../utils/utils';
10
+ import {isNumeric, parseOptionalNonNegativeNumber} from '../../utils/utils';
10
11
  import {HoverPopup} from '../HoverPopup/HoverPopup';
11
12
  import {ProgressViewer} from '../ProgressViewer/ProgressViewer';
12
13
 
13
- import {calculateAllocatedMemory, getMemorySegments} from './utils';
14
+ import {getMemorySegments} from './utils';
14
15
 
15
16
  import './MemoryViewer.scss';
16
17
 
@@ -38,6 +39,8 @@ const formatDetailedValues: FormatProgressViewerValues = (value, total) => {
38
39
 
39
40
  export interface MemoryProgressViewerProps {
40
41
  stats: TMemoryStats;
42
+ memoryUsed?: string;
43
+ memoryLimit?: string;
41
44
  className?: string;
42
45
  warningThreshold?: number;
43
46
  dangerThreshold?: number;
@@ -47,29 +50,35 @@ export interface MemoryProgressViewerProps {
47
50
 
48
51
  export function MemoryViewer({
49
52
  stats,
53
+ memoryUsed,
54
+ memoryLimit,
50
55
  percents,
51
56
  formatValues,
52
57
  className,
53
58
  warningThreshold,
54
59
  dangerThreshold,
55
60
  }: MemoryProgressViewerProps) {
56
- const memoryUsage = stats.AnonRss ?? calculateAllocatedMemory(stats);
57
-
58
- const capacity = stats.HardLimit;
59
-
61
+ const {memoryUsed: memoryUsage, memoryLimit: capacity} = getNodeMemory({
62
+ MemoryStats: stats,
63
+ MemoryUsed: memoryUsed,
64
+ MemoryLimit: memoryLimit,
65
+ });
60
66
  const theme = useTheme();
61
- let fillWidth =
62
- Math.floor((parseFloat(String(memoryUsage)) / parseFloat(String(capacity))) * 100) || 0;
63
- fillWidth = fillWidth > 100 ? 100 : fillWidth;
67
+
68
+ if (memoryUsage === undefined) {
69
+ return EMPTY_DATA_PLACEHOLDER;
70
+ }
71
+ const fillWidth =
72
+ capacity === undefined ? 0 : Math.min(100, Math.floor((memoryUsage / capacity) * 100));
64
73
  let valueText: number | string | undefined = memoryUsage,
65
74
  capacityText: number | string | undefined = capacity,
66
75
  divider = '/';
67
- if (percents) {
76
+ if (percents && capacity !== undefined) {
68
77
  valueText = fillWidth + '%';
69
78
  capacityText = '';
70
79
  divider = '';
71
80
  } else if (formatValues) {
72
- [valueText, capacityText] = formatValues(Number(memoryUsage), Number(capacity));
81
+ [valueText, capacityText] = formatValues(memoryUsage, capacity);
73
82
  }
74
83
 
75
84
  const renderContent = () => {
@@ -81,13 +90,17 @@ export function MemoryViewer({
81
90
  };
82
91
 
83
92
  const calculateMemoryShare = (segmentSize: number) => {
84
- if (!memoryUsage) {
93
+ if (!memoryUsage || capacity === undefined) {
85
94
  return 0;
86
95
  }
87
- return (segmentSize / parseFloat(String(capacity))) * 100;
96
+ return (segmentSize / capacity) * 100;
88
97
  };
89
98
 
90
- const memorySegments = getMemorySegments(stats, Number(memoryUsage));
99
+ // Without anonymous RSS, the backend's MemoryUsed excludes allocator caches.
100
+ const memorySegments = getMemorySegments(stats, memoryUsage, {
101
+ allocatorCachesIncludedInUsage: parseOptionalNonNegativeNumber(stats.AnonRss) !== undefined,
102
+ memoryLimit: capacity,
103
+ });
91
104
 
92
105
  const status = calculateProgressStatus({
93
106
  fillWidth,
@@ -135,9 +148,9 @@ export function MemoryViewer({
135
148
  )}
136
149
  >
137
150
  <div className={b({theme, status}, className)}>
138
- <div className={b('progress-container')}>
151
+ <div className={capacity === undefined ? undefined : b('progress-container')}>
139
152
  {memorySegments
140
- .filter(({isInfo}) => !isInfo)
153
+ .filter(({isInfo}) => !isInfo && capacity !== undefined)
141
154
  .map((segment) => {
142
155
  if (segment.value < MIN_VISIBLE_MEMORY_VALUE) {
143
156
  return null;
@@ -5,8 +5,9 @@
5
5
  "text_memtable": "MemTable",
6
6
  "text_query-execution": "Query Execution",
7
7
  "text_usage": "Usage",
8
- "text_soft-limit": "Soft Limit",
9
- "text_hard-limit": "Hard Limit",
8
+ "text_soft-limit": "Memory Controller Soft Limit",
9
+ "text_hard-limit": "Memory Controller Hard Limit",
10
10
  "text_other": "Other",
11
- "text_memory-details": "Memory Details"
11
+ "text_memory-details": "Memory Details",
12
+ "text_memory-limit": "Memory Limit"
12
13
  }
@@ -1,14 +1,8 @@
1
1
  import type {TMemoryStats} from '../../types/api/nodes';
2
- import {isNumeric} from '../../utils/utils';
2
+ import {isNumeric, parseOptionalNonNegativeNumber} from '../../utils/utils';
3
3
 
4
4
  import i18n from './i18n';
5
5
 
6
- export function calculateAllocatedMemory(stats: TMemoryStats) {
7
- const allocatedMemory = getMaybeNumber(stats.AllocatedMemory) || 0;
8
- const allocatorCaches = getMaybeNumber(stats.AllocatorCachesMemory) || 0;
9
- return String(allocatedMemory + allocatorCaches);
10
- }
11
-
12
6
  function getMaybeNumber(value: string | number | undefined): number | undefined {
13
7
  return isNumeric(value) ? parseFloat(String(value)) : undefined;
14
8
  }
@@ -34,7 +28,14 @@ export function getMemorySegmentColor(key: string): string {
34
28
  return MEMORY_SEGMENT_COLORS[key] || MEMORY_SEGMENT_COLORS['Other'];
35
29
  }
36
30
 
37
- export function getMemorySegments(stats: TMemoryStats, memoryUsage: number): MemorySegment[] {
31
+ export function getMemorySegments(
32
+ stats: TMemoryStats,
33
+ memoryUsage: number,
34
+ {
35
+ allocatorCachesIncludedInUsage = true,
36
+ memoryLimit,
37
+ }: {allocatorCachesIncludedInUsage?: boolean; memoryLimit?: number} = {},
38
+ ): MemorySegment[] {
38
39
  const segments = [
39
40
  {
40
41
  label: i18n('text_shared-cache'),
@@ -61,12 +62,12 @@ export function getMemorySegments(stats: TMemoryStats, memoryUsage: number): Mem
61
62
  label: i18n('text_allocator-caches'),
62
63
  key: 'AllocatorCachesMemory',
63
64
  value: getMaybeNumber(stats.AllocatorCachesMemory),
64
- isInfo: false,
65
+ isInfo: !allocatorCachesIncludedInUsage,
65
66
  },
66
67
  ];
67
68
 
68
69
  const nonInfoSegments = segments.filter(
69
- (segment) => segment.value !== undefined,
70
+ (segment) => !segment.isInfo && segment.value !== undefined,
70
71
  ) as MemorySegment[];
71
72
  const sumNonInfoSegments = nonInfoSegments.reduce((acc, segment) => acc + segment.value, 0);
72
73
 
@@ -92,16 +93,22 @@ export function getMemorySegments(stats: TMemoryStats, memoryUsage: number): Mem
92
93
  value: memoryUsage,
93
94
  isInfo: true,
94
95
  },
96
+ {
97
+ label: i18n('text_memory-limit'),
98
+ key: 'MemoryLimit',
99
+ value: memoryLimit,
100
+ isInfo: true,
101
+ },
95
102
  {
96
103
  label: i18n('text_soft-limit'),
97
104
  key: 'SoftLimit',
98
- value: getMaybeNumber(stats.SoftLimit),
105
+ value: parseOptionalNonNegativeNumber(stats.SoftLimit) || undefined,
99
106
  isInfo: true,
100
107
  },
101
108
  {
102
109
  label: i18n('text_hard-limit'),
103
110
  key: 'HardLimit',
104
- value: getMaybeNumber(stats.HardLimit),
111
+ value: parseOptionalNonNegativeNumber(stats.HardLimit) || undefined,
105
112
  isInfo: true,
106
113
  },
107
114
  );
@@ -0,0 +1,15 @@
1
+ .ydb-pdisk-info {
2
+ --g-definition-list-item-gap: var(--g-spacing-3);
3
+
4
+ &__column {
5
+ flex: 1 1 400px;
6
+
7
+ min-width: 0;
8
+ max-width: 500px;
9
+ }
10
+
11
+ &__identity-value {
12
+ min-width: 0;
13
+ overflow-wrap: anywhere;
14
+ }
15
+ }