@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
@@ -0,0 +1,531 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { useToast } from "@scality/core-ui";
3
+ import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
4
+ import { cleanup, render, screen, waitFor } from "@testing-library/react";
5
+ import user_event from "@testing-library/user-event";
6
+ import { useGetPresignedDownload } from "../../../hooks/index.js";
7
+ import { GetPresignedUrlButton } from "../GetPresignedUrlButton.js";
8
+ jest.mock('../../../hooks');
9
+ jest.mock('@scality/core-ui', ()=>{
10
+ const actual = jest.requireActual('@scality/core-ui');
11
+ return {
12
+ ...actual,
13
+ useToast: jest.fn()
14
+ };
15
+ });
16
+ const mockUseGetPresignedDownload = jest.mocked(useGetPresignedDownload);
17
+ const mockUseToast = jest.mocked(useToast);
18
+ const defaultProps = {
19
+ bucketName: 'test-bucket',
20
+ objectKey: 'folder/test-object.txt',
21
+ versionId: 'test-version-id'
22
+ };
23
+ const mockPresignedResult = {
24
+ Url: 'https://s3.example.com/test-bucket/folder/test-object.txt?signature=abc123',
25
+ ExpiresAt: new Date('2024-01-08T00:00:00Z'),
26
+ Bucket: 'test-bucket',
27
+ Key: 'folder/test-object.txt'
28
+ };
29
+ const setupMockDefaults = ()=>{
30
+ mockUseGetPresignedDownload.mockReturnValue({
31
+ mutateAsync: jest.fn().mockResolvedValue(mockPresignedResult),
32
+ isPending: false
33
+ });
34
+ mockUseToast.mockReturnValue({
35
+ showToast: jest.fn()
36
+ });
37
+ };
38
+ const renderWithProviders = (ui)=>{
39
+ const queryClient = new QueryClient({
40
+ defaultOptions: {
41
+ queries: {
42
+ retry: false
43
+ },
44
+ mutations: {
45
+ retry: false
46
+ }
47
+ }
48
+ });
49
+ return render(/*#__PURE__*/ jsx(QueryClientProvider, {
50
+ client: queryClient,
51
+ children: ui
52
+ }));
53
+ };
54
+ describe('GetPresignedUrlButton', ()=>{
55
+ beforeEach(()=>{
56
+ jest.clearAllMocks();
57
+ setupMockDefaults();
58
+ });
59
+ afterEach(()=>{
60
+ cleanup();
61
+ });
62
+ describe('Modal Behavior', ()=>{
63
+ it('should render the button', ()=>{
64
+ renderWithProviders(/*#__PURE__*/ jsx(GetPresignedUrlButton, {
65
+ ...defaultProps
66
+ }));
67
+ expect(screen.getByRole('button', {
68
+ name: /get pre-signed url/i
69
+ })).toBeInTheDocument();
70
+ });
71
+ it('should open modal when button is clicked', async ()=>{
72
+ const user = user_event.setup();
73
+ renderWithProviders(/*#__PURE__*/ jsx(GetPresignedUrlButton, {
74
+ ...defaultProps
75
+ }));
76
+ await user.click(screen.getByRole('button', {
77
+ name: /get pre-signed url/i
78
+ }));
79
+ expect(screen.getByText('Get a pre-signed url')).toBeInTheDocument();
80
+ expect(screen.getByText('test-object.txt')).toBeInTheDocument();
81
+ });
82
+ it('should close modal when Close button is clicked', async ()=>{
83
+ const user = user_event.setup();
84
+ renderWithProviders(/*#__PURE__*/ jsx(GetPresignedUrlButton, {
85
+ ...defaultProps
86
+ }));
87
+ await user.click(screen.getByRole('button', {
88
+ name: /get pre-signed url/i
89
+ }));
90
+ expect(screen.getByText('Get a pre-signed url')).toBeInTheDocument();
91
+ await user.click(screen.getByRole('button', {
92
+ name: /close/i
93
+ }));
94
+ await waitFor(()=>{
95
+ expect(screen.queryByText('Get a pre-signed url')).not.toBeInTheDocument();
96
+ });
97
+ });
98
+ it('should reset state when modal closes', async ()=>{
99
+ const user = user_event.setup();
100
+ renderWithProviders(/*#__PURE__*/ jsx(GetPresignedUrlButton, {
101
+ ...defaultProps
102
+ }));
103
+ await user.click(screen.getByRole('button', {
104
+ name: /get pre-signed url/i
105
+ }));
106
+ const daysInput = screen.getByLabelText('Days');
107
+ await user.clear(daysInput);
108
+ await user.type(daysInput, '3');
109
+ await user.click(screen.getByRole('button', {
110
+ name: /generate a pre-signed url/i
111
+ }));
112
+ await waitFor(()=>{
113
+ expect(screen.getByLabelText('Generated pre-signed URL')).toBeInTheDocument();
114
+ });
115
+ await user.click(screen.getByRole('button', {
116
+ name: /close/i
117
+ }));
118
+ await user.click(screen.getByRole('button', {
119
+ name: /get pre-signed url/i
120
+ }));
121
+ expect(screen.getByLabelText('Days')).toHaveValue(7);
122
+ expect(screen.getByLabelText('Hours')).toHaveValue(0);
123
+ expect(screen.getByLabelText('Minutes')).toHaveValue(0);
124
+ expect(screen.queryByLabelText('Generated pre-signed URL')).not.toBeInTheDocument();
125
+ });
126
+ it('should display object name from key path', async ()=>{
127
+ const user = user_event.setup();
128
+ renderWithProviders(/*#__PURE__*/ jsx(GetPresignedUrlButton, {
129
+ ...defaultProps,
130
+ objectKey: "deep/nested/folder/myfile.pdf"
131
+ }));
132
+ await user.click(screen.getByRole('button', {
133
+ name: /get pre-signed url/i
134
+ }));
135
+ expect(screen.getByText('myfile.pdf')).toBeInTheDocument();
136
+ });
137
+ it('should handle object key without slashes', async ()=>{
138
+ const user = user_event.setup();
139
+ renderWithProviders(/*#__PURE__*/ jsx(GetPresignedUrlButton, {
140
+ ...defaultProps,
141
+ objectKey: "simple-file.txt"
142
+ }));
143
+ await user.click(screen.getByRole('button', {
144
+ name: /get pre-signed url/i
145
+ }));
146
+ expect(screen.getByText('simple-file.txt')).toBeInTheDocument();
147
+ });
148
+ });
149
+ describe('Expiration Time Input', ()=>{
150
+ it('should initialize with 7 days, 0 hours, 0 minutes', async ()=>{
151
+ const user = user_event.setup();
152
+ renderWithProviders(/*#__PURE__*/ jsx(GetPresignedUrlButton, {
153
+ ...defaultProps
154
+ }));
155
+ await user.click(screen.getByRole('button', {
156
+ name: /get pre-signed url/i
157
+ }));
158
+ expect(screen.getByLabelText('Days')).toHaveValue(7);
159
+ expect(screen.getByLabelText('Hours')).toHaveValue(0);
160
+ expect(screen.getByLabelText('Minutes')).toHaveValue(0);
161
+ });
162
+ it('should clamp days input to max 7', async ()=>{
163
+ const user = user_event.setup();
164
+ renderWithProviders(/*#__PURE__*/ jsx(GetPresignedUrlButton, {
165
+ ...defaultProps
166
+ }));
167
+ await user.click(screen.getByRole('button', {
168
+ name: /get pre-signed url/i
169
+ }));
170
+ const daysInput = screen.getByLabelText('Days');
171
+ await user.clear(daysInput);
172
+ await user.type(daysInput, '10');
173
+ expect(daysInput).toHaveValue(7);
174
+ });
175
+ it('should treat empty/invalid input as 0', async ()=>{
176
+ const user = user_event.setup();
177
+ renderWithProviders(/*#__PURE__*/ jsx(GetPresignedUrlButton, {
178
+ ...defaultProps
179
+ }));
180
+ await user.click(screen.getByRole('button', {
181
+ name: /get pre-signed url/i
182
+ }));
183
+ const daysInput = screen.getByLabelText('Days');
184
+ await user.clear(daysInput);
185
+ expect(daysInput).toHaveValue(0);
186
+ });
187
+ it('should disable hours and minutes when days equals 7', async ()=>{
188
+ const user = user_event.setup();
189
+ renderWithProviders(/*#__PURE__*/ jsx(GetPresignedUrlButton, {
190
+ ...defaultProps
191
+ }));
192
+ await user.click(screen.getByRole('button', {
193
+ name: /get pre-signed url/i
194
+ }));
195
+ expect(screen.getByLabelText('Hours')).toBeDisabled();
196
+ expect(screen.getByLabelText('Minutes')).toBeDisabled();
197
+ });
198
+ it('should enable hours and minutes when days is less than 7', async ()=>{
199
+ const user = user_event.setup();
200
+ renderWithProviders(/*#__PURE__*/ jsx(GetPresignedUrlButton, {
201
+ ...defaultProps
202
+ }));
203
+ await user.click(screen.getByRole('button', {
204
+ name: /get pre-signed url/i
205
+ }));
206
+ const daysInput = screen.getByLabelText('Days');
207
+ await user.clear(daysInput);
208
+ await user.type(daysInput, '3');
209
+ expect(screen.getByLabelText('Hours')).not.toBeDisabled();
210
+ expect(screen.getByLabelText('Minutes')).not.toBeDisabled();
211
+ });
212
+ it('should reset hours and minutes to 0 when days becomes 7', async ()=>{
213
+ const user = user_event.setup();
214
+ renderWithProviders(/*#__PURE__*/ jsx(GetPresignedUrlButton, {
215
+ ...defaultProps
216
+ }));
217
+ await user.click(screen.getByRole('button', {
218
+ name: /get pre-signed url/i
219
+ }));
220
+ const daysInput = screen.getByLabelText('Days');
221
+ await user.clear(daysInput);
222
+ await user.type(daysInput, '3');
223
+ const hoursInput = screen.getByLabelText('Hours');
224
+ const minutesInput = screen.getByLabelText('Minutes');
225
+ await user.clear(hoursInput);
226
+ await user.type(hoursInput, '5');
227
+ await user.clear(minutesInput);
228
+ await user.type(minutesInput, '30');
229
+ expect(hoursInput).toHaveValue(5);
230
+ expect(minutesInput).toHaveValue(30);
231
+ await user.clear(daysInput);
232
+ await user.type(daysInput, '7');
233
+ expect(hoursInput).toHaveValue(0);
234
+ expect(minutesInput).toHaveValue(0);
235
+ });
236
+ it('should clamp hours input to 0-23 range', async ()=>{
237
+ const user = user_event.setup();
238
+ renderWithProviders(/*#__PURE__*/ jsx(GetPresignedUrlButton, {
239
+ ...defaultProps
240
+ }));
241
+ await user.click(screen.getByRole('button', {
242
+ name: /get pre-signed url/i
243
+ }));
244
+ const daysInput = screen.getByLabelText('Days');
245
+ await user.clear(daysInput);
246
+ await user.type(daysInput, '3');
247
+ const hoursInput = screen.getByLabelText('Hours');
248
+ await user.clear(hoursInput);
249
+ await user.type(hoursInput, '30');
250
+ expect(hoursInput).toHaveValue(23);
251
+ });
252
+ it('should clamp minutes input to 0-59 range', async ()=>{
253
+ const user = user_event.setup();
254
+ renderWithProviders(/*#__PURE__*/ jsx(GetPresignedUrlButton, {
255
+ ...defaultProps
256
+ }));
257
+ await user.click(screen.getByRole('button', {
258
+ name: /get pre-signed url/i
259
+ }));
260
+ const daysInput = screen.getByLabelText('Days');
261
+ await user.clear(daysInput);
262
+ await user.type(daysInput, '3');
263
+ const minutesInput = screen.getByLabelText('Minutes');
264
+ await user.clear(minutesInput);
265
+ await user.type(minutesInput, '99');
266
+ expect(minutesInput).toHaveValue(59);
267
+ });
268
+ });
269
+ describe('Generate Button State', ()=>{
270
+ it('should be disabled when total expiration is 0', async ()=>{
271
+ const user = user_event.setup();
272
+ renderWithProviders(/*#__PURE__*/ jsx(GetPresignedUrlButton, {
273
+ ...defaultProps
274
+ }));
275
+ await user.click(screen.getByRole('button', {
276
+ name: /get pre-signed url/i
277
+ }));
278
+ const daysInput = screen.getByLabelText('Days');
279
+ await user.clear(daysInput);
280
+ await user.type(daysInput, '0');
281
+ expect(screen.getByRole('button', {
282
+ name: /generate a pre-signed url/i
283
+ })).toBeDisabled();
284
+ });
285
+ it('should be enabled with valid expiration time', async ()=>{
286
+ const user = user_event.setup();
287
+ renderWithProviders(/*#__PURE__*/ jsx(GetPresignedUrlButton, {
288
+ ...defaultProps
289
+ }));
290
+ await user.click(screen.getByRole('button', {
291
+ name: /get pre-signed url/i
292
+ }));
293
+ expect(screen.getByRole('button', {
294
+ name: /generate a pre-signed url/i
295
+ })).not.toBeDisabled();
296
+ });
297
+ it('should be disabled while generating', async ()=>{
298
+ mockUseGetPresignedDownload.mockReturnValue({
299
+ mutateAsync: jest.fn().mockImplementation(()=>new Promise(()=>{})),
300
+ isPending: true
301
+ });
302
+ const user = user_event.setup();
303
+ renderWithProviders(/*#__PURE__*/ jsx(GetPresignedUrlButton, {
304
+ ...defaultProps
305
+ }));
306
+ await user.click(screen.getByRole('button', {
307
+ name: /get pre-signed url/i
308
+ }));
309
+ expect(screen.getByRole('button', {
310
+ name: /generate a pre-signed url/i
311
+ })).toBeDisabled();
312
+ });
313
+ });
314
+ describe('URL Generation', ()=>{
315
+ it('should call getPresignedDownload with correct params', async ()=>{
316
+ const mockMutateAsync = jest.fn().mockResolvedValue(mockPresignedResult);
317
+ mockUseGetPresignedDownload.mockReturnValue({
318
+ mutateAsync: mockMutateAsync,
319
+ isPending: false
320
+ });
321
+ const user = user_event.setup();
322
+ renderWithProviders(/*#__PURE__*/ jsx(GetPresignedUrlButton, {
323
+ ...defaultProps
324
+ }));
325
+ await user.click(screen.getByRole('button', {
326
+ name: /get pre-signed url/i
327
+ }));
328
+ await user.click(screen.getByRole('button', {
329
+ name: /generate a pre-signed url/i
330
+ }));
331
+ expect(mockMutateAsync).toHaveBeenCalledWith({
332
+ Bucket: 'test-bucket',
333
+ Key: 'folder/test-object.txt',
334
+ VersionId: 'test-version-id',
335
+ expiresIn: 604800
336
+ });
337
+ });
338
+ it('should not include versionId when not provided', async ()=>{
339
+ const mockMutateAsync = jest.fn().mockResolvedValue(mockPresignedResult);
340
+ mockUseGetPresignedDownload.mockReturnValue({
341
+ mutateAsync: mockMutateAsync,
342
+ isPending: false
343
+ });
344
+ const user = user_event.setup();
345
+ renderWithProviders(/*#__PURE__*/ jsx(GetPresignedUrlButton, {
346
+ bucketName: "test-bucket",
347
+ objectKey: "test.txt"
348
+ }));
349
+ await user.click(screen.getByRole('button', {
350
+ name: /get pre-signed url/i
351
+ }));
352
+ await user.click(screen.getByRole('button', {
353
+ name: /generate a pre-signed url/i
354
+ }));
355
+ expect(mockMutateAsync).toHaveBeenCalledWith({
356
+ Bucket: 'test-bucket',
357
+ Key: 'test.txt',
358
+ expiresIn: 604800
359
+ });
360
+ });
361
+ it('should display generated URL on success', async ()=>{
362
+ const user = user_event.setup();
363
+ renderWithProviders(/*#__PURE__*/ jsx(GetPresignedUrlButton, {
364
+ ...defaultProps
365
+ }));
366
+ await user.click(screen.getByRole('button', {
367
+ name: /get pre-signed url/i
368
+ }));
369
+ await user.click(screen.getByRole('button', {
370
+ name: /generate a pre-signed url/i
371
+ }));
372
+ await waitFor(()=>{
373
+ expect(screen.getByLabelText('Generated pre-signed URL')).toHaveValue(mockPresignedResult.Url);
374
+ });
375
+ });
376
+ it('should display expiration date preview', async ()=>{
377
+ const user = user_event.setup();
378
+ renderWithProviders(/*#__PURE__*/ jsx(GetPresignedUrlButton, {
379
+ ...defaultProps
380
+ }));
381
+ await user.click(screen.getByRole('button', {
382
+ name: /get pre-signed url/i
383
+ }));
384
+ expect(screen.getByText(/Access ends on:/)).toBeInTheDocument();
385
+ });
386
+ it('should change button label after first generation', async ()=>{
387
+ const user = user_event.setup();
388
+ renderWithProviders(/*#__PURE__*/ jsx(GetPresignedUrlButton, {
389
+ ...defaultProps
390
+ }));
391
+ await user.click(screen.getByRole('button', {
392
+ name: /get pre-signed url/i
393
+ }));
394
+ expect(screen.getByRole('button', {
395
+ name: /generate a pre-signed url/i
396
+ })).toBeInTheDocument();
397
+ await user.click(screen.getByRole('button', {
398
+ name: /generate a pre-signed url/i
399
+ }));
400
+ await waitFor(()=>{
401
+ expect(screen.getByRole('button', {
402
+ name: /generate another pre-signed url/i
403
+ })).toBeInTheDocument();
404
+ });
405
+ });
406
+ it('should calculate correct expiration seconds', async ()=>{
407
+ const mockMutateAsync = jest.fn().mockResolvedValue(mockPresignedResult);
408
+ mockUseGetPresignedDownload.mockReturnValue({
409
+ mutateAsync: mockMutateAsync,
410
+ isPending: false
411
+ });
412
+ const user = user_event.setup();
413
+ renderWithProviders(/*#__PURE__*/ jsx(GetPresignedUrlButton, {
414
+ ...defaultProps
415
+ }));
416
+ await user.click(screen.getByRole('button', {
417
+ name: /get pre-signed url/i
418
+ }));
419
+ const daysInput = screen.getByLabelText('Days');
420
+ await user.clear(daysInput);
421
+ await user.type(daysInput, '2');
422
+ const hoursInput = screen.getByLabelText('Hours');
423
+ await user.clear(hoursInput);
424
+ await user.type(hoursInput, '3');
425
+ const minutesInput = screen.getByLabelText('Minutes');
426
+ await user.clear(minutesInput);
427
+ await user.type(minutesInput, '30');
428
+ await user.click(screen.getByRole('button', {
429
+ name: /generate a pre-signed url/i
430
+ }));
431
+ expect(mockMutateAsync).toHaveBeenCalledWith(expect.objectContaining({
432
+ expiresIn: 185400
433
+ }));
434
+ });
435
+ });
436
+ describe('Error Handling', ()=>{
437
+ it('should show toast with error.message for Error instances', async ()=>{
438
+ const mockShowToast = jest.fn();
439
+ mockUseToast.mockReturnValue({
440
+ showToast: mockShowToast
441
+ });
442
+ const errorMessage = 'Access denied to bucket';
443
+ mockUseGetPresignedDownload.mockReturnValue({
444
+ mutateAsync: jest.fn().mockRejectedValue(new Error(errorMessage)),
445
+ isPending: false
446
+ });
447
+ const user = user_event.setup();
448
+ renderWithProviders(/*#__PURE__*/ jsx(GetPresignedUrlButton, {
449
+ ...defaultProps
450
+ }));
451
+ await user.click(screen.getByRole('button', {
452
+ name: /get pre-signed url/i
453
+ }));
454
+ await user.click(screen.getByRole('button', {
455
+ name: /generate a pre-signed url/i
456
+ }));
457
+ await waitFor(()=>{
458
+ expect(mockShowToast).toHaveBeenCalledWith({
459
+ open: true,
460
+ message: errorMessage,
461
+ status: 'error'
462
+ });
463
+ });
464
+ });
465
+ it('should show generic toast for non-Error failures', async ()=>{
466
+ const mockShowToast = jest.fn();
467
+ mockUseToast.mockReturnValue({
468
+ showToast: mockShowToast
469
+ });
470
+ mockUseGetPresignedDownload.mockReturnValue({
471
+ mutateAsync: jest.fn().mockRejectedValue('string error'),
472
+ isPending: false
473
+ });
474
+ const user = user_event.setup();
475
+ renderWithProviders(/*#__PURE__*/ jsx(GetPresignedUrlButton, {
476
+ ...defaultProps
477
+ }));
478
+ await user.click(screen.getByRole('button', {
479
+ name: /get pre-signed url/i
480
+ }));
481
+ await user.click(screen.getByRole('button', {
482
+ name: /generate a pre-signed url/i
483
+ }));
484
+ await waitFor(()=>{
485
+ expect(mockShowToast).toHaveBeenCalledWith({
486
+ open: true,
487
+ message: 'Failed to generate presigned URL',
488
+ status: 'error'
489
+ });
490
+ });
491
+ });
492
+ it('should not display URL when generation fails', async ()=>{
493
+ mockUseGetPresignedDownload.mockReturnValue({
494
+ mutateAsync: jest.fn().mockRejectedValue(new Error('Failed')),
495
+ isPending: false
496
+ });
497
+ const user = user_event.setup();
498
+ renderWithProviders(/*#__PURE__*/ jsx(GetPresignedUrlButton, {
499
+ ...defaultProps
500
+ }));
501
+ await user.click(screen.getByRole('button', {
502
+ name: /get pre-signed url/i
503
+ }));
504
+ await user.click(screen.getByRole('button', {
505
+ name: /generate a pre-signed url/i
506
+ }));
507
+ await waitFor(()=>{
508
+ expect(screen.queryByLabelText('Generated pre-signed URL')).not.toBeInTheDocument();
509
+ });
510
+ });
511
+ });
512
+ describe('Copy Button', ()=>{
513
+ it('should render copy button with generated URL', async ()=>{
514
+ const user = user_event.setup();
515
+ renderWithProviders(/*#__PURE__*/ jsx(GetPresignedUrlButton, {
516
+ ...defaultProps
517
+ }));
518
+ await user.click(screen.getByRole('button', {
519
+ name: /get pre-signed url/i
520
+ }));
521
+ await user.click(screen.getByRole('button', {
522
+ name: /generate a pre-signed url/i
523
+ }));
524
+ await waitFor(()=>{
525
+ expect(screen.getByRole('button', {
526
+ name: /copy/i
527
+ })).toBeInTheDocument();
528
+ });
529
+ });
530
+ });
531
+ });
@@ -1,20 +1,31 @@
1
- import React from "react";
2
- import { QueryClient } from "@tanstack/react-query";
3
- import { GetConfigFunction } from "../../types";
4
- import { CoreUITheme } from "@scality/core-ui/dist/style/theme";
1
+ import { type CoreUITheme } from '@scality/core-ui/dist/next';
2
+ import { type InvalidateQueryFilters, type QueryClient, type QueryKey } from '@tanstack/react-query';
3
+ import type React from 'react';
4
+ import type { GetConfigFunction } from '../../types';
5
5
  export interface DataBrowserContextValue {
6
- getS3Config: GetConfigFunction;
7
- theme: CoreUITheme;
6
+ getS3Config: GetConfigFunction | null;
7
+ s3ConfigIdentifier: string;
8
8
  }
