ydb-embedded-ui 22.3.0 → 22.5.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 (472) hide show
  1. package/dist/components/ButtonWithConfirmDialog/ButtonWithConfirmDialog.d.ts +3 -2
  2. package/dist/components/ButtonWithConfirmDialog/ButtonWithConfirmDialog.js +19 -4
  3. package/dist/components/ButtonWithConfirmDialog/ButtonWithConfirmDialog.js.map +1 -1
  4. package/dist/components/CopyableValue/CopyableValue.d.ts +10 -0
  5. package/dist/components/CopyableValue/CopyableValue.js +10 -0
  6. package/dist/components/CopyableValue/CopyableValue.js.map +1 -0
  7. package/dist/components/CopyableValue/CopyableValue.scss +16 -0
  8. package/dist/components/CopyableValue/i18n/en.json +3 -0
  9. package/dist/components/CopyableValue/i18n/index.d.ts +2 -0
  10. package/dist/components/CopyableValue/i18n/index.js +6 -0
  11. package/dist/components/CopyableValue/i18n/index.js.map +1 -0
  12. package/dist/components/CriticalActionDialog/CriticalActionDialog.d.ts +2 -1
  13. package/dist/components/CriticalActionDialog/CriticalActionDialog.js +2 -1
  14. package/dist/components/CriticalActionDialog/CriticalActionDialog.js.map +1 -1
  15. package/dist/components/DiskCapacityInfo/DiskCapacityInfo.d.ts +8 -19
  16. package/dist/components/DiskCapacityInfo/DiskCapacityInfo.js +68 -92
  17. package/dist/components/DiskCapacityInfo/DiskCapacityInfo.js.map +1 -1
  18. package/dist/components/DiskCapacityInfo/i18n/en.json +0 -1
  19. package/dist/components/DiskCapacityInfo/i18n/index.d.ts +1 -1
  20. package/dist/components/DiskPopup/DiskPopup.d.ts +25 -0
  21. package/dist/components/DiskPopup/DiskPopup.js +44 -0
  22. package/dist/components/DiskPopup/DiskPopup.js.map +1 -0
  23. package/dist/components/DiskPopup/DiskPopup.scss +203 -0
  24. package/dist/components/DiskPopup/i18n/en.json +3 -0
  25. package/dist/components/DiskPopup/i18n/index.d.ts +2 -0
  26. package/dist/components/DiskPopup/i18n/index.js +4 -0
  27. package/dist/components/DiskPopup/i18n/index.js.map +1 -0
  28. package/dist/components/DiskStatus/DiskStatus.d.ts +31 -0
  29. package/dist/components/DiskStatus/DiskStatus.js +61 -0
  30. package/dist/components/DiskStatus/DiskStatus.js.map +1 -0
  31. package/dist/components/DiskStatus/DiskStatus.scss +59 -0
  32. package/dist/components/DiskStatus/i18n/en.json +6 -0
  33. package/dist/components/DiskStatus/i18n/index.d.ts +2 -0
  34. package/dist/components/DiskStatus/i18n/index.js +4 -0
  35. package/dist/components/DiskStatus/i18n/index.js.map +1 -0
  36. package/dist/components/EntityStatus/EntityStatus.d.ts +19 -6
  37. package/dist/components/EntityStatus/EntityStatus.js +6 -2
  38. package/dist/components/EntityStatus/EntityStatus.js.map +1 -1
  39. package/dist/components/EntityStatus/EntityStatus.scss +5 -0
  40. package/dist/components/EvictVDiskButton/EvictVDiskButton.d.ts +5 -2
  41. package/dist/components/EvictVDiskButton/EvictVDiskButton.js +3 -2
  42. package/dist/components/EvictVDiskButton/EvictVDiskButton.js.map +1 -1
  43. package/dist/components/EvictVDiskButton/i18n/en.json +2 -2
  44. package/dist/components/FullNodeViewer/FullNodeViewer.js +4 -7
  45. package/dist/components/FullNodeViewer/FullNodeViewer.js.map +1 -1
  46. package/dist/components/FullNodeViewer/i18n/index.d.ts +1 -1
  47. package/dist/components/HoverPopup/HoverPopup.d.ts +3 -1
  48. package/dist/components/HoverPopup/HoverPopup.js +131 -28
  49. package/dist/components/HoverPopup/HoverPopup.js.map +1 -1
  50. package/dist/components/HoverPopup/usePopupPriority.d.ts +4 -0
  51. package/dist/components/HoverPopup/usePopupPriority.js +30 -0
  52. package/dist/components/HoverPopup/usePopupPriority.js.map +1 -0
  53. package/dist/components/MemoryViewer/MemoryViewer.d.ts +3 -1
  54. package/dist/components/MemoryViewer/MemoryViewer.js +25 -16
  55. package/dist/components/MemoryViewer/MemoryViewer.js.map +1 -1
  56. package/dist/components/MemoryViewer/i18n/en.json +4 -3
  57. package/dist/components/MemoryViewer/i18n/index.d.ts +1 -1
  58. package/dist/components/MemoryViewer/utils.d.ts +4 -2
  59. package/dist/components/MemoryViewer/utils.js +11 -11
  60. package/dist/components/MemoryViewer/utils.js.map +1 -1
  61. package/dist/components/PDiskInfo/PDiskInfo.d.ts +4 -9
  62. package/dist/components/PDiskInfo/PDiskInfo.js +32 -144
  63. package/dist/components/PDiskInfo/PDiskInfo.js.map +1 -1
  64. package/dist/components/PDiskInfo/PDiskInfo.scss +15 -0
  65. package/dist/components/PDiskInfo/PDiskLogSize.d.ts +5 -0
  66. package/dist/components/PDiskInfo/PDiskLogSize.js +20 -0
  67. package/dist/components/PDiskInfo/PDiskLogSize.js.map +1 -0
  68. package/dist/components/PDiskInfo/PDiskLogSize.scss +12 -0
  69. package/dist/components/PDiskInfo/getPDiskDetails.d.ts +4 -0
  70. package/dist/components/PDiskInfo/getPDiskDetails.js +33 -0
  71. package/dist/components/PDiskInfo/getPDiskDetails.js.map +1 -0
  72. package/dist/components/PDiskInfo/i18n/en.json +69 -4
  73. package/dist/components/PDiskInfo/i18n/index.d.ts +1 -1
  74. package/dist/components/PDiskInfo/statuses.d.ts +7 -0
  75. package/dist/components/PDiskInfo/statuses.js +194 -0
  76. package/dist/components/PDiskInfo/statuses.js.map +1 -0
  77. package/dist/components/PDiskPopup/PDiskPopup.d.ts +4 -7
  78. package/dist/components/PDiskPopup/PDiskPopup.js +28 -99
  79. package/dist/components/PDiskPopup/PDiskPopup.js.map +1 -1
  80. package/dist/components/PDiskPopup/i18n/en.json +2 -12
  81. package/dist/components/PDiskPopup/i18n/index.d.ts +1 -1
  82. package/dist/components/Search/Search.js +3 -1
  83. package/dist/components/Search/Search.js.map +1 -1
  84. package/dist/components/StorageGroupInfo/StorageGroupInfo.d.ts +3 -3
  85. package/dist/components/StorageGroupInfo/StorageGroupInfo.js +73 -218
  86. package/dist/components/StorageGroupInfo/StorageGroupInfo.js.map +1 -1
  87. package/dist/components/StorageGroupInfo/StorageGroupInfo.scss +21 -0
  88. package/dist/components/StorageGroupInfo/i18n/en.json +1 -9
  89. package/dist/components/StorageGroupInfo/i18n/index.d.ts +1 -1
  90. package/dist/components/TenantNameWrapper/i18n/index.d.ts +1 -1
  91. package/dist/components/VDisk/VDisk.d.ts +2 -1
  92. package/dist/components/VDisk/VDisk.js +24 -33
  93. package/dist/components/VDisk/VDisk.js.map +1 -1
  94. package/dist/components/VDisk/VDiskWithDonorsStack.d.ts +1 -1
  95. package/dist/components/VDisk/VDiskWithDonorsStack.js +2 -1
  96. package/dist/components/VDisk/VDiskWithDonorsStack.js.map +1 -1
  97. package/dist/components/VDisk/getFlagStatusText.d.ts +2 -0
  98. package/dist/components/VDisk/getFlagStatusText.js +18 -0
  99. package/dist/components/VDisk/getFlagStatusText.js.map +1 -0
  100. package/dist/components/VDisk/i18n/en.json +1 -1
  101. package/dist/components/VDisk/i18n/index.d.ts +1 -1
  102. package/dist/components/VDiskInfo/VDiskInfo.d.ts +3 -7
  103. package/dist/components/VDiskInfo/VDiskInfo.js +57 -235
  104. package/dist/components/VDiskInfo/VDiskInfo.js.map +1 -1
  105. package/dist/components/VDiskInfo/VDiskInfo.scss +19 -3
  106. package/dist/components/VDiskInfo/getVDiskDetails.d.ts +11 -0
  107. package/dist/components/VDiskInfo/getVDiskDetails.js +42 -0
  108. package/dist/components/VDiskInfo/getVDiskDetails.js.map +1 -0
  109. package/dist/components/VDiskInfo/i18n/en.json +5 -12
  110. package/dist/components/VDiskInfo/i18n/index.d.ts +1 -1
  111. package/dist/components/VDiskPopup/VDiskPopup.d.ts +7 -8
  112. package/dist/components/VDiskPopup/VDiskPopup.js +91 -241
  113. package/dist/components/VDiskPopup/VDiskPopup.js.map +1 -1
  114. package/dist/components/VDiskPopup/VDiskPopup.scss +3 -10
  115. package/dist/components/VDiskPopup/i18n/en.json +4 -22
  116. package/dist/components/VDiskPopup/i18n/index.d.ts +1 -1
  117. package/dist/components/VDiskStatus/VDiskReplicationStatus.d.ts +8 -0
  118. package/dist/components/VDiskStatus/VDiskReplicationStatus.js +32 -0
  119. package/dist/components/VDiskStatus/VDiskReplicationStatus.js.map +1 -0
  120. package/dist/components/VDiskStatus/VDiskStatus.d.ts +16 -0
  121. package/dist/components/VDiskStatus/VDiskStatus.js +20 -0
  122. package/dist/components/VDiskStatus/VDiskStatus.js.map +1 -0
  123. package/dist/components/VDiskStatus/VDiskStatus.scss +36 -0
  124. package/dist/components/VDiskStatus/i18n/en.json +33 -0
  125. package/dist/components/VDiskStatus/i18n/index.d.ts +1 -0
  126. package/dist/components/VDiskStatus/i18n/index.js +5 -0
  127. package/dist/components/VDiskStatus/i18n/index.js.map +1 -0
  128. package/dist/components/VDiskStatus/index.d.ts +2 -0
  129. package/dist/components/VDiskStatus/index.js +3 -0
  130. package/dist/components/VDiskStatus/index.js.map +1 -0
  131. package/dist/components/VDiskStatus/statuses.d.ts +4 -0
  132. package/dist/components/VDiskStatus/statuses.js +120 -0
  133. package/dist/components/VDiskStatus/statuses.js.map +1 -0
  134. package/dist/components/capacityMetricsColumns/i18n/en.json +4 -4
  135. package/dist/components/nodesColumns/columns.d.ts +1 -0
  136. package/dist/components/nodesColumns/columns.js +13 -6
  137. package/dist/components/nodesColumns/columns.js.map +1 -1
  138. package/dist/containers/Cluster/ClusterDrawerHealthcheck.js +6 -1
  139. package/dist/containers/Cluster/ClusterDrawerHealthcheck.js.map +1 -1
  140. package/dist/containers/Clusters/ClusterDrawerHealthcheck.js +1 -1
  141. package/dist/containers/Clusters/ClusterDrawerHealthcheck.js.map +1 -1
  142. package/dist/containers/Clusters/Clusters.js +35 -6
  143. package/dist/containers/Clusters/Clusters.js.map +1 -1
  144. package/dist/containers/Clusters/Clusters.scss +24 -6
  145. package/dist/containers/Clusters/columns.js +9 -4
  146. package/dist/containers/Clusters/columns.js.map +1 -1
  147. package/dist/containers/Clusters/i18n/en.json +6 -0
  148. package/dist/containers/Clusters/i18n/index.d.ts +1 -1
  149. package/dist/containers/Header/Header.js +16 -2
  150. package/dist/containers/Header/Header.js.map +1 -1
  151. package/dist/containers/Header/HeaderLeftControls.js +3 -1
  152. package/dist/containers/Header/HeaderLeftControls.js.map +1 -1
  153. package/dist/containers/Header/PDiskLeftControls.d.ts +1 -0
  154. package/dist/containers/Header/PDiskLeftControls.js +24 -0
  155. package/dist/containers/Header/PDiskLeftControls.js.map +1 -0
  156. package/dist/containers/Header/StorageGroupLeftControls.d.ts +1 -0
  157. package/dist/containers/Header/StorageGroupLeftControls.js +23 -0
  158. package/dist/containers/Header/StorageGroupLeftControls.js.map +1 -0
  159. package/dist/containers/Header/VDiskLeftControls.d.ts +1 -0
  160. package/dist/containers/Header/VDiskLeftControls.js +23 -0
  161. package/dist/containers/Header/VDiskLeftControls.js.map +1 -0
  162. package/dist/containers/Header/breadcrumbs.js +5 -2
  163. package/dist/containers/Header/breadcrumbs.js.map +1 -1
  164. package/dist/containers/Header/i18n/en.json +6 -1
  165. package/dist/containers/Header/i18n/index.d.ts +1 -1
  166. package/dist/containers/Nodes/NodesControls/NodesControls.js +1 -1
  167. package/dist/containers/Nodes/NodesControls/NodesControls.js.map +1 -1
  168. package/dist/containers/Nodes/PaginatedNodes/GroupedNodesComponent.js +5 -3
  169. package/dist/containers/Nodes/PaginatedNodes/GroupedNodesComponent.js.map +1 -1
  170. package/dist/containers/Nodes/PaginatedNodes/NodesComponent.js +4 -2
  171. package/dist/containers/Nodes/PaginatedNodes/NodesComponent.js.map +1 -1
  172. package/dist/containers/Nodes/useDebouncedSearch.d.ts +2 -0
  173. package/dist/containers/Nodes/useDebouncedSearch.js +11 -0
  174. package/dist/containers/Nodes/useDebouncedSearch.js.map +1 -0
  175. package/dist/containers/Operations/constants.d.ts +1 -1
  176. package/dist/containers/PDiskPage/PDiskPage.js +30 -31
  177. package/dist/containers/PDiskPage/PDiskPage.js.map +1 -1
  178. package/dist/containers/PDiskPage/PDiskPage.scss +22 -11
  179. package/dist/containers/PDiskPage/PDiskSpaceDistribution/PDiskSpaceDistribution.js +7 -7
  180. package/dist/containers/PDiskPage/PDiskSpaceDistribution/PDiskSpaceDistribution.js.map +1 -1
  181. package/dist/containers/PDiskPage/PDiskStorageDetails.d.ts +6 -0
  182. package/dist/containers/PDiskPage/PDiskStorageDetails.js +28 -0
  183. package/dist/containers/PDiskPage/PDiskStorageDetails.js.map +1 -0
  184. package/dist/containers/PDiskPage/PDiskStorageDetails.scss +51 -0
  185. package/dist/containers/PDiskPage/i18n/en.json +2 -0
  186. package/dist/containers/PDiskPage/i18n/index.d.ts +1 -1
  187. package/dist/containers/Storage/Disks/Disks.js +36 -9
  188. package/dist/containers/Storage/Disks/Disks.js.map +1 -1
  189. package/dist/containers/Storage/PDisk/PDisk.d.ts +2 -1
  190. package/dist/containers/Storage/PDisk/PDisk.js +2 -2
  191. package/dist/containers/Storage/PDisk/PDisk.js.map +1 -1
  192. package/dist/containers/Storage/PDisk/i18n/index.d.ts +1 -1
  193. package/dist/containers/Storage/PaginatedStorageGroupsTable/columns/columns.js +7 -2
  194. package/dist/containers/Storage/PaginatedStorageGroupsTable/columns/columns.js.map +1 -1
  195. package/dist/containers/Storage/PaginatedStorageGroupsTable/columns/i18n/index.d.ts +1 -1
  196. package/dist/containers/Storage/StorageExpertModePanel/components/SpaceLegend.scss +14 -82
  197. package/dist/containers/Storage/StorageExpertModePanel/constants.d.ts +1 -1
  198. package/dist/containers/Storage/StorageExpertModePanel/i18n/index.d.ts +1 -1
  199. package/dist/containers/Storage/StorageGroupStateLabel.d.ts +4 -0
  200. package/dist/containers/Storage/StorageGroupStateLabel.js +9 -0
  201. package/dist/containers/Storage/StorageGroupStateLabel.js.map +1 -0
  202. package/dist/containers/Storage/useStorageQueryParams.d.ts +4 -4
  203. package/dist/containers/Storage/utils/getStorageGroupStateLabel.d.ts +2 -0
  204. package/dist/containers/Storage/utils/getStorageGroupStateLabel.js +35 -0
  205. package/dist/containers/Storage/utils/getStorageGroupStateLabel.js.map +1 -0
  206. package/dist/containers/StorageGroupPage/StorageGroupPage.js +20 -13
  207. package/dist/containers/StorageGroupPage/StorageGroupPage.js.map +1 -1
  208. package/dist/containers/StorageGroupPage/StorageGroupPage.scss +18 -12
  209. package/dist/containers/StorageGroupPage/i18n/en.json +2 -1
  210. package/dist/containers/StorageGroupPage/i18n/index.d.ts +1 -1
  211. package/dist/containers/Tenant/Diagnostics/Overview/Overview.d.ts +2 -1
  212. package/dist/containers/Tenant/Diagnostics/Overview/Overview.js +4 -1
  213. package/dist/containers/Tenant/Diagnostics/Overview/Overview.js.map +1 -1
  214. package/dist/containers/Tenant/Diagnostics/Overview/SchemaObjectInfo/SchemaObjectInfo.d.ts +2 -1
  215. package/dist/containers/Tenant/Diagnostics/Overview/SchemaObjectInfo/SchemaObjectInfo.js +11 -2
  216. package/dist/containers/Tenant/Diagnostics/Overview/SchemaObjectInfo/SchemaObjectInfo.js.map +1 -1
  217. package/dist/containers/Tenant/Diagnostics/Overview/SchemaObjectInfo/prepareSchemaObjectInfo.d.ts +2 -1
  218. package/dist/containers/Tenant/Diagnostics/Overview/SchemaObjectInfo/prepareSchemaObjectInfo.js +9 -8
  219. package/dist/containers/Tenant/Diagnostics/Overview/SchemaObjectInfo/prepareSchemaObjectInfo.js.map +1 -1
  220. package/dist/containers/Tenant/Diagnostics/Overview/StreamingQueryInfo/StreamingQueryInfo.d.ts +16 -1
  221. package/dist/containers/Tenant/Diagnostics/Overview/StreamingQueryInfo/StreamingQueryInfo.js +56 -19
  222. package/dist/containers/Tenant/Diagnostics/Overview/StreamingQueryInfo/StreamingQueryInfo.js.map +1 -1
  223. package/dist/containers/Tenant/Diagnostics/Overview/StreamingQueryInfo/i18n/en.json +5 -1
  224. package/dist/containers/Tenant/Diagnostics/Overview/StreamingQueryInfo/i18n/index.d.ts +1 -1
  225. package/dist/containers/Tenant/Diagnostics/Overview/TableInfo/ManagePartitioningDialog/i18n/index.d.ts +1 -1
  226. package/dist/containers/Tenant/Diagnostics/TenantOverview/TenantOverview.js +5 -12
  227. package/dist/containers/Tenant/Diagnostics/TenantOverview/TenantOverview.js.map +1 -1
  228. package/dist/containers/Tenant/Diagnostics/TenantOverview/TenantStorage/i18n/index.d.ts +1 -1
  229. package/dist/containers/Tenant/Diagnostics/TopQueries/columns/i18n/index.d.ts +1 -1
  230. package/dist/containers/Tenant/Healthcheck/Healthcheck.scss +6 -1
  231. package/dist/containers/Tenant/Healthcheck/components/HealthcheckDrawer.d.ts +3 -1
  232. package/dist/containers/Tenant/Healthcheck/components/HealthcheckDrawer.js +3 -3
  233. package/dist/containers/Tenant/Healthcheck/components/HealthcheckDrawer.js.map +1 -1
  234. package/dist/containers/Tenant/Healthcheck/components/HealthcheckIssue.js +2 -2
  235. package/dist/containers/Tenant/Healthcheck/components/HealthcheckIssue.js.map +1 -1
  236. package/dist/containers/Tenant/TenantDrawerHealthcheck.js +17 -2
  237. package/dist/containers/Tenant/TenantDrawerHealthcheck.js.map +1 -1
  238. package/dist/containers/Tenants/DatabaseDrawerHealthcheck.js +8 -1
  239. package/dist/containers/Tenants/DatabaseDrawerHealthcheck.js.map +1 -1
  240. package/dist/containers/VDiskPage/VDiskPage.js +33 -33
  241. package/dist/containers/VDiskPage/VDiskPage.js.map +1 -1
  242. package/dist/containers/VDiskPage/VDiskPage.scss +21 -8
  243. package/dist/containers/VDiskPage/VDiskStorageDetails.js +27 -29
  244. package/dist/containers/VDiskPage/VDiskStorageDetails.js.map +1 -1
  245. package/dist/containers/VDiskPage/VDiskStorageDetails.scss +24 -93
  246. package/dist/containers/VDiskPage/i18n/en.json +3 -12
  247. package/dist/containers/VDiskPage/i18n/index.d.ts +1 -1
  248. package/dist/lib.d.ts +1 -1
  249. package/dist/lib.js.map +1 -1
  250. package/dist/store/configureStore.d.ts +2 -2
  251. package/dist/store/defaultStore.d.ts +1 -1
  252. package/dist/store/reducers/cluster/parseFields.js +1 -0
  253. package/dist/store/reducers/cluster/parseFields.js.map +1 -1
  254. package/dist/store/reducers/clusters/clusters.js +1 -0
  255. package/dist/store/reducers/clusters/clusters.js.map +1 -1
  256. package/dist/store/reducers/clusters/selectors.d.ts +1 -0
  257. package/dist/store/reducers/clusters/selectors.js +4 -1
  258. package/dist/store/reducers/clusters/selectors.js.map +1 -1
  259. package/dist/store/reducers/clusters/types.d.ts +2 -0
  260. package/dist/store/reducers/header/types.d.ts +1 -1
  261. package/dist/store/reducers/index.d.ts +2 -2
  262. package/dist/store/reducers/pdisk/types.d.ts +1 -0
  263. package/dist/store/reducers/pdisk/utils.js +6 -1
  264. package/dist/store/reducers/pdisk/utils.js.map +1 -1
  265. package/dist/store/reducers/storage/prepareGroupsDisks.d.ts +2 -1
  266. package/dist/store/reducers/storage/prepareGroupsDisks.js +9 -19
  267. package/dist/store/reducers/storage/prepareGroupsDisks.js.map +1 -1
  268. package/dist/store/reducers/storage/utils.js +14 -3
  269. package/dist/store/reducers/storage/utils.js.map +1 -1
  270. package/dist/store/reducers/streamingQuery/streamingQuery.js +2 -4
  271. package/dist/store/reducers/streamingQuery/streamingQuery.js.map +1 -1
  272. package/dist/store/reducers/vdisk/types.d.ts +1 -1
  273. package/dist/store/reducers/vdisk/utils.js +5 -5
  274. package/dist/store/reducers/vdisk/utils.js.map +1 -1
  275. package/dist/styles/mixins.scss +22 -0
  276. package/dist/types/api/meta.d.ts +1 -0
  277. package/dist/types/api/nodesList.d.ts +2 -0
  278. package/dist/types/api/pdisk.d.ts +4 -0
  279. package/dist/types/api/pdisk.js.map +1 -1
  280. package/dist/types/api/vdisk.d.ts +8 -0
  281. package/dist/types/api/vdisk.js +7 -0
  282. package/dist/types/api/vdisk.js.map +1 -1
  283. package/dist/types/store/nodesList.d.ts +4 -2
  284. package/dist/uiFactory/types.d.ts +5 -2
  285. package/dist/utils/bytesParsers/formatBytes.d.ts +3 -1
  286. package/dist/utils/bytesParsers/formatBytes.js +12 -3
  287. package/dist/utils/bytesParsers/formatBytes.js.map +1 -1
  288. package/dist/utils/disks/constants.d.ts +1 -0
  289. package/dist/utils/disks/constants.js +4 -0
  290. package/dist/utils/disks/constants.js.map +1 -1
  291. package/dist/utils/disks/diskInfo/getDiskLocationItems.d.ts +16 -0
  292. package/dist/utils/disks/diskInfo/getDiskLocationItems.js +30 -0
  293. package/dist/utils/disks/diskInfo/getDiskLocationItems.js.map +1 -0
  294. package/dist/utils/disks/diskInfo/i18n/en.json +9 -0
  295. package/dist/utils/disks/diskInfo/i18n/index.d.ts +2 -0
  296. package/dist/utils/disks/diskInfo/i18n/index.js +4 -0
  297. package/dist/utils/disks/diskInfo/i18n/index.js.map +1 -0
  298. package/dist/utils/disks/iconCalculators.d.ts +5 -0
  299. package/dist/utils/disks/iconCalculators.js +1 -1
  300. package/dist/utils/disks/iconCalculators.js.map +1 -1
  301. package/dist/utils/disks/prepareDisks.d.ts +6 -2
  302. package/dist/utils/disks/prepareDisks.js +22 -35
  303. package/dist/utils/disks/prepareDisks.js.map +1 -1
  304. package/dist/utils/disks/types.d.ts +9 -2
  305. package/dist/utils/hooks/useDatabaseHealthcheckAvailable.d.ts +2 -0
  306. package/dist/utils/hooks/useDatabaseHealthcheckAvailable.js +6 -0
  307. package/dist/utils/hooks/useDatabaseHealthcheckAvailable.js.map +1 -0
  308. package/dist/utils/hooks/useNodeMetadata.d.ts +2 -0
  309. package/dist/utils/hooks/useNodeMetadata.js +15 -0
  310. package/dist/utils/hooks/useNodeMetadata.js.map +1 -0
  311. package/dist/utils/memory.d.ts +5 -0
  312. package/dist/utils/memory.js +9 -0
  313. package/dist/utils/memory.js.map +1 -0
  314. package/dist/utils/nodes.js +6 -2
  315. package/dist/utils/nodes.js.map +1 -1
  316. package/dist/utils/storageMetrics.d.ts +3 -2
  317. package/dist/utils/storageMetrics.js +30 -10
  318. package/dist/utils/storageMetrics.js.map +1 -1
  319. package/dist/utils/timeParsers/formatDuration.d.ts +4 -1
  320. package/dist/utils/timeParsers/formatDuration.js +16 -1
  321. package/dist/utils/timeParsers/formatDuration.js.map +1 -1
  322. package/dist/utils/timeParsers/i18n/en.json +5 -1
  323. package/dist/utils/timeParsers/i18n/index.d.ts +1 -1
  324. package/dist/utils/timeParsers/i18n/ru.json +5 -1
  325. package/package.json +2 -2
  326. package/src/components/ButtonWithConfirmDialog/ButtonWithConfirmDialog.tsx +22 -3
  327. package/src/components/CopyableValue/CopyableValue.scss +16 -0
  328. package/src/components/CopyableValue/CopyableValue.tsx +40 -0
  329. package/src/components/CopyableValue/i18n/en.json +3 -0
  330. package/src/components/CopyableValue/i18n/index.ts +8 -0
  331. package/src/components/CriticalActionDialog/CriticalActionDialog.tsx +3 -0
  332. package/src/components/DiskCapacityInfo/DiskCapacityInfo.tsx +75 -129
  333. package/src/components/DiskCapacityInfo/i18n/en.json +0 -1
  334. package/src/components/DiskPopup/DiskPopup.scss +203 -0
  335. package/src/components/DiskPopup/DiskPopup.tsx +123 -0
  336. package/src/components/DiskPopup/i18n/en.json +3 -0
  337. package/src/components/DiskPopup/i18n/index.ts +5 -0
  338. package/src/components/DiskStatus/DiskStatus.scss +59 -0
  339. package/src/components/DiskStatus/DiskStatus.tsx +149 -0
  340. package/src/components/DiskStatus/i18n/en.json +6 -0
  341. package/src/components/DiskStatus/i18n/index.ts +5 -0
  342. package/src/components/EntityStatus/EntityStatus.scss +5 -0
  343. package/src/components/EntityStatus/EntityStatus.tsx +39 -6
  344. package/src/components/EvictVDiskButton/EvictVDiskButton.tsx +10 -2
  345. package/src/components/EvictVDiskButton/i18n/en.json +2 -2
  346. package/src/components/FullNodeViewer/FullNodeViewer.tsx +4 -9
  347. package/src/components/HoverPopup/HoverPopup.tsx +157 -34
  348. package/src/components/HoverPopup/usePopupPriority.ts +39 -0
  349. package/src/components/MemoryViewer/MemoryViewer.tsx +30 -17
  350. package/src/components/MemoryViewer/i18n/en.json +4 -3
  351. package/src/components/MemoryViewer/utils.ts +19 -12
  352. package/src/components/PDiskInfo/PDiskInfo.scss +15 -0
  353. package/src/components/PDiskInfo/PDiskInfo.tsx +51 -243
  354. package/src/components/PDiskInfo/PDiskLogSize.scss +12 -0
  355. package/src/components/PDiskInfo/PDiskLogSize.tsx +41 -0
  356. package/src/components/PDiskInfo/getPDiskDetails.tsx +37 -0
  357. package/src/components/PDiskInfo/i18n/en.json +69 -10
  358. package/src/components/PDiskInfo/statuses.ts +222 -0
  359. package/src/components/PDiskPopup/PDiskPopup.tsx +62 -147
  360. package/src/components/PDiskPopup/i18n/en.json +2 -12
  361. package/src/components/Search/Search.tsx +5 -2
  362. package/src/components/StorageGroupInfo/StorageGroupInfo.scss +21 -0
  363. package/src/components/StorageGroupInfo/StorageGroupInfo.tsx +119 -263
  364. package/src/components/StorageGroupInfo/i18n/en.json +1 -9
  365. package/src/components/VDisk/VDisk.tsx +34 -36
  366. package/src/components/VDisk/VDiskWithDonorsStack.tsx +2 -0
  367. package/src/components/VDisk/getFlagStatusText.ts +19 -0
  368. package/src/components/VDisk/i18n/en.json +1 -1
  369. package/src/components/VDiskInfo/VDiskInfo.scss +19 -3
  370. package/src/components/VDiskInfo/VDiskInfo.tsx +119 -341
  371. package/src/components/VDiskInfo/getVDiskDetails.tsx +63 -0
  372. package/src/components/VDiskInfo/i18n/en.json +5 -21
  373. package/src/components/VDiskPopup/VDiskPopup.scss +3 -10
  374. package/src/components/VDiskPopup/VDiskPopup.tsx +192 -424
  375. package/src/components/VDiskPopup/i18n/en.json +4 -22
  376. package/src/components/VDiskStatus/VDiskReplicationStatus.tsx +77 -0
  377. package/src/components/VDiskStatus/VDiskStatus.scss +36 -0
  378. package/src/components/VDiskStatus/VDiskStatus.tsx +49 -0
  379. package/src/components/VDiskStatus/i18n/en.json +33 -0
  380. package/src/components/VDiskStatus/i18n/index.ts +7 -0
  381. package/src/components/VDiskStatus/index.ts +7 -0
  382. package/src/components/VDiskStatus/statuses.ts +139 -0
  383. package/src/components/capacityMetricsColumns/i18n/en.json +4 -4
  384. package/src/components/nodesColumns/columns.tsx +26 -12
  385. package/src/containers/Cluster/ClusterDrawerHealthcheck.tsx +6 -0
  386. package/src/containers/Clusters/ClusterDrawerHealthcheck.tsx +1 -0
  387. package/src/containers/Clusters/Clusters.scss +24 -6
  388. package/src/containers/Clusters/Clusters.tsx +74 -5
  389. package/src/containers/Clusters/columns.tsx +36 -6
  390. package/src/containers/Clusters/i18n/en.json +6 -0
  391. package/src/containers/Header/Header.tsx +19 -3
  392. package/src/containers/Header/HeaderLeftControls.tsx +3 -1
  393. package/src/containers/Header/PDiskLeftControls.tsx +41 -0
  394. package/src/containers/Header/StorageGroupLeftControls.tsx +38 -0
  395. package/src/containers/Header/VDiskLeftControls.tsx +40 -0
  396. package/src/containers/Header/breadcrumbs.tsx +4 -2
  397. package/src/containers/Header/i18n/en.json +6 -1
  398. package/src/containers/Nodes/NodesControls/NodesControls.tsx +1 -0
  399. package/src/containers/Nodes/PaginatedNodes/GroupedNodesComponent.tsx +5 -3
  400. package/src/containers/Nodes/PaginatedNodes/NodesComponent.tsx +4 -2
  401. package/src/containers/Nodes/useDebouncedSearch.ts +13 -0
  402. package/src/containers/PDiskPage/PDiskPage.scss +22 -11
  403. package/src/containers/PDiskPage/PDiskPage.tsx +88 -56
  404. package/src/containers/PDiskPage/PDiskSpaceDistribution/PDiskSpaceDistribution.tsx +16 -11
  405. package/src/containers/PDiskPage/PDiskStorageDetails.scss +51 -0
  406. package/src/containers/PDiskPage/PDiskStorageDetails.tsx +64 -0
  407. package/src/containers/PDiskPage/i18n/en.json +2 -0
  408. package/src/containers/Storage/Disks/Disks.tsx +66 -12
  409. package/src/containers/Storage/PDisk/PDisk.tsx +3 -0
  410. package/src/containers/Storage/PaginatedStorageGroupsTable/columns/columns.tsx +24 -3
  411. package/src/containers/Storage/StorageExpertModePanel/components/SpaceLegend.scss +14 -82
  412. package/src/containers/Storage/StorageGroupStateLabel.tsx +22 -0
  413. package/src/containers/Storage/utils/getStorageGroupStateLabel.ts +49 -0
  414. package/src/containers/StorageGroupPage/StorageGroupPage.scss +18 -12
  415. package/src/containers/StorageGroupPage/StorageGroupPage.tsx +63 -26
  416. package/src/containers/StorageGroupPage/i18n/en.json +2 -1
  417. package/src/containers/Tenant/Diagnostics/Overview/Overview.tsx +5 -1
  418. package/src/containers/Tenant/Diagnostics/Overview/SchemaObjectInfo/SchemaObjectInfo.tsx +12 -1
  419. package/src/containers/Tenant/Diagnostics/Overview/SchemaObjectInfo/prepareSchemaObjectInfo.tsx +11 -10
  420. package/src/containers/Tenant/Diagnostics/Overview/StreamingQueryInfo/StreamingQueryInfo.tsx +83 -20
  421. package/src/containers/Tenant/Diagnostics/Overview/StreamingQueryInfo/i18n/en.json +5 -1
  422. package/src/containers/Tenant/Diagnostics/TenantOverview/TenantOverview.tsx +5 -32
  423. package/src/containers/Tenant/Healthcheck/Healthcheck.scss +6 -1
  424. package/src/containers/Tenant/Healthcheck/components/HealthcheckDrawer.tsx +5 -2
  425. package/src/containers/Tenant/Healthcheck/components/HealthcheckIssue.tsx +18 -8
  426. package/src/containers/Tenant/TenantDrawerHealthcheck.tsx +24 -1
  427. package/src/containers/Tenants/DatabaseDrawerHealthcheck.tsx +10 -0
  428. package/src/containers/VDiskPage/VDiskPage.scss +21 -8
  429. package/src/containers/VDiskPage/VDiskPage.tsx +103 -64
  430. package/src/containers/VDiskPage/VDiskStorageDetails.scss +24 -93
  431. package/src/containers/VDiskPage/VDiskStorageDetails.tsx +50 -158
  432. package/src/containers/VDiskPage/i18n/en.json +3 -14
  433. package/src/lib.ts +1 -0
  434. package/src/store/reducers/cluster/parseFields.ts +1 -0
  435. package/src/store/reducers/clusters/clusters.ts +1 -0
  436. package/src/store/reducers/clusters/selectors.ts +4 -0
  437. package/src/store/reducers/clusters/types.ts +3 -0
  438. package/src/store/reducers/header/types.ts +3 -1
  439. package/src/store/reducers/pdisk/types.ts +1 -0
  440. package/src/store/reducers/pdisk/utils.ts +6 -3
  441. package/src/store/reducers/storage/prepareGroupsDisks.ts +9 -22
  442. package/src/store/reducers/storage/utils.ts +17 -3
  443. package/src/store/reducers/streamingQuery/streamingQuery.ts +2 -4
  444. package/src/store/reducers/vdisk/types.ts +2 -1
  445. package/src/store/reducers/vdisk/utils.ts +4 -5
  446. package/src/styles/mixins.scss +22 -0
  447. package/src/types/api/meta.ts +1 -0
  448. package/src/types/api/nodesList.ts +3 -0
  449. package/src/types/api/pdisk.ts +4 -0
  450. package/src/types/api/vdisk.ts +9 -0
  451. package/src/types/store/nodesList.ts +7 -7
  452. package/src/uiFactory/types.ts +9 -2
  453. package/src/utils/bytesParsers/formatBytes.ts +23 -4
  454. package/src/utils/disks/constants.ts +5 -0
  455. package/src/utils/disks/diskInfo/getDiskLocationItems.ts +50 -0
  456. package/src/utils/disks/diskInfo/i18n/en.json +9 -0
  457. package/src/utils/disks/diskInfo/i18n/index.ts +5 -0
  458. package/src/utils/disks/iconCalculators.ts +1 -1
  459. package/src/utils/disks/prepareDisks.ts +21 -47
  460. package/src/utils/disks/types.ts +10 -2
  461. package/src/utils/hooks/useDatabaseHealthcheckAvailable.ts +9 -0
  462. package/src/utils/hooks/useNodeMetadata.ts +21 -0
  463. package/src/utils/memory.ts +16 -0
  464. package/src/utils/nodes.ts +7 -1
  465. package/src/utils/storageMetrics.ts +38 -14
  466. package/src/utils/timeParsers/formatDuration.ts +22 -1
  467. package/src/utils/timeParsers/i18n/en.json +5 -1
  468. package/src/utils/timeParsers/i18n/ru.json +5 -1
  469. package/dist/components/VDiskInfo/getVDiskCapacityColumns.d.ts +0 -11
  470. package/dist/components/VDiskInfo/getVDiskCapacityColumns.js +0 -52
  471. package/dist/components/VDiskInfo/getVDiskCapacityColumns.js.map +0 -1
  472. package/src/components/VDiskInfo/getVDiskCapacityColumns.tsx +0 -83
