@scality/data-browser-library 1.0.0-preview.9 → 1.0.1

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 (285) hide show
  1. package/dist/components/DataBrowserUI.d.ts +12 -0
  2. package/dist/components/DataBrowserUI.js +99 -0
  3. package/dist/components/Editor.d.ts +1 -1
  4. package/dist/components/Editor.js +3 -3
  5. package/dist/components/__tests__/BucketAccessor.test.js +214 -0
  6. package/dist/components/__tests__/BucketCorsPage.test.d.ts +1 -0
  7. package/dist/components/__tests__/BucketCorsPage.test.js +263 -0
  8. package/dist/components/__tests__/BucketCreate.test.js +271 -105
  9. package/dist/components/__tests__/BucketDetails.test.d.ts +1 -0
  10. package/dist/components/__tests__/BucketDetails.test.js +421 -0
  11. package/dist/components/__tests__/BucketLifecycleFormPage.test.d.ts +13 -0
  12. package/dist/components/__tests__/BucketLifecycleFormPage.test.js +178 -178
  13. package/dist/components/__tests__/BucketLifecycleList.test.js +85 -85
  14. package/dist/components/__tests__/BucketList.test.js +463 -239
  15. package/dist/components/__tests__/BucketNotificationFormPage.test.d.ts +1 -0
  16. package/dist/components/__tests__/BucketNotificationFormPage.test.js +348 -0
  17. package/dist/components/__tests__/BucketNotificationList.test.d.ts +1 -0
  18. package/dist/components/__tests__/BucketNotificationList.test.js +379 -0
  19. package/dist/components/__tests__/BucketOverview.test.js +281 -266
  20. package/dist/components/__tests__/BucketPolicyPage.test.js +151 -99
  21. package/dist/components/__tests__/BucketReplicationFormPage.test.d.ts +15 -0
  22. package/dist/components/__tests__/BucketReplicationFormPage.test.js +544 -544
  23. package/dist/components/__tests__/BucketReplicationList.test.js +106 -106
  24. package/dist/components/__tests__/CreateFolderButton.test.js +56 -56
  25. package/dist/components/__tests__/DeleteBucketButton.test.js +64 -64
  26. package/dist/components/__tests__/DeleteBucketConfigRuleButton.test.js +47 -47
  27. package/dist/components/__tests__/DeleteObjectButton.test.js +64 -64
  28. package/dist/components/__tests__/EmptyBucketButton.test.js +59 -59
  29. package/dist/components/__tests__/MetadataSearch.test.js +65 -65
  30. package/dist/components/__tests__/ObjectList.test.js +741 -240
  31. package/dist/components/__tests__/UploadButton.test.js +45 -45
  32. package/dist/components/breadcrumb/Breadcrumb.d.ts +6 -0
  33. package/dist/components/breadcrumb/Breadcrumb.js +37 -0
  34. package/dist/components/breadcrumb/DataBrowserBreadcrumb.d.ts +1 -0
  35. package/dist/components/breadcrumb/DataBrowserBreadcrumb.js +10 -0
  36. package/dist/components/breadcrumb/__tests__/Breadcrumb.test.d.ts +1 -0
  37. package/dist/components/breadcrumb/__tests__/Breadcrumb.test.js +196 -0
  38. package/dist/components/breadcrumb/__tests__/DataBrowserBreadcrumb.test.d.ts +1 -0
  39. package/dist/components/breadcrumb/__tests__/DataBrowserBreadcrumb.test.js +153 -0
  40. package/dist/components/breadcrumb/__tests__/useBreadcrumbPaths.test.d.ts +1 -0
  41. package/dist/components/breadcrumb/__tests__/useBreadcrumbPaths.test.js +134 -0
  42. package/dist/components/breadcrumb/index.d.ts +8 -0
  43. package/dist/components/breadcrumb/index.js +4 -0
  44. package/dist/components/breadcrumb/useBreadcrumbPaths.d.ts +2 -0
  45. package/dist/components/breadcrumb/useBreadcrumbPaths.js +82 -0
  46. package/dist/components/buckets/BucketAccessor.d.ts +2 -0
  47. package/dist/components/buckets/BucketAccessor.js +125 -0
  48. package/dist/components/buckets/BucketConfigEditButton.d.ts +8 -0
  49. package/dist/components/buckets/{BucketPolicyButton.js → BucketConfigEditButton.js} +9 -5
  50. package/dist/components/buckets/BucketCorsPage.d.ts +1 -0
  51. package/dist/components/buckets/BucketCorsPage.js +234 -0
  52. package/dist/components/buckets/BucketCreate.d.ts +3 -2
  53. package/dist/components/buckets/BucketCreate.js +89 -47
  54. package/dist/components/buckets/BucketDetails.d.ts +42 -0
  55. package/dist/components/buckets/BucketDetails.js +249 -85
  56. package/dist/components/buckets/BucketLifecycleFormPage.js +206 -190
  57. package/dist/components/buckets/BucketLifecycleList.d.ts +2 -2
  58. package/dist/components/buckets/BucketLifecycleList.js +47 -47
  59. package/dist/components/buckets/BucketList.d.ts +7 -8
  60. package/dist/components/buckets/BucketList.js +158 -101
  61. package/dist/components/buckets/BucketLocation.js +4 -4
  62. package/dist/components/buckets/BucketOverview.d.ts +22 -2
  63. package/dist/components/buckets/BucketOverview.js +394 -187
  64. package/dist/components/buckets/BucketPage.js +43 -21
  65. package/dist/components/buckets/BucketPolicyPage.js +155 -127
  66. package/dist/components/buckets/BucketReplicationFormPage.js +134 -133
  67. package/dist/components/buckets/BucketReplicationList.d.ts +2 -2
  68. package/dist/components/buckets/BucketReplicationList.js +42 -42
  69. package/dist/components/buckets/BucketVersioning.d.ts +4 -0
  70. package/dist/components/buckets/BucketVersioning.js +76 -0
  71. package/dist/components/buckets/DeleteBucketButton.js +8 -8
  72. package/dist/components/buckets/DeleteBucketConfigRuleButton.d.ts +2 -2
  73. package/dist/components/buckets/DeleteBucketConfigRuleButton.js +2 -2
  74. package/dist/components/buckets/EmptyBucketButton.js +24 -24
  75. package/dist/components/buckets/EmptyBucketSummary.d.ts +2 -2
  76. package/dist/components/buckets/EmptyBucketSummary.js +1 -1
  77. package/dist/components/buckets/EmptyBucketSummaryList.d.ts +1 -1
  78. package/dist/components/buckets/EmptyBucketSummaryList.js +22 -22
  79. package/dist/components/buckets/__tests__/BucketVersioning.test.d.ts +1 -0
  80. package/dist/components/buckets/__tests__/BucketVersioning.test.js +163 -0
  81. package/dist/components/buckets/notifications/BucketNotificationFormPage.d.ts +1 -0
  82. package/dist/components/buckets/notifications/BucketNotificationFormPage.js +316 -0
  83. package/dist/components/buckets/notifications/BucketNotificationList.d.ts +10 -0
  84. package/dist/components/buckets/notifications/BucketNotificationList.js +267 -0
  85. package/dist/components/buckets/notifications/EventsSection.js +145 -29
  86. package/dist/components/buckets/notifications/__tests__/events.test.d.ts +1 -0
  87. package/dist/components/buckets/notifications/__tests__/events.test.js +56 -0
  88. package/dist/components/buckets/notifications/events.d.ts +71 -7
  89. package/dist/components/buckets/notifications/events.js +98 -16
  90. package/dist/components/index.d.ts +27 -20
  91. package/dist/components/index.js +17 -10
  92. package/dist/components/layouts/ArrowNavigation.d.ts +3 -0
  93. package/dist/components/layouts/ArrowNavigation.js +28 -0
  94. package/dist/components/layouts/BrowserPageLayout.d.ts +5 -1
  95. package/dist/components/layouts/BrowserPageLayout.js +10 -5
  96. package/dist/components/objects/CreateFolderButton.d.ts +2 -2
  97. package/dist/components/objects/CreateFolderButton.js +12 -12
  98. package/dist/components/objects/DeleteObjectButton.d.ts +1 -1
  99. package/dist/components/objects/DeleteObjectButton.js +19 -21
  100. package/dist/components/objects/GetPresignedUrlButton.d.ts +7 -0
  101. package/dist/components/objects/GetPresignedUrlButton.js +255 -0
  102. package/dist/components/objects/ObjectDetails/ObjectMetadata.d.ts +2 -2
  103. package/dist/components/objects/ObjectDetails/ObjectMetadata.js +263 -230
  104. package/dist/components/objects/ObjectDetails/ObjectSummary.d.ts +2 -2
  105. package/dist/components/objects/ObjectDetails/ObjectSummary.js +540 -138
  106. package/dist/components/objects/ObjectDetails/ObjectTags.d.ts +2 -2
  107. package/dist/components/objects/ObjectDetails/ObjectTags.js +95 -123
  108. package/dist/components/objects/ObjectDetails/__tests__/ObjectDetails.test.d.ts +1 -0
  109. package/dist/components/objects/ObjectDetails/__tests__/ObjectDetails.test.js +516 -0
  110. package/dist/components/objects/ObjectDetails/__tests__/ObjectSummary.test.d.ts +1 -0
  111. package/dist/components/objects/ObjectDetails/__tests__/ObjectSummary.test.js +1064 -0
  112. package/dist/components/objects/ObjectDetails/index.d.ts +18 -2
  113. package/dist/components/objects/ObjectDetails/index.js +152 -40
  114. package/dist/components/objects/ObjectList.d.ts +12 -10
  115. package/dist/components/objects/ObjectList.js +590 -263
  116. package/dist/components/objects/ObjectLock/EditRetentionButton.js +4 -4
  117. package/dist/components/objects/ObjectLock/ObjectLockRetentionSettings.js +15 -15
  118. package/dist/components/objects/ObjectLock/ObjectLockSettings.d.ts +1 -1
  119. package/dist/components/objects/ObjectLock/ObjectLockSettings.js +32 -31
  120. package/dist/components/objects/ObjectLock/ObjectLockSettingsUtils.d.ts +1 -1
  121. package/dist/components/objects/ObjectLock/ObjectLockSettingsUtils.js +6 -6
  122. package/dist/components/objects/ObjectLock/__tests__/EditRetentionButton.test.js +51 -51
  123. package/dist/components/objects/ObjectLock/__tests__/ObjectLockSettings.test.js +78 -78
  124. package/dist/components/objects/ObjectPage.js +12 -8
  125. package/dist/components/objects/UploadButton.d.ts +3 -3
  126. package/dist/components/objects/UploadButton.js +10 -10
  127. package/dist/components/objects/__tests__/GetPresignedUrlButton.test.d.ts +1 -0
  128. package/dist/components/objects/__tests__/GetPresignedUrlButton.test.js +531 -0
  129. package/dist/components/providers/DataBrowserProvider.d.ts +23 -12
  130. package/dist/components/providers/DataBrowserProvider.js +60 -38
  131. package/dist/components/providers/QueryProvider.d.ts +9 -0
  132. package/dist/components/providers/QueryProvider.js +21 -0
  133. package/dist/components/search/MetadataSearch.js +29 -28
  134. package/dist/components/search/SearchHints.js +1 -1
  135. package/dist/components/ui/ArrayFieldActions.js +12 -7
  136. package/dist/components/ui/ConfirmDeleteRuleModal.d.ts +2 -2
  137. package/dist/components/ui/ConfirmDeleteRuleModal.js +6 -1
  138. package/dist/components/ui/DeleteObjectModalContent.d.ts +1 -1
  139. package/dist/components/ui/DeleteObjectModalContent.js +12 -12
  140. package/dist/components/ui/FilterFormSection.d.ts +2 -2
  141. package/dist/components/ui/FilterFormSection.js +29 -29
  142. package/dist/components/ui/Search.elements.d.ts +2 -2
  143. package/dist/components/ui/Search.elements.js +7 -7
  144. package/dist/components/ui/Table.elements.d.ts +2 -1
  145. package/dist/components/ui/Table.elements.js +18 -12
  146. package/dist/config/__tests__/factory.test.d.ts +1 -0
  147. package/dist/config/__tests__/factory.test.js +311 -0
  148. package/dist/config/factory.d.ts +10 -56
  149. package/dist/config/factory.js +23 -71
  150. package/dist/config/types.d.ts +212 -34
  151. package/dist/contexts/DataBrowserUICustomizationContext.d.ts +27 -0
  152. package/dist/contexts/DataBrowserUICustomizationContext.js +13 -0
  153. package/dist/hooks/__tests__/useAccessibleBuckets.test.d.ts +1 -0
  154. package/dist/hooks/__tests__/useAccessibleBuckets.test.js +145 -0
  155. package/dist/hooks/__tests__/useISVBucketDetection.test.js +45 -45
  156. package/dist/hooks/__tests__/useIsBucketEmpty.test.js +27 -27
  157. package/dist/hooks/__tests__/useLoginMutation.test.d.ts +1 -0
  158. package/dist/hooks/__tests__/useLoginMutation.test.js +194 -0
  159. package/dist/hooks/bucketConfiguration.d.ts +8 -1
  160. package/dist/hooks/bucketConfiguration.js +52 -51
  161. package/dist/hooks/bucketOperations.d.ts +10 -1
  162. package/dist/hooks/bucketOperations.js +10 -9
  163. package/dist/hooks/factories/__tests__/useCreateS3FunctionMutationHook.test.js +80 -80
  164. package/dist/hooks/factories/__tests__/useCreateS3InfiniteQueryHook.test.js +80 -80
  165. package/dist/hooks/factories/__tests__/useCreateS3LoginHook.test.js +44 -44
  166. package/dist/hooks/factories/__tests__/useCreateS3MutationHook.test.js +63 -63
  167. package/dist/hooks/factories/__tests__/useCreateS3QueryHook.test.js +65 -65
  168. package/dist/hooks/factories/index.d.ts +4 -4
  169. package/dist/hooks/factories/index.js +2 -2
  170. package/dist/hooks/factories/useCreateS3InfiniteQueryHook.d.ts +2 -2
  171. package/dist/hooks/factories/useCreateS3InfiniteQueryHook.js +16 -13
  172. package/dist/hooks/factories/useCreateS3LoginHook.d.ts +2 -2
  173. package/dist/hooks/factories/useCreateS3LoginHook.js +1 -1
  174. package/dist/hooks/factories/useCreateS3MutationHook.d.ts +3 -3
  175. package/dist/hooks/factories/useCreateS3MutationHook.js +7 -2
  176. package/dist/hooks/factories/useCreateS3QueryHook.d.ts +2 -2
  177. package/dist/hooks/factories/useCreateS3QueryHook.js +11 -6
  178. package/dist/hooks/index.d.ts +19 -12
  179. package/dist/hooks/index.js +16 -9
  180. package/dist/hooks/loginOperations.d.ts +1 -1
  181. package/dist/hooks/loginOperations.js +1 -1
  182. package/dist/hooks/objectOperations.d.ts +2 -2
  183. package/dist/hooks/objectOperations.js +50 -49
  184. package/dist/hooks/presignedOperations.d.ts +4 -4
  185. package/dist/hooks/presignedOperations.js +5 -5
  186. package/dist/hooks/useAccessibleBuckets.d.ts +11 -0
  187. package/dist/hooks/useAccessibleBuckets.js +115 -0
  188. package/dist/hooks/useBatchObjectLegalHold.d.ts +11 -0
  189. package/dist/hooks/useBatchObjectLegalHold.js +48 -0
  190. package/dist/hooks/useBucketConfigEditor.d.ts +31 -0
  191. package/dist/hooks/useBucketConfigEditor.js +82 -0
  192. package/dist/hooks/useDataBrowserNavigate.d.ts +28 -0
  193. package/dist/hooks/useDataBrowserNavigate.js +24 -0
  194. package/dist/hooks/useDeleteBucketConfigRule.d.ts +2 -2
  195. package/dist/hooks/useDeleteBucketConfigRule.js +4 -4
  196. package/dist/hooks/useEmptyBucket.js +11 -11
  197. package/dist/hooks/useFeatures.d.ts +7 -0
  198. package/dist/hooks/useFeatures.js +8 -0
  199. package/dist/hooks/useISVBucketDetection.js +6 -6
  200. package/dist/hooks/useIsBucketEmpty.js +4 -4
  201. package/dist/hooks/useLimitedAccessFlow.d.ts +48 -0
  202. package/dist/hooks/useLimitedAccessFlow.js +23 -0
  203. package/dist/hooks/useS3Client.d.ts +6 -0
  204. package/dist/hooks/useS3Client.js +3 -2
  205. package/dist/hooks/useS3ConfigSwitch.d.ts +11 -0
  206. package/dist/hooks/useS3ConfigSwitch.js +37 -0
  207. package/dist/hooks/useSupportedNotificationEvents.d.ts +6 -0
  208. package/dist/hooks/useSupportedNotificationEvents.js +8 -0
  209. package/dist/index.d.ts +6 -6
  210. package/dist/index.js +2 -2
  211. package/dist/schemas/bucketPolicySchema.json +3 -13
  212. package/dist/test/msw/handlers/deleteBucket.d.ts +1 -1
  213. package/dist/test/msw/handlers/deleteBucket.js +20 -10
  214. package/dist/test/msw/handlers/getBucketAcl.d.ts +1 -1
  215. package/dist/test/msw/handlers/getBucketAcl.js +29 -17
  216. package/dist/test/msw/handlers/getBucketLocation.d.ts +1 -1
  217. package/dist/test/msw/handlers/getBucketLocation.js +29 -15
  218. package/dist/test/msw/handlers/getBucketPolicy.d.ts +1 -1
  219. package/dist/test/msw/handlers/getBucketPolicy.js +52 -32
  220. package/dist/test/msw/handlers/headObject.d.ts +1 -1
  221. package/dist/test/msw/handlers/headObject.js +31 -13
  222. package/dist/test/msw/handlers/listBuckets.d.ts +1 -1
  223. package/dist/test/msw/handlers/listBuckets.js +5 -3
  224. package/dist/test/msw/handlers/listObjectVersions.d.ts +1 -1
  225. package/dist/test/msw/handlers/listObjectVersions.js +38 -26
  226. package/dist/test/msw/handlers/listObjects.d.ts +1 -1
  227. package/dist/test/msw/handlers/listObjects.js +35 -23
  228. package/dist/test/msw/handlers/objectLegalHold.d.ts +1 -1
  229. package/dist/test/msw/handlers/objectLegalHold.js +32 -17
  230. package/dist/test/msw/handlers/objectRetention.d.ts +1 -1
  231. package/dist/test/msw/handlers/objectRetention.js +31 -17
  232. package/dist/test/msw/handlers/putBucketAcl.d.ts +1 -1
  233. package/dist/test/msw/handlers/putBucketAcl.js +29 -14
  234. package/dist/test/msw/handlers/putObject.d.ts +1 -1
  235. package/dist/test/msw/handlers/putObject.js +27 -12
  236. package/dist/test/msw/handlers.d.ts +3 -3
  237. package/dist/test/msw/handlers.js +77 -54
  238. package/dist/test/msw/index.d.ts +2 -2
  239. package/dist/test/msw/index.js +1 -1
  240. package/dist/test/msw/server.d.ts +1 -1
  241. package/dist/test/msw/server.js +1 -1
  242. package/dist/test/msw/utils.js +2 -2
  243. package/dist/test/setup.d.ts +1 -1
  244. package/dist/test/setup.js +13 -30
  245. package/dist/test/testUtils.d.ts +85 -33
  246. package/dist/test/testUtils.js +176 -111
  247. package/dist/test/utils/errorHandling.test.js +119 -119
  248. package/dist/types/index.d.ts +49 -36
  249. package/dist/types/monaco.d.ts +13 -0
  250. package/dist/types/monaco.js +0 -0
  251. package/dist/utils/__tests__/proxyMiddleware.test.d.ts +1 -0
  252. package/dist/utils/__tests__/proxyMiddleware.test.js +579 -0
  253. package/dist/utils/__tests__/s3Client.test.d.ts +1 -0
  254. package/dist/utils/__tests__/s3Client.test.js +340 -0
  255. package/dist/utils/__tests__/s3ConfigIdentifier.test.d.ts +1 -0
  256. package/dist/utils/__tests__/s3ConfigIdentifier.test.js +437 -0
  257. package/dist/utils/constants.d.ts +10 -0
  258. package/dist/utils/constants.js +19 -9
  259. package/dist/utils/deletion/index.d.ts +2 -2
  260. package/dist/utils/deletion/index.js +1 -1
  261. package/dist/utils/deletion/messages.d.ts +1 -1
  262. package/dist/utils/deletion/messages.js +4 -4
  263. package/dist/utils/errorHandling.d.ts +3 -3
  264. package/dist/utils/errorHandling.js +6 -6
  265. package/dist/utils/hooks.js +8 -8
  266. package/dist/utils/index.d.ts +5 -4
  267. package/dist/utils/index.js +4 -2
  268. package/dist/utils/proxyMiddleware.d.ts +32 -13
  269. package/dist/utils/proxyMiddleware.js +90 -36
  270. package/dist/utils/s3Client.d.ts +14 -4
  271. package/dist/utils/s3Client.js +5 -26
  272. package/dist/utils/s3ConfigIdentifier.d.ts +79 -0
  273. package/dist/utils/s3ConfigIdentifier.js +57 -0
  274. package/dist/utils/s3RuleUtils.d.ts +5 -5
  275. package/dist/utils/s3RuleUtils.js +17 -17
  276. package/package.json +10 -8
  277. package/dist/components/__tests__/BucketNotificationCreatePage.test.js +0 -316
  278. package/dist/components/buckets/BucketPolicyButton.d.ts +0 -7
  279. package/dist/components/buckets/notifications/BucketNotificationCreatePage.d.ts +0 -1
  280. package/dist/components/buckets/notifications/BucketNotificationCreatePage.js +0 -234
  281. package/dist/hooks/useLoginMutation.d.ts +0 -21
  282. package/dist/hooks/useLoginMutation.js +0 -9
  283. package/dist/utils/useFeatures.d.ts +0 -1
  284. package/dist/utils/useFeatures.js +0 -7
  285. /package/dist/components/__tests__/{BucketNotificationCreatePage.test.d.ts → BucketAccessor.test.d.ts} +0 -0