9
- export declare const DataBrowserContext: React.Context<DataBrowserContextValue | null>;
9
+ export declare const DataBrowserContext: React.Context<DataBrowserContextValue>;
10
10
  export declare const useDataBrowserContext: () => DataBrowserContextValue;
11
- export declare const useDataBrowserTheme: () => CoreUITheme;
12
- interface DataBrowserProviderProps {
11
+ export interface DataBrowserProviderProps {
13
12
  children: React.ReactNode;
14
- queryClient?: QueryClient;
15
- enableDevtools?: boolean;
16
13
  getS3Config?: GetConfigFunction;
14
+ queryClient?: QueryClient;
17
15
  theme?: CoreUITheme;
16
+ enableDevtools?: boolean;
18
17
  }
19
18
  export declare const DataBrowserProvider: React.FC<DataBrowserProviderProps>;
20
- export {};
19
+ export declare const useDataBrowserConfig: () => import("../../types").S3BrowserConfig & {
20
+ credentials: import("../../types").S3Credentials;
21
+ };
22
+ /**
23
+ * Hook to invalidate queries with automatic S3 config identifier prefixing.
24
+ *
25
+ * @example
26
+ * const invalidateQueries = useInvalidateQueries();
27
+ * await invalidateQueries({ queryKey: ['ListObjects', { Bucket: 'my-bucket' }] });
28
+ */
29
+ export declare const useInvalidateQueries: () => (filters: Omit<InvalidateQueryFilters, "queryKey"> & {
30
+ queryKey: QueryKey;
31
+ }) => Promise<void>;
@@ -1,42 +1,64 @@
1
- import { jsx, jsxs } from "react/jsx-runtime";
2
- import { createContext, useContext } from "react";
3
- import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
4
- import { ReactQueryDevtools } from "@tanstack/react-query-devtools";
5
- const DataBrowserContext = /*#__PURE__*/ createContext(null);
6
- const useDataBrowserContext = ()=>{
7
- const context = useContext(DataBrowserContext);
8
- if (!context) throw new Error("useDataBrowserContext must be used within a DataBrowserProvider component");
9
- return context;
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { CoreUiThemeProvider } from "@scality/core-ui/dist/next";
3
+ import { coreUIAvailableThemes } from "@scality/core-ui/dist/style/theme";
4
+ import { useQueryClient } from "@tanstack/react-query";
5
+ import { createContext, useCallback, useContext, useMemo } from "react";
6
+ import { ANONYMOUS_S3_CONFIG_IDENTIFIER, computeS3ConfigIdentifier } from "../../utils/s3ConfigIdentifier.js";
7
+ import { QueryProvider } from "./QueryProvider.js";
8
+ const DEFAULT_CONTEXT_VALUE = {
9
+ getS3Config: null,
10
+ s3ConfigIdentifier: ANONYMOUS_S3_CONFIG_IDENTIFIER
10
11
  };
11
- const useDataBrowserTheme = ()=>{
12
- const { theme } = useDataBrowserContext();
13
- return theme;
14
- };
15
- const defaultQueryClient = new QueryClient({
16
- defaultOptions: {
17
- queries: {
18
- staleTime: 300000,
19
- retry: 2
20
- }
21
- }
22
- });
23
- const DataBrowserProvider = ({ children, queryClient = defaultQueryClient, enableDevtools = "development" === process.env.NODE_ENV, getS3Config, theme })=>{
24
- const content = /*#__PURE__*/ jsxs(QueryClientProvider, {
25
- client: queryClient,
26
- children: [
27
- children,
28
- enableDevtools && /*#__PURE__*/ jsx(ReactQueryDevtools, {
29
- initialIsOpen: false
12
+ const DataBrowserContext = /*#__PURE__*/ createContext(DEFAULT_CONTEXT_VALUE);
13
+ const useDataBrowserContext = ()=>useContext(DataBrowserContext);
14
+ const DataBrowserProvider = ({ children, queryClient, theme, enableDevtools, getS3Config })=>{
15
+ const currentConfig = getS3Config?.();
16
+ const s3ConfigIdentifier = useMemo(()=>currentConfig ? computeS3ConfigIdentifier(currentConfig) : ANONYMOUS_S3_CONFIG_IDENTIFIER, [
17
+ currentConfig?.cacheKey,
18
+ currentConfig?.credentials?.accessKeyId,
19
+ currentConfig?.credentials?.sessionToken,
20
+ currentConfig?.region,
21
+ currentConfig?.endpoint
22
+ ]);
23
+ const contextValue = useMemo(()=>({
24
+ getS3Config: getS3Config ?? null,
25
+ s3ConfigIdentifier
26
+ }), [
27
+ getS3Config,
28
+ s3ConfigIdentifier
29
+ ]);
30
+ return /*#__PURE__*/ jsx(CoreUiThemeProvider, {
31
+ theme: theme ?? coreUIAvailableThemes.darkRebrand,
32
+ children: /*#__PURE__*/ jsx(QueryProvider, {
33
+ queryClient: queryClient,
34
+ enableDevtools: enableDevtools,
35
+ children: /*#__PURE__*/ jsx(DataBrowserContext.Provider, {
36
+ value: contextValue,
37
+ children: children
30
38
  })
31
- ]
32
- });
33
- if (getS3Config && theme) return /*#__PURE__*/ jsx(DataBrowserContext.Provider, {
34
- value: {
35
- getS3Config,
36
- theme
37
- },
38
- children: content
39
+ })
39
40
  });
40
- return content;
41
41
  };
42
- export { DataBrowserContext, DataBrowserProvider, useDataBrowserContext, useDataBrowserTheme };
42
+ const useDataBrowserConfig = ()=>{
43
+ const { getS3Config } = useDataBrowserContext();
44
+ if (!getS3Config) throw new Error("useDataBrowserConfig: S3 config not available. Ensure DataBrowserProvider has getS3Config prop set.");
45
+ return getS3Config();
46
+ };
47
+ const useInvalidateQueries = ()=>{
48
+ const { s3ConfigIdentifier } = useDataBrowserContext();
49
+ const queryClient = useQueryClient();
50
+ return useCallback((filters)=>{
51
+ const { queryKey, ...rest } = filters;
52
+ return queryClient.invalidateQueries({
53
+ ...rest,
54
+ queryKey: [
55
+ s3ConfigIdentifier,
56
+ ...queryKey
57
+ ]
58
+ });
59
+ }, [
60
+ queryClient,
61
+ s3ConfigIdentifier
62
+ ]);
63
+ };
64
+ export { DataBrowserContext, DataBrowserProvider, useDataBrowserConfig, useDataBrowserContext, useInvalidateQueries };