@@ -2,7 +2,7 @@ import React from 'react';
2
2
 
3
3
  import {Magnifier} from '@gravity-ui/icons';
4
4
  import DataTable from '@gravity-ui/react-data-table';
5
- import {Icon, Select, Text} from '@gravity-ui/uikit';
5
+ import {Flex, Icon, Select, Text} from '@gravity-ui/uikit';
6
6
 
7
7
  import {ResponseError} from '../../components/Errors/ResponseError';
8
8
  import {ResizeableDataTable} from '../../components/ResizeableDataTable/ResizeableDataTable';
@@ -13,13 +13,14 @@ import {useEmMetaAvailable} from '../../store/reducers/capabilities/hooks';
13
13
  import {changeClustersFilters, clustersApi} from '../../store/reducers/clusters/clusters';
14
14
  import {
15
15
  filterClusters,
16
+ selectAvailabilityFilter,
16
17
  selectClusterNameFilter,
17
18
  selectGalaxyFilter,
18
19
  selectServiceFilter,
19
20
  selectStatusFilter,
20
21
  selectVersionFilter,
21
22
  } from '../../store/reducers/clusters/selectors';
22
- import type {PreparedCluster} from '../../store/reducers/clusters/types';
23
+ import type {ClusterAvailability, PreparedCluster} from '../../store/reducers/clusters/types';
23
24
  import {uiFactory} from '../../uiFactory/uiFactory';