@@ -3,6 +3,10 @@ import { fireEvent, render, screen } from "@testing-library/react";
3
3
  import { MemoryRouter } from "react-router";
4
4
  import { createTestWrapper, mockOffsetSize } from "../../test/testUtils.js";
5
5
  import { BucketList } from "../buckets/BucketList.js";
6
+ import * as __rspack_external__contexts_DataBrowserUICustomizationContext_js_f267b01c from "../../contexts/DataBrowserUICustomizationContext.js";
7
+ const mockUseDataBrowserUICustomization = (config = {})=>{
8
+ jest.spyOn(__rspack_external__contexts_DataBrowserUICustomizationContext_js_f267b01c, 'useDataBrowserUICustomization').mockReturnValue(config);
9
+ };
6
10
  const renderBucketList = (props = {})=>{
7
11
  const Wrapper = createTestWrapper();
8
12
  return render(/*#__PURE__*/ jsx(MemoryRouter, {
@@ -16,190 +20,169 @@ const renderBucketList = (props = {})=>{
16
20
  };
17
21
  const mockBuckets = [
18
22
  {
19
- Name: "test-bucket-1",
20
- CreationDate: new Date("2024-01-15T10:30:00Z")
23
+ Name: 'test-bucket-1',
24
+ CreationDate: new Date('2024-01-15T10:30:00Z')
21
25
  },
22
26
  {
23
- Name: "test-bucket-2",
24
- CreationDate: new Date("2024-01-16T14:45:00Z")
27
+ Name: 'test-bucket-2',
28
+ CreationDate: new Date('2024-01-16T14:45:00Z')
25
29
  },
26
30
  {
27
- Name: "test-bucket-3",
28
- CreationDate: new Date("2024-01-17T09:15:00Z")
31
+ Name: 'test-bucket-3',
32
+ CreationDate: new Date('2024-01-17T09:15:00Z')
29
33
  }
30
34
  ];
31
- describe("BucketList", ()=>{
35
+ describe('BucketList', ()=>{
32
36
  beforeEach(()=>{
33
37
  jest.clearAllMocks();
34
38
  mockOffsetSize(800, 600);
39
+ mockUseDataBrowserUICustomization({});
35
40
  });
36
- it("shows a table with proper headers", ()=>{
41
+ it('shows a table with proper headers', ()=>{
37
42
  renderBucketList({
38
43
  buckets: mockBuckets
39
44
  });
40
- expect(screen.getByRole("grid")).toBeInTheDocument();
41
- expect(screen.getByText("Bucket Name")).toBeInTheDocument();
42
- expect(screen.getByText("Storage Location")).toBeInTheDocument();
43
- expect(screen.getByText("Created on")).toBeInTheDocument();
45
+ expect(screen.getByRole('grid')).toBeInTheDocument();
46
+ expect(screen.getByText('Bucket Name')).toBeInTheDocument();
47
+ expect(screen.getByText('Storage Location')).toBeInTheDocument();
48
+ expect(screen.getByText('Created on')).toBeInTheDocument();
44
49
  });
45
- it("displays buckets with their names as clickable links", ()=>{
50
+ it('displays buckets with their names as clickable links', ()=>{
46
51
  const onNavigateToBucket = jest.fn();
47
52
  renderBucketList({
48
53
  buckets: mockBuckets,
49
54
  onNavigateToBucket
50
55
  });
51
- expect(screen.getByText("test-bucket-1")).toBeInTheDocument();
52
- expect(screen.getByText("test-bucket-2")).toBeInTheDocument();
53
- expect(screen.getByText("test-bucket-3")).toBeInTheDocument();
54
- fireEvent.click(screen.getByText("test-bucket-1"));
55
- expect(onNavigateToBucket).toHaveBeenCalledWith("test-bucket-1");
56
+ expect(screen.getByText('test-bucket-1')).toBeInTheDocument();
57
+ expect(screen.getByText('test-bucket-2')).toBeInTheDocument();
58
+ expect(screen.getByText('test-bucket-3')).toBeInTheDocument();
59
+ fireEvent.click(screen.getByText('test-bucket-1'));
60
+ expect(onNavigateToBucket).toHaveBeenCalledWith('test-bucket-1');
56
61
  });
57
- it("displays creation dates in formatted format", ()=>{
62
+ it('displays creation dates in formatted format', ()=>{
58
63
  renderBucketList({
59
64
  buckets: mockBuckets
60
65
  });
61
- const gridElement = screen.getByRole("grid");
62
- expect(gridElement).toHaveTextContent("2024");
66
+ const gridElement = screen.getByRole('grid');
67
+ expect(gridElement).toHaveTextContent('2024');
63
68
  const dateElements = screen.getAllByText(/2024/);
64
69
  expect(dateElements.length).toBeGreaterThanOrEqual(3);
65
70
  });
66
- it("shows storage location when renderBucketLocation is provided", ()=>{
67
- const renderBucketLocation = jest.fn((bucketName)=>/*#__PURE__*/ jsxs("span", {
68
- children: [
69
- "Location for ",
70
- bucketName
71
- ]
72
- }));
73
- renderBucketList({
74
- buckets: mockBuckets,
75
- renderBucketLocation
76
- });
77
- expect(renderBucketLocation).toHaveBeenCalledWith("test-bucket-1");
78
- expect(renderBucketLocation).toHaveBeenCalledWith("test-bucket-2");
79
- expect(renderBucketLocation).toHaveBeenCalledWith("test-bucket-3");
80
- });
81
- it("shows dash for storage location when renderBucketLocation is not provided", ()=>{
82
- renderBucketList({
83
- buckets: mockBuckets
84
- });
85
- const dashes = screen.getAllByText("-");
86
- expect(dashes.length).toBeGreaterThan(0);
87
- });
88
- it("handles bucket selection when onBucketSelect is provided", ()=>{
71
+ it('handles bucket selection when onBucketSelect is provided', ()=>{
89
72
  const onBucketSelect = jest.fn();
90
73
  renderBucketList({
91
74
  buckets: mockBuckets,
92
75
  onBucketSelect
93
76
  });
94
- const rows = screen.getAllByRole("row");
77
+ const rows = screen.getAllByRole('row');
95
78
  fireEvent.click(rows[1]);
96
- expect(onBucketSelect).toHaveBeenCalledWith("test-bucket-3");
79
+ expect(onBucketSelect).toHaveBeenCalledWith('test-bucket-3');
97
80
  });
98
- it("shows selected bucket when selectedBucketName is provided", ()=>{
81
+ it('shows selected bucket when selectedBucketName is provided', ()=>{
99
82
  renderBucketList({
100
83
  buckets: mockBuckets,
101
- selectedBucketName: "test-bucket-2"
84
+ selectedBucketName: 'test-bucket-2'
102
85
  });
103
- const selectedRow = screen.getByRole("row", {
86
+ const selectedRow = screen.getByRole('row', {
104
87
  name: /test-bucket-2/
105
88
  });
106
- expect(selectedRow).toHaveAttribute("aria-selected", "true");
89
+ expect(selectedRow).toHaveAttribute('aria-selected', 'true');
107
90
  });
108
- it("handles create bucket button click", ()=>{
91
+ it('handles create bucket button click', ()=>{
109
92
  const onCreateBucket = jest.fn();
110
93
  renderBucketList({
111
94
  buckets: mockBuckets,
112
95
  onCreateBucket
113
96
  });
114
- const createButton = screen.getByRole("button", {
97
+ const createButton = screen.getByRole('button', {
115
98
  name: /create bucket/i
116
99
  });
117
100
  expect(createButton).toBeInTheDocument();
118
101
  fireEvent.click(createButton);
119
102
  expect(onCreateBucket).toHaveBeenCalled();
120
103
  });
121
- it("shows search functionality", ()=>{
104
+ it('shows search functionality', ()=>{
122
105
  renderBucketList({
123
106
  buckets: mockBuckets
124
107
  });
125
- const searchInput = screen.getByRole("searchbox");
108
+ const searchInput = screen.getByRole('searchbox');
126
109
  expect(searchInput).toBeInTheDocument();
127
- expect(searchInput).toHaveAttribute("placeholder", "Example: Search");
110
+ expect(searchInput).toHaveAttribute('placeholder', 'Example: Search');
128
111
  });
129
- it("handles empty buckets list", ()=>{
112
+ it('handles empty buckets list', ()=>{
130
113
  renderBucketList({
131
114
  buckets: []
132
115
  });
133
- expect(screen.getByRole("grid")).toBeInTheDocument();
134
- expect(screen.getByText("Bucket Name")).toBeInTheDocument();
116
+ expect(screen.getByRole('grid')).toBeInTheDocument();
117
+ expect(screen.getByText('Bucket Name')).toBeInTheDocument();
135
118
  });
136
- it("handles buckets without names gracefully", ()=>{
119
+ it('handles buckets without names gracefully', ()=>{
137
120
  const bucketsWithMissingNames = [
138
121
  {
139
122
  Name: void 0,
140
123
  CreationDate: new Date()
141
124
  },
142
125
  {
143
- Name: "",
126
+ Name: '',
144
127
  CreationDate: new Date()
145
128
  },
146
129
  {
147
- Name: "valid-bucket",
130
+ Name: 'valid-bucket',
148
131
  CreationDate: new Date()
149
132
  }
150
133
  ];
151
134
  renderBucketList({
152
135
  buckets: bucketsWithMissingNames
153
136
  });
154
- expect(screen.getByText("valid-bucket")).toBeInTheDocument();
155
- const dashes = screen.getAllByText("-");
137
+ expect(screen.getByText('valid-bucket')).toBeInTheDocument();
138
+ const dashes = screen.getAllByText('-');
156
139
  expect(dashes.length).toBeGreaterThan(0);
157
140
  });
158
- it("handles buckets without creation dates", ()=>{
141
+ it('handles buckets without creation dates', ()=>{
159
142
  const bucketsWithoutDates = [
160
143
  {
161
- Name: "bucket-1",
144
+ Name: 'bucket-1',
162
145
  CreationDate: void 0
163
146
  },
164
147
  {
165
- Name: "bucket-2"
148
+ Name: 'bucket-2'
166
149
  }
167
150
  ];
168
151
  renderBucketList({
169
152
  buckets: bucketsWithoutDates
170
153
  });
171
- expect(screen.getByText("bucket-1")).toBeInTheDocument();
172
- expect(screen.getByText("bucket-2")).toBeInTheDocument();
154
+ expect(screen.getByText('bucket-1')).toBeInTheDocument();
155
+ expect(screen.getByText('bucket-2')).toBeInTheDocument();
173
156
  });
174
- it("works when no callbacks are provided", ()=>{
157
+ it('works when no callbacks are provided', ()=>{
175
158
  renderBucketList({
176
159
  buckets: mockBuckets
177
160
  });
178
161
  expect(()=>{
179
- fireEvent.click(screen.getByText("test-bucket-1"));
180
- const createButton = screen.getByRole("button", {
162
+ fireEvent.click(screen.getByText('test-bucket-1'));
163
+ const createButton = screen.getByRole('button', {
181
164
  name: /create bucket/i
182
165
  });
183
166
  fireEvent.click(createButton);
184
167
  }).not.toThrow();
185
168
  });
186
- it("handles different bucket statuses", ()=>{
169
+ it('handles different bucket statuses', ()=>{
187
170
  expect(()=>{
188
171
  renderBucketList({
189
172
  buckets: mockBuckets,
190
- bucketStatus: "loading"
173
+ bucketStatus: 'loading'
191
174
  });
192
175
  renderBucketList({
193
176
  buckets: mockBuckets,
194
- bucketStatus: "error"
177
+ bucketStatus: 'error'
195
178
  });
196
179
  renderBucketList({
197
180
  buckets: mockBuckets,
198
- bucketStatus: "success"
181
+ bucketStatus: 'success'
199
182
  });
200
183
  }).not.toThrow();
201
184
  });
202
- it("prevents event propagation when clicking bucket name link", ()=>{
185
+ it('prevents event propagation when clicking bucket name link', ()=>{
203
186
  const onNavigateToBucket = jest.fn();
204
187
  const onBucketSelect = jest.fn();
205
188
  renderBucketList({
@@ -207,209 +190,450 @@ describe("BucketList", ()=>{
207
190
  onNavigateToBucket,
208
191
  onBucketSelect
209
192
  });
210
- fireEvent.click(screen.getByText("test-bucket-1"));
211
- expect(onNavigateToBucket).toHaveBeenCalledWith("test-bucket-1");
193
+ fireEvent.click(screen.getByText('test-bucket-1'));
194
+ expect(onNavigateToBucket).toHaveBeenCalledWith('test-bucket-1');
212
195
  expect(onBucketSelect).not.toHaveBeenCalled();
213
196
  });
214
- it("does not select already selected bucket", ()=>{
197
+ it('does not select already selected bucket', ()=>{
215
198
  const onBucketSelect = jest.fn();
216
199
  renderBucketList({
217
200
  buckets: mockBuckets,
218
- selectedBucketName: "test-bucket-1",
201
+ selectedBucketName: 'test-bucket-1',
219
202
  onBucketSelect
220
203
  });
221
- const bucketName = screen.getByText("test-bucket-1");
204
+ const bucketName = screen.getByText('test-bucket-1');
222
205
  fireEvent.click(bucketName.closest('[role="row"]') || bucketName);
223
206
  expect(onBucketSelect).not.toHaveBeenCalled();
224
207
  });
225
- describe("additionalColumns support", ()=>{
226
- it("renders additional columns when additionalColumns prop is provided", ()=>{
227
- const additionalColumns = [
228
- {
229
- Header: "Metrics",
230
- accessor: "metrics",
231
- id: "metrics",
232
- Cell: ()=>/*#__PURE__*/ jsx("span", {
233
- children: "Metrics Data"
234
- })
235
- }
236
- ];
208
+ describe('extraBucketListColumns support', ()=>{
209
+ it('renders extra columns when extraBucketListColumns is configured', ()=>{
210
+ const CustomColumn = ({ data })=>/*#__PURE__*/ jsxs("span", {
211
+ children: [
212
+ "Custom data for ",
213
+ data.Name
214
+ ]
215
+ });
216
+ mockUseDataBrowserUICustomization({
217
+ extraBucketListColumns: [
218
+ {
219
+ id: 'customData',
220
+ header: 'Custom Data',
221
+ render: CustomColumn
222
+ }
223
+ ]
224
+ });
237
225
  renderBucketList({
238
- buckets: mockBuckets,
239
- additionalColumns
240
- });
241
- expect(screen.getByText("Metrics")).toBeInTheDocument();
242
- expect(screen.getAllByText("Metrics Data")).toHaveLength(3);
243
- });
244
- it("renders multiple additional columns in correct order", ()=>{
245
- const additionalColumns = [
246
- {
247
- Header: "Column A",
248
- accessor: "columnA",
249
- id: "columnA",
250
- Cell: ()=>/*#__PURE__*/ jsx("span", {
251
- children: "A"
252
- })
253
- },
254
- {
255
- Header: "Column B",
256
- accessor: "columnB",
257
- id: "columnB",
258
- Cell: ()=>/*#__PURE__*/ jsx("span", {
259
- children: "B"
260
- })
261
- }
262
- ];
226
+ buckets: mockBuckets
227
+ });
228
+ expect(screen.getByText('Custom Data')).toBeInTheDocument();
229
+ expect(screen.getByText('Custom data for test-bucket-1')).toBeInTheDocument();
230
+ expect(screen.getByText('Custom data for test-bucket-2')).toBeInTheDocument();
231
+ expect(screen.getByText('Custom data for test-bucket-3')).toBeInTheDocument();
232
+ });
233
+ it('renders multiple extra columns in correct order', ()=>{
234
+ const ColumnA = ()=>/*#__PURE__*/ jsx("span", {
235
+ children: "A"
236
+ });
237
+ const ColumnB = ()=>/*#__PURE__*/ jsx("span", {
238
+ children: "B"
239
+ });
240
+ mockUseDataBrowserUICustomization({
241
+ extraBucketListColumns: [
242
+ {
243
+ id: 'columnA',
244
+ header: 'Column A',
245
+ render: ColumnA
246
+ },
247
+ {
248
+ id: 'columnB',
249
+ header: 'Column B',
250
+ render: ColumnB
251
+ }
252
+ ]
253
+ });
263
254
  renderBucketList({
264
- buckets: mockBuckets,
265
- additionalColumns
255
+ buckets: mockBuckets
266
256
  });
267
- const headers = screen.getAllByRole("columnheader");
257
+ const headers = screen.getAllByRole('columnheader');
268
258
  const headerTexts = headers.map((h)=>h.textContent);
269
- expect(headerTexts).toContain("Bucket Name");
270
- expect(headerTexts).toContain("Storage Location");
271
- expect(headerTexts).toContain("Column A");
272
- expect(headerTexts).toContain("Column B");
273
- expect(headerTexts).toContain("Created on");
274
- const bucketNameIndex = headerTexts.indexOf("Bucket Name");
275
- const storageLocationIndex = headerTexts.indexOf("Storage Location");
276
- const columnAIndex = headerTexts.indexOf("Column A");
277
- const columnBIndex = headerTexts.indexOf("Column B");
278
- const createdOnIndex = headerTexts.indexOf("Created on");
259
+ expect(headerTexts).toContain('Bucket Name');
260
+ expect(headerTexts).toContain('Storage Location');
261
+ expect(headerTexts).toContain('Column A');
262
+ expect(headerTexts).toContain('Column B');
263
+ expect(headerTexts).toContain('Created on');
264
+ const bucketNameIndex = headerTexts.indexOf('Bucket Name');
265
+ const storageLocationIndex = headerTexts.indexOf('Storage Location');
266
+ const columnAIndex = headerTexts.indexOf('Column A');
267
+ const columnBIndex = headerTexts.indexOf('Column B');
268
+ const createdOnIndex = headerTexts.indexOf('Created on');
279
269
  expect(bucketNameIndex).toBeLessThan(storageLocationIndex);
280
270
  expect(storageLocationIndex).toBeLessThan(columnAIndex);
281
271
  expect(columnAIndex).toBeLessThan(columnBIndex);
282
272
  expect(columnBIndex).toBeLessThan(createdOnIndex);
283
273
  });
284
- it("works without additional columns (backward compatibility)", ()=>{
274
+ it('works without extra columns (shows default columns)', ()=>{
285
275
  renderBucketList({
286
276
  buckets: mockBuckets
287
277
  });
288
- const headers = screen.getAllByRole("columnheader");
278
+ const headers = screen.getAllByRole('columnheader');
289
279
  const headerTexts = headers.map((h)=>h.textContent);
290
- expect(headerTexts).toContain("Bucket Name");
291
- expect(headerTexts).toContain("Storage Location");
292
- expect(headerTexts).toContain("Created on");
280
+ expect(headerTexts).toContain('Bucket Name');
281
+ expect(headerTexts).toContain('Storage Location');
282
+ expect(headerTexts).toContain('Created on');
293
283
  expect(headerTexts).toHaveLength(3);
294
284
  });
285
+ it('receives full bucket data in render component', ()=>{
286
+ const CustomColumn = jest.fn(({ data })=>/*#__PURE__*/ jsxs("span", {
287
+ children: [
288
+ "Bucket ",
289
+ data.Name
290
+ ]
291
+ }));
292
+ mockUseDataBrowserUICustomization({
293
+ extraBucketListColumns: [
294
+ {
295
+ id: 'customColumn',
296
+ header: 'Custom',
297
+ render: CustomColumn
298
+ }
299
+ ]
300
+ });
301
+ renderBucketList({
302
+ buckets: mockBuckets
303
+ });
304
+ expect(CustomColumn).toHaveBeenCalledWith(expect.objectContaining({
305
+ data: mockBuckets[0]
306
+ }), expect.anything());
307
+ });
308
+ it('supports custom column widths', ()=>{
309
+ const CustomColumn = ({ data })=>/*#__PURE__*/ jsxs("span", {
310
+ children: [
311
+ "Width: ",
312
+ data.Name
313
+ ]
314
+ });
315
+ mockUseDataBrowserUICustomization({
316
+ extraBucketListColumns: [
317
+ {
318
+ id: 'customWidth',
319
+ header: 'Custom Width',
320
+ width: '200px',
321
+ render: CustomColumn
322
+ }
323
+ ]
324
+ });
325
+ renderBucketList({
326
+ buckets: mockBuckets
327
+ });
328
+ expect(screen.getByText('Custom Width')).toBeInTheDocument();
329
+ expect(screen.getByText('Width: test-bucket-1')).toBeInTheDocument();
330
+ });
331
+ it('supports custom columns with IDs not in Bucket type (e.g., computed data)', ()=>{
332
+ const DataUsedColumn = ({ data })=>/*#__PURE__*/ jsxs("span", {
333
+ children: [
334
+ "Data used for ",
335
+ data.Name
336
+ ]
337
+ });
338
+ mockUseDataBrowserUICustomization({
339
+ extraBucketListColumns: [
340
+ {
341
+ id: 'dataUsed',
342
+ header: 'Data Used',
343
+ render: DataUsedColumn
344
+ }
345
+ ]
346
+ });
347
+ renderBucketList({
348
+ buckets: mockBuckets
349
+ });
350
+ expect(screen.getByText('Data Used')).toBeInTheDocument();
351
+ expect(screen.getByText('Data used for test-bucket-1')).toBeInTheDocument();
352
+ expect(screen.getByText('Data used for test-bucket-2')).toBeInTheDocument();
353
+ expect(screen.getByText('Data used for test-bucket-3')).toBeInTheDocument();
354
+ });
355
+ it('supports mixing native and custom column IDs', ()=>{
356
+ const RegionColumn = ({ data })=>/*#__PURE__*/ jsxs("span", {
357
+ children: [
358
+ "Region: ",
359
+ data.Name
360
+ ]
361
+ });
362
+ const MetricsColumn = ({ data })=>/*#__PURE__*/ jsxs("span", {
363
+ children: [
364
+ "Metrics for ",
365
+ data.Name
366
+ ]
367
+ });
368
+ mockUseDataBrowserUICustomization({
369
+ extraBucketListColumns: [
370
+ {
371
+ id: 'location',
372
+ header: 'Region',
373
+ render: RegionColumn
374
+ },
375
+ {
376
+ id: 'customMetrics',
377
+ header: 'Metrics',
378
+ render: MetricsColumn
379
+ }
380
+ ]
381
+ });
382
+ renderBucketList({
383
+ buckets: mockBuckets
384
+ });
385
+ expect(screen.queryByText('Storage Location')).not.toBeInTheDocument();
386
+ expect(screen.getByText('Region')).toBeInTheDocument();
387
+ expect(screen.getByText('Metrics')).toBeInTheDocument();
388
+ expect(screen.getByText('Region: test-bucket-1')).toBeInTheDocument();
389
+ expect(screen.getByText('Metrics for test-bucket-1')).toBeInTheDocument();
390
+ });
391
+ it('can replace default columns by using matching IDs', ()=>{
392
+ const CustomLocationColumn = ({ data })=>/*#__PURE__*/ jsxs("span", {
393
+ children: [
394
+ "Custom location for ",
395
+ data.Name
396
+ ]
397
+ });
398
+ mockUseDataBrowserUICustomization({
399
+ extraBucketListColumns: [
400
+ {
401
+ id: 'location',
402
+ header: 'Custom Location',
403
+ render: CustomLocationColumn
404
+ }
405
+ ]
406
+ });
407
+ renderBucketList({
408
+ buckets: mockBuckets
409
+ });
410
+ expect(screen.getByText('Custom Location')).toBeInTheDocument();
411
+ expect(screen.queryByText('Storage Location')).not.toBeInTheDocument();
412
+ expect(screen.getByText('Custom location for test-bucket-1')).toBeInTheDocument();
413
+ expect(screen.getByText('Custom location for test-bucket-2')).toBeInTheDocument();
414
+ expect(screen.getByText('Custom location for test-bucket-3')).toBeInTheDocument();
415
+ });
416
+ it('can replace multiple default columns simultaneously', ()=>{
417
+ const CustomLocationColumn = ({ data })=>/*#__PURE__*/ jsxs("span", {
418
+ children: [
419
+ "Loc: ",
420
+ data.Name
421
+ ]
422
+ });
423
+ const CustomDateColumn = ({ data })=>/*#__PURE__*/ jsxs("span", {
424
+ children: [
425
+ "Date: ",
426
+ data.CreationDate?.toString()
427
+ ]
428
+ });
429
+ mockUseDataBrowserUICustomization({
430
+ extraBucketListColumns: [
431
+ {
432
+ id: 'location',
433
+ header: 'Loc',
434
+ render: CustomLocationColumn
435
+ },
436
+ {
437
+ id: 'date',
438
+ header: 'Date',
439
+ render: CustomDateColumn
440
+ }
441
+ ]
442
+ });
443
+ renderBucketList({
444
+ buckets: mockBuckets
445
+ });
446
+ expect(screen.getByText('Loc')).toBeInTheDocument();
447
+ expect(screen.getByText('Date')).toBeInTheDocument();
448
+ expect(screen.queryByText('Storage Location')).not.toBeInTheDocument();
449
+ expect(screen.queryByText('Created on')).not.toBeInTheDocument();
450
+ expect(screen.getByText('Loc: test-bucket-1')).toBeInTheDocument();
451
+ });
452
+ it('maintains correct column order when replacing and adding columns', ()=>{
453
+ const CustomLocationColumn = ()=>/*#__PURE__*/ jsx("span", {
454
+ children: "Custom Loc"
455
+ });
456
+ const ExtraColumn = ()=>/*#__PURE__*/ jsx("span", {
457
+ children: "Extra"
458
+ });
459
+ mockUseDataBrowserUICustomization({
460
+ extraBucketListColumns: [
461
+ {
462
+ id: 'location',
463
+ header: 'Custom Location',
464
+ render: CustomLocationColumn
465
+ },
466
+ {
467
+ id: 'extraData',
468
+ header: 'Extra Data',
469
+ render: ExtraColumn
470
+ }
471
+ ]
472
+ });
473
+ renderBucketList({
474
+ buckets: mockBuckets
475
+ });
476
+ const headers = screen.getAllByRole('columnheader');
477
+ const headerTexts = headers.map((h)=>h.textContent);
478
+ const bucketNameIndex = headerTexts.indexOf('Bucket Name');
479
+ const customLocationIndex = headerTexts.indexOf('Custom Location');
480
+ const extraDataIndex = headerTexts.indexOf('Extra Data');
481
+ const createdOnIndex = headerTexts.indexOf('Created on');
482
+ expect(bucketNameIndex).toBe(0);
483
+ expect(customLocationIndex).toBe(1);
484
+ expect(extraDataIndex).toBe(2);
485
+ expect(createdOnIndex).toBe(3);
486
+ });
295
487
  });
296
- describe("transformBucketData support", ()=>{
297
- it("transforms bucket data when transformBucketData is provided", ()=>{
298
- const transformBucketData = jest.fn((bucket)=>({
299
- ...bucket,
300
- metrics: {
301
- value: 100
488
+ describe('extraBucketListActions support', ()=>{
489
+ it('renders extra actions when extraBucketListActions is configured', ()=>{
490
+ const CustomAction = ()=>/*#__PURE__*/ jsx("button", {
491
+ children: "Custom Action"
492
+ });
493
+ mockUseDataBrowserUICustomization({
494
+ extraBucketListActions: [
495
+ {
496
+ id: 'customAction',
497
+ render: CustomAction
302
498
  }
303
- }));
304
- const additionalColumns = [
305
- {
306
- Header: "Metrics",
307
- accessor: "metrics",
308
- id: "metrics",
309
- Cell: ({ value })=>/*#__PURE__*/ jsxs("span", {
310
- children: [
311
- "Value: ",
312
- value.value
313
- ]
314
- })
315
- }
316
- ];
499
+ ]
500
+ });
317
501
  renderBucketList({
318
- buckets: mockBuckets,
319
- additionalColumns,
320
- transformBucketData
321
- });
322
- expect(transformBucketData).toHaveBeenCalledTimes(3);
323
- expect(transformBucketData).toHaveBeenCalledWith(mockBuckets[0]);
324
- expect(transformBucketData).toHaveBeenCalledWith(mockBuckets[1]);
325
- expect(transformBucketData).toHaveBeenCalledWith(mockBuckets[2]);
326
- });
327
- it("renders transformed data in additional columns", ()=>{
328
- const transformBucketData = (bucket)=>({
329
- ...bucket,
330
- metrics: {
331
- value: "test-bucket-1" === bucket.Name ? 50 : 100
502
+ buckets: mockBuckets
503
+ });
504
+ expect(screen.getByText('Custom Action')).toBeInTheDocument();
505
+ });
506
+ it('renders multiple extra actions', ()=>{
507
+ const Action1 = ()=>/*#__PURE__*/ jsx("button", {
508
+ children: "Action 1"
509
+ });
510
+ const Action2 = ()=>/*#__PURE__*/ jsx("button", {
511
+ children: "Action 2"
512
+ });
513
+ mockUseDataBrowserUICustomization({
514
+ extraBucketListActions: [
515
+ {
516
+ id: 'action1',
517
+ render: Action1
518
+ },
519
+ {
520
+ id: 'action2',
521
+ render: Action2
332
522
  }
523
+ ]
524
+ });
525
+ renderBucketList({
526
+ buckets: mockBuckets
527
+ });
528
+ expect(screen.getByText('Action 1')).toBeInTheDocument();
529
+ expect(screen.getByText('Action 2')).toBeInTheDocument();
530
+ });
531
+ it('renders actions alongside default Create Bucket button', ()=>{
532
+ const CustomAction = ()=>/*#__PURE__*/ jsx("button", {
533
+ children: "Export"
333
534
  });
334
- const additionalColumns = [
335
- {
336
- Header: "Metrics",
337
- accessor: "metrics",
338
- id: "metrics",
339
- Cell: ({ value })=>/*#__PURE__*/ jsxs("span", {
340
- children: [
341
- "Metric: ",
342
- value.value
343
- ]
344
- })
345
- }
346
- ];
535
+ mockUseDataBrowserUICustomization({
536
+ extraBucketListActions: [
537
+ {
538
+ id: 'export',
539
+ render: CustomAction
540
+ }
541
+ ]
542
+ });
347
543
  renderBucketList({
348
544
  buckets: mockBuckets,
349
- additionalColumns,
350
- transformBucketData
351
- });
352
- expect(screen.getByText("Metric: 50")).toBeInTheDocument();
353
- expect(screen.getAllByText("Metric: 100")).toHaveLength(2);
354
- });
355
- it("works without transformBucketData (uses default behavior)", ()=>{
356
- const additionalColumns = [
357
- {
358
- Header: "Test Column",
359
- accessor: "Name",
360
- id: "testColumn",
361
- Cell: ({ value })=>/*#__PURE__*/ jsxs("span", {
362
- children: [
363
- "Name: ",
364
- value
365
- ]
366
- })
367
- }
368
- ];
545
+ onCreateBucket: jest.fn()
546
+ });
547
+ expect(screen.getByText('Create Bucket')).toBeInTheDocument();
548
+ expect(screen.getByText('Export')).toBeInTheDocument();
549
+ });
550
+ it('works without extra actions', ()=>{
369
551
  renderBucketList({
370
552
  buckets: mockBuckets,
371
- additionalColumns
553
+ onCreateBucket: jest.fn()
372
554
  });
373
- expect(screen.getByText("Name: test-bucket-1")).toBeInTheDocument();
374
- expect(screen.getByText("Name: test-bucket-2")).toBeInTheDocument();
375
- expect(screen.getByText("Name: test-bucket-3")).toBeInTheDocument();
555
+ expect(screen.getByText('Create Bucket')).toBeInTheDocument();
376
556
  });
377
- });
378
- describe("generic type support", ()=>{
379
- it("maintains type safety with extended bucket types", ()=>{
380
- const transformBucketData = (bucket)=>({
381
- ...bucket,
382
- customField: `Custom ${bucket.Name}`,
383
- numericField: 42
557
+ it("can replace default Create Bucket action by using 'createBucket' ID", ()=>{
558
+ const CustomCreateAction = ()=>/*#__PURE__*/ jsx("button", {
559
+ children: "Custom Create"
560
+ });
561
+ mockUseDataBrowserUICustomization({
562
+ extraBucketListActions: [
563
+ {
564
+ id: 'createBucket',
565
+ render: CustomCreateAction
566
+ }
567
+ ]
568
+ });
569
+ renderBucketList({
570
+ buckets: mockBuckets,
571
+ onCreateBucket: jest.fn()
572
+ });
573
+ expect(screen.getByText('Custom Create')).toBeInTheDocument();
574
+ expect(screen.queryByText('Create Bucket')).not.toBeInTheDocument();
575
+ });
576
+ it('can mix replacing default action and adding new actions', ()=>{
577
+ const CustomCreateAction = ()=>/*#__PURE__*/ jsx("button", {
578
+ children: "Custom Create"
579
+ });
580
+ const ExportAction = ()=>/*#__PURE__*/ jsx("button", {
581
+ children: "Export"
582
+ });
583
+ mockUseDataBrowserUICustomization({
584
+ extraBucketListActions: [
585
+ {
586
+ id: 'createBucket',
587
+ render: CustomCreateAction
588
+ },
589
+ {
590
+ id: 'export',
591
+ render: ExportAction
592
+ }
593
+ ]
594
+ });
595
+ renderBucketList({
596
+ buckets: mockBuckets,
597
+ onCreateBucket: jest.fn()
598
+ });
599
+ expect(screen.getByText('Custom Create')).toBeInTheDocument();
600
+ expect(screen.getByText('Export')).toBeInTheDocument();
601
+ expect(screen.queryByText('Create Bucket')).not.toBeInTheDocument();
602
+ });
603
+ it('maintains correct action order when replacing and adding actions', ()=>{
604
+ const CustomCreateAction = ()=>/*#__PURE__*/ jsx("button", {
605
+ children: "Custom Create"
606
+ });
607
+ const Action1 = ()=>/*#__PURE__*/ jsx("button", {
608
+ children: "Action 1"
384
609
  });
385
- const additionalColumns = [
386
- {
387
- Header: "Custom",
388
- accessor: "customField",
389
- id: "custom",
390
- Cell: ({ value })=>/*#__PURE__*/ jsx("span", {
391
- children: value
392
- })
393
- },
394
- {
395
- Header: "Number",
396
- accessor: "numericField",
397
- id: "numeric",
398
- Cell: ({ value })=>/*#__PURE__*/ jsxs("span", {
399
- children: [
400
- "Num: ",
401
- value
402
- ]
403
- })
404
- }
405
- ];
610
+ const Action2 = ()=>/*#__PURE__*/ jsx("button", {
611
+ children: "Action 2"
612
+ });
613
+ mockUseDataBrowserUICustomization({
614
+ extraBucketListActions: [
615
+ {
616
+ id: 'createBucket',
617
+ render: CustomCreateAction
618
+ },
619
+ {
620
+ id: 'action1',
621
+ render: Action1
622
+ },
623
+ {
624
+ id: 'action2',
625
+ render: Action2
626
+ }
627
+ ]
628
+ });
406
629
  renderBucketList({
407
630
  buckets: mockBuckets,
408
- additionalColumns,
409
- transformBucketData
631
+ onCreateBucket: jest.fn()
410
632
  });
411
- expect(screen.getByText("Custom test-bucket-1")).toBeInTheDocument();
412
- expect(screen.getAllByText("Num: 42")).toHaveLength(3);
633
+ const buttons = screen.getAllByRole('button');
634
+ expect(buttons[0]).toHaveTextContent('Custom Create');
635
+ expect(buttons[1]).toHaveTextContent('Action 1');
636
+ expect(buttons[2]).toHaveTextContent('Action 2');
413
637
  });
414
638
  });
415
639
  });