24
25
  import {DEFAULT_TABLE_SETTINGS, EMPTY_DATA_PLACEHOLDER} from '../../utils/constants';
25
26
  import {useAutoRefreshInterval, useTypedDispatch, useTypedSelector} from '../../utils/hooks';
@@ -61,6 +62,7 @@ export function Clusters({scrollContainerRef}: ClustersProps) {
61
62
  const service = useTypedSelector(selectServiceFilter);
62
63
  const version = useTypedSelector(selectVersionFilter);
63
64
  const galaxy = useTypedSelector(selectGalaxyFilter);
65
+ const availability = useTypedSelector(selectAvailabilityFilter);
64
66
 
65
67
  const changeStatus = (value: string[]) => {
66
68
  dispatch(changeClustersFilters({status: value}));
@@ -77,6 +79,16 @@ export function Clusters({scrollContainerRef}: ClustersProps) {
77
79
  const changeGalaxy = (value: string[]) => {
78
80
  dispatch(changeClustersFilters({galaxy: value}));
79
81
  };
82
+ const changeAvailability = (value: string[]) => {
83
+ dispatch(
84
+ changeClustersFilters({
85
+ availability: value.filter(
86
+ (item): item is ClusterAvailability =>
87
+ item === 'available' || item === 'unavailable',
88
+ ),
89
+ }),
90
+ );
91
+ };
80
92
 
81
93
  const [healthcheckClusterName, setHealthcheckClusterName] = React.useState<string | undefined>(
82
94
  undefined,
@@ -101,6 +113,19 @@ export function Clusters({scrollContainerRef}: ClustersProps) {
101
113
  }, [isDeleteClusterAvailable, isEditClusterAvailable, handleStatusClick]);
102
114
 
103
115
  const clusters = query.data;
116
+ const hasUnavailableClusters = clusters?.some(
117
+ (cluster) => cluster.settings?.unavailable === true,
118
+ );
119
+ const showAvailabilityFilter =
120
+ hasUnavailableClusters || availability.length !== 1 || availability[0] !== 'available';
121
+ const availabilityOptions = [
122
+ {value: 'available', content: i18n('value_available')},
123
+ {value: 'unavailable', content: i18n('value_unavailable')},
124
+ ];
125
+ const availabilitySummary =
126
+ availability.length === availabilityOptions.length
127
+ ? i18n('controls_select-placeholder')
128
+ : availabilityOptions.find((option) => option.value === availability[0])?.content;
104
129
 
105
130
  // Check which columns have data across all clusters
106
131
  const {hasAnyStatus, hasAnyService, hasAnyGalaxy} = React.useMemo(() => {
@@ -184,8 +209,15 @@ export function Clusters({scrollContainerRef}: ClustersProps) {
184
209
  }, [clusters]);
185
210
 
186
211
  const filteredClusters = React.useMemo(() => {
187
- return filterClusters(clusters ?? [], {clusterName, status, service, version, galaxy});
188
- }, [clusterName, clusters, service, status, version, galaxy]);
212
+ return filterClusters(clusters ?? [], {
213
+ clusterName,
214
+ status,
215
+ service,
216
+ version,
217
+ galaxy,
218
+ availability,
219
+ });
220
+ }, [clusterName, clusters, service, status, version, galaxy, availability]);
189
221
 
190
222
  const statuses = React.useMemo(() => {
191
223
  return Array.from(
@@ -260,6 +292,37 @@ export function Clusters({scrollContainerRef}: ClustersProps) {
260
292
  width={200}
261
293
  />
262
294
  ) : null}
295
+ {showAvailabilityFilter ? (
296
+ <Select
297
+ multiple
298
+ label={i18n('controls_availability-select-label')}
299
+ placeholder={i18n('value_none')}
300
+ value={availability}
301
+ options={availabilityOptions}
302
+ onUpdate={changeAvailability}
303
+ width={200}
304
+ popupWidth={280}
305
+ popupClassName={b('availability-popup')}
306
+ hasCounter={false}
307
+ qa="clusters-availability"
308
+ getOptionHeight={(option) => (option.value === 'unavailable' ? 56 : 36)}
309
+ renderOption={(option) => (
310
+ <Flex direction="column">
311
+ <Text>{option.content}</Text>
312
+ {option.value === 'unavailable' ? (
313
+ <Text color="secondary" variant="body-1">
314
+ {i18n('context_unavailable-admin')}
315
+ </Text>
316
+ ) : null}
317
+ </Flex>
318
+ )}
319
+ renderSelectedOption={(_option, index) => (
320
+ <React.Fragment>
321
+ {index === 0 ? availabilitySummary : null}
322
+ </React.Fragment>
323
+ )}
324
+ />
325
+ ) : null}
263
326
  </React.Fragment>
264
327
  );
265
328
  };
@@ -320,7 +383,13 @@ export function Clusters({scrollContainerRef}: ClustersProps) {
320
383
  <TableWithControlsLayout
321
384
  fullHeight
322
385
  className={b(null)}
323
- keyboardNavigationResetKey={JSON.stringify([status, service, version, galaxy])}
386
+ keyboardNavigationResetKey={JSON.stringify([
387
+ status,
388
+ service,
389
+ version,
390
+ galaxy,
391
+ availability,
392
+ ])}
324
393
  >
325
394
  <TableWithControlsLayout.Controls
326
395
  className={b('controls')}
@@ -1,13 +1,15 @@
1
- import {Pencil, TrashBin} from '@gravity-ui/icons';
1
+ import {CircleXmark, Pencil, TrashBin} from '@gravity-ui/icons';
2
2
  import DataTable from '@gravity-ui/react-data-table';
3
3
  import type {Column} from '@gravity-ui/react-data-table';
4
4
  import {
5
5
  ClipboardButton,
6
6
  Link as ExternalLink,
7
7
  Flex,
8
+ Icon,
8
9
  Label,
9
10
  Progress,
10
11
  Text,
12
+ Tooltip,
11
13
  } from '@gravity-ui/uikit';
12
14
 
13
15
  import type {DropdownMenuItemWithDescription} from '../../components/DropdownMenu';
@@ -240,9 +242,9 @@ function getTitleColumn({
240
242
 
241
243
  return (
242
244
  <Flex direction={'column'} gap={0.5}>
243
- <Flex alignItems={'flex-start'} justifyContent={'space-between'} gap={1}>
245
+ <Flex alignItems="center" justifyContent="space-between" gap={1}>
244
246
  {renderName()}
245
- <Flex gap={1}>
247
+ <Flex alignItems="center" gap={1}>
246
248
  {renderStatus()}
247
249
  {renderActions()}
248
250
  </Flex>
@@ -262,9 +264,37 @@ function ClusterName({row}: ClusterNameProps) {
262
264
  const clusterPath = calculateClusterPath(row);
263
265
 
264
266
  return (
265
- <div className={b('cluster-name')}>
266
- <ExternalLink href={clusterPath}>{row.title || row.name}</ExternalLink>
267
- </div>
267
+ <Flex alignItems="center" gap={1} className={b('cluster-name-wrapper')}>
268
+ <ExternalLink
269
+ href={clusterPath}
270
+ className={b('cluster-name')}
271
+ title={row.title || row.name}
272
+ >
273
+ {row.title || row.name}
274
+ </ExternalLink>
275
+ {row.settings?.unavailable === true ? (
276
+ <Tooltip content={i18n('tooltip_unavailable')}>
277
+ <span
278
+ className={b('unavailable-label')}
279
+ tabIndex={0}
280
+ data-qa="cluster-unavailable-label"
281
+ onKeyDown={(event) => {
282
+ if (['ArrowUp', 'ArrowDown', 'Enter'].includes(event.key)) {
283
+ event.stopPropagation();
284
+ }
285
+ }}
286
+ >
287
+ <Label
288
+ theme="unknown"
289
+ size="xs"
290
+ icon={<Icon data={CircleXmark} size={12} />}
291
+ >
292
+ {i18n('value_unavailable')}
293
+ </Label>
294
+ </span>
295
+ </Tooltip>
296
+ ) : null}
297
+ </Flex>
268
298
  );
269
299
  }
270
300
 
@@ -3,6 +3,11 @@
3
3
  "controls_service-select-label": "Service:",
4
4
  "controls_version-select-label": "Version:",
5
5
  "controls_galaxy-select-label": "Galaxy:",
6
+ "controls_availability-select-label": "Availability:",
7
+ "value_available": "Available",
8
+ "value_unavailable": "Unavailable",
9
+ "value_none": "None",
10
+ "context_unavailable-admin": "Marked by an administrator",
6
11
 
7
12
  "controls_search-placeholder": "Cluster name, version, domain, host...",
8
13
  "controls_select-placeholder": "All",
@@ -14,6 +19,7 @@
14
19
  "statistics_storage": "Storage",
15
20
 
16
21
  "tooltip_no-cluster-data": "No cluster data",
22
+ "tooltip_unavailable": "Marked as unavailable by an administrator. This is independent of healthcheck. You can still open the cluster",
17
23
 
18
24
  "clusters-count": {
19
25
  "one": "{{count}} cluster found",
@@ -1,6 +1,9 @@
1
1
  import {HeaderBreadcrumbs} from './HeaderBreadcrumbs';
2
2
  import {HeaderLeftControls} from './HeaderLeftControls';
3
3
  import {HeaderRightControls} from './HeaderRightControls';
4
+ import {PDiskLeftControls} from './PDiskLeftControls';
5
+ import {StorageGroupLeftControls} from './StorageGroupLeftControls';
6
+ import {VDiskLeftControls} from './VDiskLeftControls';
4
7
  import {b} from './constants';
5
8
  import {useHeaderBreadcrumbs} from './hooks/useHeaderBreadcrumbs';
6
9
  import {useHeaderData} from './hooks/useHeaderData';
@@ -66,18 +69,31 @@ export function Header() {
66
69
  return null;
67
70
  }
68
71
 
69
- const leftControls =
70
- database && isDatabasePage && isV2NavigationEnabled ? (
72
+ const renderLeftControls = () => {
73
+ if (page === 'storageGroup') {
74
+ return <StorageGroupLeftControls />;
75
+ }
76
+ if (page === 'vDisk') {
77
+ return <VDiskLeftControls />;
78
+ }
79
+ if (page === 'pDisk') {
80
+ return <PDiskLeftControls />;
81
+ }
82
+ return database && isDatabasePage && isV2NavigationEnabled ? (
71
83
  <HeaderLeftControls
72
84
  database={database}
73
85
  databaseData={databaseData}
74
86
  isDatabaseDataLoading={isDatabaseDataLoading}
75
87
  />
76
88
  ) : null;
89
+ };
77
90
 
78
91
  return (
79
92
  <header className={b()}>
80
- <HeaderBreadcrumbs breadcrumbItems={breadcrumbItems} endContent={leftControls} />
93
+ <HeaderBreadcrumbs
94
+ breadcrumbItems={breadcrumbItems}
95
+ endContent={renderLeftControls()}
96
+ />
81
97
 
82
98
  <HeaderRightControls
83
99
  clusterName={clusterName}
@@ -4,6 +4,7 @@ import {ActionTooltip, Button, ClipboardButton, Flex, Icon} from '@gravity-ui/ui
4
4
  import {getConnectToDBDialog} from '../../components/ConnectToDB/ConnectToDBDialog';
5
5
  import {ServerlessDBLabel} from '../../components/ServerlessDBLabel/ServerlessDBLabel';
6
6
  import type {PreparedTenant} from '../../store/reducers/tenants/types';
7
+ import {useDatabaseHealthcheckAvailable} from '../../utils/hooks/useDatabaseHealthcheckAvailable';
7
8
  import {HealthcheckPreview} from '../Tenant/Diagnostics/TenantOverview/Healthcheck/HealthcheckPreview';
8
9
 
9
10
  import {b} from './constants';
@@ -20,9 +21,10 @@ export function HeaderLeftControls({
20
21
  databaseData,
21
22
  isDatabaseDataLoading,
22
23
  }: HeaderLeftControlsProps) {
24
+ const healthcheckAvailable = useDatabaseHealthcheckAvailable(databaseData?.Type);
23
25
  const showCopyButton = Boolean(databaseData?.Name);
24
26
  const isServerless = databaseData?.Type === 'Serverless';
25
- const showHealthcheck = !isServerless && !isDatabaseDataLoading;
27
+ const showHealthcheck = healthcheckAvailable && !isDatabaseDataLoading;
26
28
 
27
29
  return (
28
30
  <Flex direction="row" alignItems={'center'} gap={2} className={b('left-controls')}>
@@ -0,0 +1,41 @@
1
+ import {ClipboardButton, Flex} from '@gravity-ui/uikit';
2
+ import {skipToken} from '@reduxjs/toolkit/query';
3
+ import {StringParam, useQueryParams} from 'use-query-params';
4
+
5
+ import {DiskStatusLabel} from '../../components/DiskStatus/DiskStatus';
6
+ import {getPDiskStateLabel} from '../../components/PDiskInfo/statuses';
7
+ import {pDiskApi} from '../../store/reducers/pdisk/pdisk';
8
+ import {valueIsDefined} from '../../utils';
9
+ import {getPDiskId} from '../../utils/disks/helpers';
10
+
11
+ import {b} from './constants';
12
+ import {headerKeyset} from './i18n';
13
+
14
+ export function PDiskLeftControls() {
15
+ const [{nodeId, pDiskId}] = useQueryParams({
16
+ nodeId: StringParam,
17
+ pDiskId: StringParam,
18
+ });
19
+ const {currentData} = pDiskApi.endpoints.getPdiskInfo.useQueryState(
20
+ valueIsDefined(nodeId) && valueIsDefined(pDiskId) ? {nodeId, pDiskId} : skipToken,
21
+ );
22
+ const diskId = getPDiskId({nodeId, pDiskId});
23
+
24
+ if (!diskId) {
25
+ return null;
26
+ }
27
+
28
+ return (
29
+ <Flex alignItems="center" gap={2} className={b('left-controls')}>
30
+ <ClipboardButton
31
+ text={diskId}
32
+ size="s"
33
+ view="flat-secondary"
34
+ color="secondary"
35
+ aria-label={headerKeyset('action_copy-pdisk-id-from-breadcrumb')}
36
+ tooltipInitialText={headerKeyset('action_copy-pdisk-id')}
37
+ />
38
+ <DiskStatusLabel {...getPDiskStateLabel(currentData?.State)} size="xs" iconSize={12} />
39
+ </Flex>
40
+ );
41
+ }
@@ -0,0 +1,38 @@
1
+ import {ClipboardButton, Flex} from '@gravity-ui/uikit';
2
+ import {skipToken} from '@reduxjs/toolkit/query';
3
+ import {StringParam, useQueryParams} from 'use-query-params';
4
+
5
+ import {storageApi} from '../../store/reducers/storage/storage';
6
+ import {valueIsDefined} from '../../utils';
7
+ import {useDatabaseFromQuery} from '../../utils/hooks/useDatabaseFromQuery';
8
+ import {StorageGroupStateLabel} from '../Storage/StorageGroupStateLabel';
9
+
10
+ import {b} from './constants';
11
+ import {headerKeyset} from './i18n';
12
+
13
+ export function StorageGroupLeftControls() {
14
+ const [{groupId}] = useQueryParams({groupId: StringParam});
15
+ const database = useDatabaseFromQuery();
16
+ const {currentData} = storageApi.endpoints.getStorageGroupsInfo.useQueryState(
17
+ valueIsDefined(groupId)
18
+ ? {groupId, with: 'all', fieldsRequired: 'all', database}
19
+ : skipToken,
20
+ );
21
+
22
+ if (!groupId) {
23
+ return null;
24
+ }
25
+
26
+ return (
27
+ <Flex alignItems="center" gap={2} className={b('left-controls')}>
28
+ <ClipboardButton
29
+ text={groupId}
30
+ view="flat-secondary"
31
+ size="s"
32
+ aria-label={headerKeyset('action_copy-group-id-from-breadcrumb')}
33
+ tooltipInitialText={headerKeyset('action_copy-group-id')}
34
+ />
35
+ <StorageGroupStateLabel state={currentData?.groups?.[0]?.State} size="xs" />
36
+ </Flex>
37
+ );
38
+ }
@@ -0,0 +1,40 @@
1
+ import {ClipboardButton, Flex} from '@gravity-ui/uikit';
2
+ import {skipToken} from '@reduxjs/toolkit/query';
3
+ import {StringParam, useQueryParams} from 'use-query-params';
4
+
5
+ import {VDiskStateLabel} from '../../components/VDiskStatus';
6
+ import {vDiskApi} from '../../store/reducers/vdisk/vdisk';
7
+
8
+ import {b} from './constants';
9
+ import {headerKeyset} from './i18n';
10
+
11
+ export function VDiskLeftControls() {
12
+ const [{vDiskId, nodeId, database}] = useQueryParams({
13
+ vDiskId: StringParam,
14
+ nodeId: StringParam,
15
+ database: StringParam,
16
+ });
17
+ const {currentData} = vDiskApi.endpoints.getVDiskData.useQueryState(
18
+ vDiskId
19
+ ? {vDiskId, nodeId: nodeId ?? undefined, database: database ?? undefined}
20
+ : skipToken,
21
+ );
22
+
23
+ if (!vDiskId) {
24
+ return null;
25
+ }
26
+
27
+ return (
28
+ <Flex alignItems="center" gap={2} className={b('left-controls')}>
29
+ <ClipboardButton
30
+ text={vDiskId}
31
+ size="s"
32
+ view="flat-secondary"
33
+ color="secondary"
34
+ aria-label={headerKeyset('action_copy-vdisk-id')}
35
+ tooltipInitialText={headerKeyset('action_copy-vdisk-id')}
36
+ />
37
+ <VDiskStateLabel state={currentData?.VDiskState} size="xs" />
38
+ </Flex>
39
+ );
40
+ }
@@ -35,6 +35,7 @@ import {
35
35
  TENANT_PAGES_IDS,
36
36
  } from '../../store/reducers/tenant/constants';
37
37
  import {CLUSTER_DEFAULT_TITLE, UNBREAKABLE_GAP, getTabletLabel} from '../../utils/constants';
38
+ import {getPDiskId} from '../../utils/disks/helpers';
38
39
  import {TenantTabsGroups} from '../Tenant/TenantPages';
39
40
 
40
41
  import {headerKeyset} from './i18n';
@@ -205,8 +206,9 @@ const getPDiskBreadcrumbs: GetBreadcrumbs<PDiskBreadcrumbsOptions> = (options, q
205
206
  });
206
207
 
207
208
  let text = headerKeyset('breadcrumbs.pDisk');
208
- if (pDiskId) {
209
- text += ` ${pDiskId}`;
209
+ const diskId = getPDiskId({nodeId, pDiskId}) ?? pDiskId;
210
+ if (diskId) {
211
+ text += ` ${diskId}`;
210
212
  }
211
213
 
212
214
  const hasLink = pDiskId && nodeId;
@@ -24,5 +24,10 @@
24
24
  "description_connect-to-db": "Connect to database",
25
25
 
26
26
  "title_monitoring": "Open in {{system}}",
27
- "action_copy-path": "Copy path"
27
+ "action_copy-path": "Copy path",
28
+ "action_copy-group-id": "Copy Storage Group ID",
29
+ "action_copy-group-id-from-breadcrumb": "Copy Storage Group ID from breadcrumb",
30
+ "action_copy-vdisk-id": "Copy VDisk ID",
31
+ "action_copy-pdisk-id": "Copy PDisk ID",
32
+ "action_copy-pdisk-id-from-breadcrumb": "Copy PDisk ID from breadcrumb"
28
33
  }
@@ -68,6 +68,7 @@ export function NodesControls({
68
68
  <React.Fragment>
69
69
  <Search
70
70
  tableFilter
71
+ debounce={0}
71
72
  onChange={handleSearchQueryChange}
72
73
  placeholder={i18n('controls_search-placeholder')}
73
74
  width={238}
@@ -22,6 +22,7 @@ import {NodesControls} from '../NodesControls/NodesControls';
22
22
  import {NodesTable} from '../NodesTable';
23
23
  import i18n from '../i18n';
24
24
  import {b} from '../shared';
25
+ import {useDebouncedSearch} from '../useDebouncedSearch';
25
26
  import {useNodesPageQueryParams} from '../useNodesPageQueryParams';
26
27
 
27
28
  interface NodeGroupProps {
@@ -123,6 +124,7 @@ export function GroupedNodesComponent({
123
124
  groupByParams,
124
125
  withPeerRoleFilter,
125
126
  );
127
+ const searchFilter = useDebouncedSearch(searchValue);
126
128
  const useMetaProxy = useClusterWithProxy();
127
129
  const [autoRefreshInterval] = useAutoRefreshInterval();
128
130
 
@@ -145,7 +147,7 @@ export function GroupedNodesComponent({
145
147
  {
146
148
  path: schemaPathParam,
147
149
  database,
148
- filter: searchValue.trim(),
150
+ filter: searchFilter.trim(),
149
151
  filter_peer_role: peerRoleFilter,
150
152
  group: groupByParam,
151
153
  limit: 0,
@@ -185,7 +187,7 @@ export function GroupedNodesComponent({
185
187
  path={path}
186
188
  databaseFullPath={databaseFullPath}
187
189
  database={database}
188
- searchValue={searchValue}
190
+ searchValue={searchFilter}
189
191
  peerRoleFilter={peerRoleFilter}
190
192
  groupByParam={groupByParam}
191
193
  columns={columnsToShow}
@@ -225,7 +227,7 @@ export function GroupedNodesComponent({
225
227
  table={renderGroups()}
226
228
  tableWrapperProps={{
227
229
  scrollContainerRef,
228
- scrollDependencies: [searchValue, groupByParam, tableGroups, peerRoleFilter],
230
+ scrollDependencies: [searchFilter, groupByParam, tableGroups, peerRoleFilter],
229
231
  loading: isLoading,
230
232
  className: b('groups-wrapper'),
231
233
  }}
@@ -11,6 +11,7 @@ import type {PreparedStorageNode} from '../../../store/reducers/storage/types';
11
11
  import type {NodesGroupByField} from '../../../types/api/nodes';
12
12
  import {useSelectedColumns} from '../../../utils/hooks/useSelectedColumns';
13
13
  import {NodesTable} from '../NodesTable';
14
+ import {useDebouncedSearch} from '../useDebouncedSearch';
14
15
  import {useNodesPageQueryParams} from '../useNodesPageQueryParams';
15
16
 
16
17
  import {NodesControlsWithTableState} from './NodesControlsWithTableState';
@@ -46,6 +47,7 @@ export function NodesComponent({
46
47
  groupByParams,
47
48
  withPeerRoleFilter,
48
49
  );
50
+ const searchFilter = useDebouncedSearch(searchValue);
49
51
  const viewerNodesHandlerHasGrouping = useViewerNodesHandlerHasGrouping();
50
52
 
51
53
  const {columnsToShow, columnsToSelect, setColumns} = useSelectedColumns(
@@ -78,7 +80,7 @@ export function NodesComponent({
78
80
  path={path}
79
81
  database={database}
80
82
  databaseFullPath={databaseFullPath}
81
- searchValue={searchValue}
83
+ searchValue={searchFilter}
82
84
  withProblems={withProblems}
83
85
  uptimeFilter={uptimeFilter}
84
86
  peerRoleFilter={peerRoleFilter}
@@ -89,7 +91,7 @@ export function NodesComponent({
89
91
  }
90
92
  tableWrapperProps={{
91
93
  scrollContainerRef,
92
- scrollDependencies: [searchValue, withProblems, uptimeFilter, peerRoleFilter],
94
+ scrollDependencies: [searchFilter, withProblems, uptimeFilter, peerRoleFilter],
93
95
  }}
94
96
  />
95
97
  );
@@ -0,0 +1,13 @@
1
+ import React from 'react';
2
+
3
+ /** Debounce the table filter, never the input or its URL value. */
4
+ export function useDebouncedSearch(searchValue: string) {
5
+ const [debouncedSearch, setDebouncedSearch] = React.useState(searchValue);
6
+
7
+ React.useEffect(() => {
8
+ const timer = window.setTimeout(() => setDebouncedSearch(searchValue), 200);
9
+ return () => window.clearTimeout(timer);
10
+ }, [searchValue]);
11
+
12
+ return debouncedSearch;
13
+ }
@@ -4,12 +4,14 @@
4
4
  position: relative;
5
5
 
6
6
  overflow: auto;
7
+ overflow-anchor: none;
7
8
 
8
9
  height: 100%;
9
- padding: 0 20px;
10
+ padding: 20px 20px 0;
10
11
 
11
12
  &__meta,
12
13
  &__title,
14
+ &__storage-details,
13
15
  &__info,
14
16
  &__controls,
15
17
  &__tabs {
@@ -19,8 +21,23 @@
19
21
  margin-bottom: 20px;
20
22
  }
21
23
 
22
- &__meta {
23
- margin-top: 20px;
24
+ &__heading {
25
+ margin: 0;
26
+ overflow-wrap: anywhere;
27
+ }
28
+
29
+ &__title-content {
30
+ flex: 1;
31
+
32
+ min-width: 0;
33
+ }
34
+
35
+ &__refresh-control {
36
+ flex-shrink: 0;
37
+ }
38
+
39
+ &__storage-details {
40
+ margin-bottom: var(--g-spacing-4);
24
41
  }
25
42
 
26
43
  &__tabs {
@@ -31,17 +48,11 @@
31
48
  padding: 20px 0;
32
49
  }
33
50
 
34
- &__title {
35
- display: flex;
36
- flex-direction: row;
37
- align-items: center;
38
- gap: var(--g-spacing-2);
39
- }
40
-
41
51
  &__controls {
42
52
  display: flex;
53
+ flex-wrap: wrap;
43
54
  align-items: center;
44
- gap: var(--g-spacing-2);
55
+ gap: var(--g-spacing-3);
45
56
  }
46
57
 
47
58
  &__tabs {