@scality/data-browser-library 1.0.0-preview.8 → 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 (303) 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.d.ts +1 -0
  9. package/dist/components/__tests__/BucketCreate.test.js +574 -0
  10. package/dist/components/__tests__/BucketDetails.test.d.ts +1 -0
  11. package/dist/components/__tests__/BucketDetails.test.js +421 -0
  12. package/dist/components/__tests__/BucketLifecycleFormPage.test.d.ts +14 -0
  13. package/dist/components/__tests__/BucketLifecycleFormPage.test.js +618 -0
  14. package/dist/components/__tests__/BucketLifecycleList.test.d.ts +1 -0
  15. package/dist/components/__tests__/BucketLifecycleList.test.js +325 -0
  16. package/dist/components/__tests__/BucketList.test.js +495 -81
  17. package/dist/components/__tests__/BucketNotificationFormPage.test.d.ts +1 -0
  18. package/dist/components/__tests__/BucketNotificationFormPage.test.js +348 -0
  19. package/dist/components/__tests__/BucketNotificationList.test.d.ts +1 -0
  20. package/dist/components/__tests__/BucketNotificationList.test.js +379 -0
  21. package/dist/components/__tests__/BucketOverview.test.js +484 -179
  22. package/dist/components/__tests__/BucketPolicyPage.test.js +151 -99
  23. package/dist/components/__tests__/BucketReplicationFormPage.test.d.ts +16 -0
  24. package/dist/components/__tests__/BucketReplicationFormPage.test.js +1757 -0
  25. package/dist/components/__tests__/BucketReplicationList.test.d.ts +1 -0
  26. package/dist/components/__tests__/BucketReplicationList.test.js +344 -0
  27. package/dist/components/__tests__/CreateFolderButton.test.js +56 -56
  28. package/dist/components/__tests__/DeleteBucketButton.test.js +64 -64
  29. package/dist/components/__tests__/DeleteBucketConfigRuleButton.test.d.ts +1 -0
  30. package/dist/components/__tests__/DeleteBucketConfigRuleButton.test.js +196 -0
  31. package/dist/components/__tests__/DeleteObjectButton.test.js +64 -64
  32. package/dist/components/__tests__/EmptyBucketButton.test.d.ts +1 -0
  33. package/dist/components/__tests__/EmptyBucketButton.test.js +302 -0
  34. package/dist/components/__tests__/MetadataSearch.test.js +65 -65
  35. package/dist/components/__tests__/ObjectList.test.js +741 -240
  36. package/dist/components/__tests__/UploadButton.test.js +45 -45
  37. package/dist/components/breadcrumb/Breadcrumb.d.ts +6 -0
  38. package/dist/components/breadcrumb/Breadcrumb.js +37 -0
  39. package/dist/components/breadcrumb/DataBrowserBreadcrumb.d.ts +1 -0
  40. package/dist/components/breadcrumb/DataBrowserBreadcrumb.js +10 -0
  41. package/dist/components/breadcrumb/__tests__/Breadcrumb.test.d.ts +1 -0
  42. package/dist/components/breadcrumb/__tests__/Breadcrumb.test.js +196 -0
  43. package/dist/components/breadcrumb/__tests__/DataBrowserBreadcrumb.test.d.ts +1 -0
  44. package/dist/components/breadcrumb/__tests__/DataBrowserBreadcrumb.test.js +153 -0
  45. package/dist/components/breadcrumb/__tests__/useBreadcrumbPaths.test.d.ts +1 -0
  46. package/dist/components/breadcrumb/__tests__/useBreadcrumbPaths.test.js +134 -0
  47. package/dist/components/breadcrumb/index.d.ts +8 -0
  48. package/dist/components/breadcrumb/index.js +4 -0
  49. package/dist/components/breadcrumb/useBreadcrumbPaths.d.ts +2 -0
  50. package/dist/components/breadcrumb/useBreadcrumbPaths.js +82 -0
  51. package/dist/components/buckets/BucketAccessor.d.ts +2 -0
  52. package/dist/components/buckets/BucketAccessor.js +125 -0
  53. package/dist/components/buckets/BucketConfigEditButton.d.ts +8 -0
  54. package/dist/components/buckets/{BucketPolicyButton.js → BucketConfigEditButton.js} +9 -5
  55. package/dist/components/buckets/BucketCorsPage.d.ts +1 -0
  56. package/dist/components/buckets/BucketCorsPage.js +234 -0
  57. package/dist/components/buckets/BucketCreate.d.ts +50 -0
  58. package/dist/components/buckets/BucketCreate.js +279 -0
  59. package/dist/components/buckets/BucketDetails.d.ts +42 -0
  60. package/dist/components/buckets/BucketDetails.js +256 -40
  61. package/dist/components/buckets/BucketLifecycleFormPage.d.ts +15 -0
  62. package/dist/components/buckets/BucketLifecycleFormPage.js +1086 -0
  63. package/dist/components/buckets/BucketLifecycleList.d.ts +10 -0
  64. package/dist/components/buckets/BucketLifecycleList.js +270 -0
  65. package/dist/components/buckets/BucketList.d.ts +6 -4
  66. package/dist/components/buckets/BucketList.js +161 -94
  67. package/dist/components/buckets/BucketLocation.js +4 -4
  68. package/dist/components/buckets/BucketOverview.d.ts +86 -5
  69. package/dist/components/buckets/BucketOverview.js +481 -192
  70. package/dist/components/buckets/BucketPage.js +44 -22
  71. package/dist/components/buckets/BucketPolicyPage.js +155 -127
  72. package/dist/components/buckets/BucketReplicationFormPage.d.ts +1 -0
  73. package/dist/components/buckets/BucketReplicationFormPage.js +835 -0
  74. package/dist/components/buckets/BucketReplicationList.d.ts +11 -0
  75. package/dist/components/buckets/BucketReplicationList.js +189 -0
  76. package/dist/components/buckets/BucketVersioning.d.ts +4 -0
  77. package/dist/components/buckets/BucketVersioning.js +76 -0
  78. package/dist/components/buckets/DeleteBucketButton.js +8 -8
  79. package/dist/components/buckets/DeleteBucketConfigRuleButton.d.ts +18 -0
  80. package/dist/components/buckets/DeleteBucketConfigRuleButton.js +53 -0
  81. package/dist/components/buckets/EmptyBucketButton.d.ts +5 -0
  82. package/dist/components/buckets/EmptyBucketButton.js +232 -0
  83. package/dist/components/buckets/EmptyBucketSummary.d.ts +9 -0
  84. package/dist/components/buckets/EmptyBucketSummary.js +60 -0
  85. package/dist/components/buckets/EmptyBucketSummaryList.d.ts +13 -0
  86. package/dist/components/buckets/EmptyBucketSummaryList.js +140 -0
  87. package/dist/components/buckets/__tests__/BucketVersioning.test.d.ts +1 -0
  88. package/dist/components/buckets/__tests__/BucketVersioning.test.js +163 -0
  89. package/dist/components/buckets/notifications/BucketNotificationFormPage.d.ts +1 -0
  90. package/dist/components/buckets/notifications/BucketNotificationFormPage.js +316 -0
  91. package/dist/components/buckets/notifications/BucketNotificationList.d.ts +10 -0
  92. package/dist/components/buckets/notifications/BucketNotificationList.js +267 -0
  93. package/dist/components/buckets/notifications/EventsSection.js +145 -29
  94. package/dist/components/buckets/notifications/__tests__/events.test.d.ts +1 -0
  95. package/dist/components/buckets/notifications/__tests__/events.test.js +56 -0
  96. package/dist/components/buckets/notifications/events.d.ts +71 -7
  97. package/dist/components/buckets/notifications/events.js +98 -16
  98. package/dist/components/index.d.ts +27 -13
  99. package/dist/components/index.js +20 -6
  100. package/dist/components/layouts/ArrowNavigation.d.ts +3 -0
  101. package/dist/components/layouts/ArrowNavigation.js +28 -0
  102. package/dist/components/layouts/BrowserPageLayout.d.ts +5 -1
  103. package/dist/components/layouts/BrowserPageLayout.js +10 -5
  104. package/dist/components/objects/CreateFolderButton.d.ts +2 -2
  105. package/dist/components/objects/CreateFolderButton.js +12 -12
  106. package/dist/components/objects/DeleteObjectButton.d.ts +1 -1
  107. package/dist/components/objects/DeleteObjectButton.js +19 -21
  108. package/dist/components/objects/GetPresignedUrlButton.d.ts +7 -0
  109. package/dist/components/objects/GetPresignedUrlButton.js +255 -0
  110. package/dist/components/objects/ObjectDetails/ObjectMetadata.d.ts +2 -2
  111. package/dist/components/objects/ObjectDetails/ObjectMetadata.js +263 -230
  112. package/dist/components/objects/ObjectDetails/ObjectSummary.d.ts +2 -2
  113. package/dist/components/objects/ObjectDetails/ObjectSummary.js +540 -138
  114. package/dist/components/objects/ObjectDetails/ObjectTags.d.ts +2 -2
  115. package/dist/components/objects/ObjectDetails/ObjectTags.js +95 -123
  116. package/dist/components/objects/ObjectDetails/__tests__/ObjectDetails.test.d.ts +1 -0
  117. package/dist/components/objects/ObjectDetails/__tests__/ObjectDetails.test.js +516 -0
  118. package/dist/components/objects/ObjectDetails/__tests__/ObjectSummary.test.d.ts +1 -0
  119. package/dist/components/objects/ObjectDetails/__tests__/ObjectSummary.test.js +1064 -0
  120. package/dist/components/objects/ObjectDetails/index.d.ts +18 -2
  121. package/dist/components/objects/ObjectDetails/index.js +152 -40
  122. package/dist/components/objects/ObjectList.d.ts +12 -10
  123. package/dist/components/objects/ObjectList.js +590 -263
  124. package/dist/components/objects/ObjectLock/EditRetentionButton.d.ts +4 -0
  125. package/dist/components/objects/ObjectLock/EditRetentionButton.js +32 -0
  126. package/dist/components/objects/ObjectLock/ObjectLockRetentionSettings.d.ts +3 -0
  127. package/dist/components/objects/ObjectLock/ObjectLockRetentionSettings.js +211 -0
  128. package/dist/components/objects/ObjectLock/ObjectLockSettings.d.ts +9 -0
  129. package/dist/components/objects/ObjectLock/ObjectLockSettings.js +159 -0
  130. package/dist/components/objects/ObjectLock/ObjectLockSettingsUtils.d.ts +8 -0
  131. package/dist/components/objects/ObjectLock/ObjectLockSettingsUtils.js +39 -0
  132. package/dist/components/objects/ObjectLock/__tests__/EditRetentionButton.test.d.ts +1 -0
  133. package/dist/components/objects/ObjectLock/__tests__/EditRetentionButton.test.js +204 -0
  134. package/dist/components/objects/ObjectLock/__tests__/ObjectLockSettings.test.d.ts +1 -0
  135. package/dist/components/objects/ObjectLock/__tests__/ObjectLockSettings.test.js +374 -0
  136. package/dist/components/objects/ObjectPage.js +12 -8
  137. package/dist/components/objects/UploadButton.d.ts +3 -3
  138. package/dist/components/objects/UploadButton.js +10 -10
  139. package/dist/components/objects/__tests__/GetPresignedUrlButton.test.d.ts +1 -0
  140. package/dist/components/objects/__tests__/GetPresignedUrlButton.test.js +531 -0
  141. package/dist/components/providers/DataBrowserProvider.d.ts +23 -12
  142. package/dist/components/providers/DataBrowserProvider.js +60 -38
  143. package/dist/components/providers/QueryProvider.d.ts +9 -0
  144. package/dist/components/providers/QueryProvider.js +21 -0
  145. package/dist/components/search/MetadataSearch.js +29 -28
  146. package/dist/components/search/SearchHints.js +1 -1
  147. package/dist/components/ui/ArrayFieldActions.d.ts +36 -0
  148. package/dist/components/ui/ArrayFieldActions.js +43 -0
  149. package/dist/components/ui/ConfirmDeleteRuleModal.d.ts +16 -0
  150. package/dist/components/ui/ConfirmDeleteRuleModal.js +48 -0
  151. package/dist/components/ui/DeleteObjectModalContent.d.ts +1 -1
  152. package/dist/components/ui/DeleteObjectModalContent.js +12 -12
  153. package/dist/components/ui/FilterFormSection.d.ts +44 -0
  154. package/dist/components/ui/FilterFormSection.js +159 -0
  155. package/dist/components/ui/Search.elements.d.ts +2 -2
  156. package/dist/components/ui/Search.elements.js +7 -7
  157. package/dist/components/ui/Table.elements.d.ts +2 -1
  158. package/dist/components/ui/Table.elements.js +18 -12
  159. package/dist/config/__tests__/factory.test.d.ts +1 -0
  160. package/dist/config/__tests__/factory.test.js +311 -0
  161. package/dist/config/factory.d.ts +14 -49
  162. package/dist/config/factory.js +23 -68
  163. package/dist/config/types.d.ts +212 -34
  164. package/dist/contexts/DataBrowserUICustomizationContext.d.ts +27 -0
  165. package/dist/contexts/DataBrowserUICustomizationContext.js +13 -0
  166. package/dist/hooks/__tests__/useAccessibleBuckets.test.d.ts +1 -0
  167. package/dist/hooks/__tests__/useAccessibleBuckets.test.js +145 -0
  168. package/dist/hooks/__tests__/useISVBucketDetection.test.d.ts +1 -0
  169. package/dist/hooks/__tests__/useISVBucketDetection.test.js +188 -0
  170. package/dist/hooks/__tests__/useIsBucketEmpty.test.js +27 -27
  171. package/dist/hooks/__tests__/useLoginMutation.test.d.ts +1 -0
  172. package/dist/hooks/__tests__/useLoginMutation.test.js +194 -0
  173. package/dist/hooks/bucketConfiguration.d.ts +8 -1
  174. package/dist/hooks/bucketConfiguration.js +52 -51
  175. package/dist/hooks/bucketOperations.d.ts +10 -1
  176. package/dist/hooks/bucketOperations.js +10 -9
  177. package/dist/hooks/factories/__tests__/useCreateS3FunctionMutationHook.test.js +80 -80
  178. package/dist/hooks/factories/__tests__/useCreateS3InfiniteQueryHook.test.js +80 -80
  179. package/dist/hooks/factories/__tests__/useCreateS3LoginHook.test.js +44 -44
  180. package/dist/hooks/factories/__tests__/useCreateS3MutationHook.test.js +63 -63
  181. package/dist/hooks/factories/__tests__/useCreateS3QueryHook.test.js +95 -52
  182. package/dist/hooks/factories/index.d.ts +4 -4
  183. package/dist/hooks/factories/index.js +2 -2
  184. package/dist/hooks/factories/useCreateS3InfiniteQueryHook.d.ts +2 -2
  185. package/dist/hooks/factories/useCreateS3InfiniteQueryHook.js +16 -13
  186. package/dist/hooks/factories/useCreateS3LoginHook.d.ts +2 -2
  187. package/dist/hooks/factories/useCreateS3LoginHook.js +1 -1
  188. package/dist/hooks/factories/useCreateS3MutationHook.d.ts +3 -3
  189. package/dist/hooks/factories/useCreateS3MutationHook.js +7 -2
  190. package/dist/hooks/factories/useCreateS3QueryHook.d.ts +2 -2
  191. package/dist/hooks/factories/useCreateS3QueryHook.js +29 -3
  192. package/dist/hooks/index.d.ts +19 -8
  193. package/dist/hooks/index.js +16 -5
  194. package/dist/hooks/loginOperations.d.ts +1 -1
  195. package/dist/hooks/loginOperations.js +1 -1
  196. package/dist/hooks/objectOperations.d.ts +2 -2
  197. package/dist/hooks/objectOperations.js +50 -49
  198. package/dist/hooks/presignedOperations.d.ts +4 -4
  199. package/dist/hooks/presignedOperations.js +5 -5
  200. package/dist/hooks/useAccessibleBuckets.d.ts +11 -0
  201. package/dist/hooks/useAccessibleBuckets.js +115 -0
  202. package/dist/hooks/useBatchObjectLegalHold.d.ts +11 -0
  203. package/dist/hooks/useBatchObjectLegalHold.js +48 -0
  204. package/dist/hooks/useBucketConfigEditor.d.ts +31 -0
  205. package/dist/hooks/useBucketConfigEditor.js +82 -0
  206. package/dist/hooks/useDataBrowserNavigate.d.ts +28 -0
  207. package/dist/hooks/useDataBrowserNavigate.js +24 -0
  208. package/dist/hooks/useDeleteBucketConfigRule.d.ts +26 -0
  209. package/dist/hooks/useDeleteBucketConfigRule.js +46 -0
  210. package/dist/hooks/useEmptyBucket.d.ts +27 -0
  211. package/dist/hooks/useEmptyBucket.js +116 -0
  212. package/dist/hooks/useFeatures.d.ts +7 -0
  213. package/dist/hooks/useFeatures.js +8 -0
  214. package/dist/hooks/useISVBucketDetection.d.ts +15 -0
  215. package/dist/hooks/useISVBucketDetection.js +27 -0
  216. package/dist/hooks/useIsBucketEmpty.js +4 -4
  217. package/dist/hooks/useLimitedAccessFlow.d.ts +48 -0
  218. package/dist/hooks/useLimitedAccessFlow.js +23 -0
  219. package/dist/hooks/useS3Client.d.ts +6 -0
  220. package/dist/hooks/useS3Client.js +3 -2
  221. package/dist/hooks/useS3ConfigSwitch.d.ts +11 -0
  222. package/dist/hooks/useS3ConfigSwitch.js +37 -0
  223. package/dist/hooks/useSupportedNotificationEvents.d.ts +6 -0
  224. package/dist/hooks/useSupportedNotificationEvents.js +8 -0
  225. package/dist/hooks/useTableRowSelection.d.ts +9 -0
  226. package/dist/hooks/useTableRowSelection.js +45 -0
  227. package/dist/index.d.ts +6 -6
  228. package/dist/index.js +2 -2
  229. package/dist/schemas/bucketPolicySchema.json +3 -13
  230. package/dist/test/msw/handlers/deleteBucket.d.ts +1 -1
  231. package/dist/test/msw/handlers/deleteBucket.js +20 -10
  232. package/dist/test/msw/handlers/getBucketAcl.d.ts +1 -1
  233. package/dist/test/msw/handlers/getBucketAcl.js +29 -17
  234. package/dist/test/msw/handlers/getBucketLocation.d.ts +1 -1
  235. package/dist/test/msw/handlers/getBucketLocation.js +29 -15
  236. package/dist/test/msw/handlers/getBucketPolicy.d.ts +1 -1
  237. package/dist/test/msw/handlers/getBucketPolicy.js +52 -32
  238. package/dist/test/msw/handlers/headObject.d.ts +1 -1
  239. package/dist/test/msw/handlers/headObject.js +31 -13
  240. package/dist/test/msw/handlers/listBuckets.d.ts +1 -1
  241. package/dist/test/msw/handlers/listBuckets.js +5 -3
  242. package/dist/test/msw/handlers/listObjectVersions.d.ts +1 -1
  243. package/dist/test/msw/handlers/listObjectVersions.js +38 -26
  244. package/dist/test/msw/handlers/listObjects.d.ts +1 -1
  245. package/dist/test/msw/handlers/listObjects.js +35 -23
  246. package/dist/test/msw/handlers/objectLegalHold.d.ts +1 -1
  247. package/dist/test/msw/handlers/objectLegalHold.js +32 -17
  248. package/dist/test/msw/handlers/objectRetention.d.ts +1 -1
  249. package/dist/test/msw/handlers/objectRetention.js +31 -17
  250. package/dist/test/msw/handlers/putBucketAcl.d.ts +1 -1
  251. package/dist/test/msw/handlers/putBucketAcl.js +29 -14
  252. package/dist/test/msw/handlers/putObject.d.ts +1 -1
  253. package/dist/test/msw/handlers/putObject.js +27 -12
  254. package/dist/test/msw/handlers.d.ts +3 -3
  255. package/dist/test/msw/handlers.js +77 -54
  256. package/dist/test/msw/index.d.ts +2 -2
  257. package/dist/test/msw/index.js +1 -1
  258. package/dist/test/msw/server.d.ts +1 -1
  259. package/dist/test/msw/server.js +1 -1
  260. package/dist/test/msw/utils.js +2 -2
  261. package/dist/test/setup.d.ts +1 -1
  262. package/dist/test/setup.js +13 -30
  263. package/dist/test/testUtils.d.ts +170 -36
  264. package/dist/test/testUtils.js +229 -116
  265. package/dist/test/utils/errorHandling.test.js +146 -108
  266. package/dist/types/index.d.ts +49 -36
  267. package/dist/types/monaco.d.ts +13 -0
  268. package/dist/types/monaco.js +0 -0
  269. package/dist/utils/__tests__/proxyMiddleware.test.d.ts +1 -0
  270. package/dist/utils/__tests__/proxyMiddleware.test.js +579 -0
  271. package/dist/utils/__tests__/s3Client.test.d.ts +1 -0
  272. package/dist/utils/__tests__/s3Client.test.js +340 -0
  273. package/dist/utils/__tests__/s3ConfigIdentifier.test.d.ts +1 -0
  274. package/dist/utils/__tests__/s3ConfigIdentifier.test.js +437 -0
  275. package/dist/utils/constants.d.ts +22 -0
  276. package/dist/utils/constants.js +19 -0
  277. package/dist/utils/deletion/index.d.ts +2 -2
  278. package/dist/utils/deletion/index.js +1 -1
  279. package/dist/utils/deletion/messages.d.ts +1 -1
  280. package/dist/utils/deletion/messages.js +4 -4
  281. package/dist/utils/errorHandling.d.ts +12 -3
  282. package/dist/utils/errorHandling.js +12 -7
  283. package/dist/utils/hooks.js +8 -8
  284. package/dist/utils/index.d.ts +5 -2
  285. package/dist/utils/index.js +5 -1
  286. package/dist/utils/proxyMiddleware.d.ts +32 -13
  287. package/dist/utils/proxyMiddleware.js +90 -36
  288. package/dist/utils/s3Client.d.ts +14 -4
  289. package/dist/utils/s3Client.js +5 -26
  290. package/dist/utils/s3ConfigIdentifier.d.ts +79 -0
  291. package/dist/utils/s3ConfigIdentifier.js +57 -0
  292. package/dist/utils/s3RuleUtils.d.ts +53 -0
  293. package/dist/utils/s3RuleUtils.js +101 -0
  294. package/package.json +10 -8
  295. package/dist/components/__tests__/BucketNotificationCreatePage.test.js +0 -316
  296. package/dist/components/buckets/BucketPolicyButton.d.ts +0 -7
  297. package/dist/components/buckets/notifications/BucketNotificationCreatePage.d.ts +0 -1
  298. package/dist/components/buckets/notifications/BucketNotificationCreatePage.js +0 -234
  299. package/dist/hooks/useLoginMutation.d.ts +0 -21
  300. package/dist/hooks/useLoginMutation.js +0 -9
  301. package/dist/utils/useFeatures.d.ts +0 -1
  302. package/dist/utils/useFeatures.js +0 -7
  303. /package/dist/components/__tests__/{BucketNotificationCreatePage.test.d.ts → BucketAccessor.test.d.ts} +0 -0
@@ -0,0 +1,835 @@
1
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
2
+ import { joiResolver } from "@hookform/resolvers/joi";
3
+ import { Form, FormGroup, FormSection, Icon, Loader, Stack, Text, Toggle, spacing, useToast } from "@scality/core-ui";
4
+ import { convertRemToPixels } from "@scality/core-ui/dist/components/tablev2/TableUtils";
5
+ import { Box, Button, Input, Select } from "@scality/core-ui/dist/next";
6
+ import joi from "joi";
7
+ import { useCallback, useEffect, useMemo, useRef } from "react";
8
+ import { Controller, FormProvider, useFieldArray, useForm } from "react-hook-form";
9
+ import { useParams } from "react-router";
10
+ import { useGetBucketReplication, useSetBucketReplication } from "../../hooks/bucketConfiguration.js";
11
+ import { useBuckets } from "../../hooks/bucketOperations.js";
12
+ import { useDataBrowserNavigate } from "../../hooks/useDataBrowserNavigate.js";
13
+ import { AWS_RULE_LIMITS, STATUS_OPTIONS, buildS3Filter } from "../../utils/s3RuleUtils.js";
14
+ import { FilterFormSection, createFilterValidationSchema } from "../ui/FilterFormSection.js";
15
+ const storageClassOptions = [
16
+ {
17
+ value: '',
18
+ label: 'Same as source'
19
+ },
20
+ {
21
+ value: 'GLACIER',
22
+ label: 'Glacier'
23
+ },
24
+ {
25
+ value: 'DEEP_ARCHIVE',
26
+ label: 'Glacier Deep Archive'
27
+ },
28
+ {
29
+ value: 'STANDARD_IA',
30
+ label: 'Standard-IA'
31
+ },
32
+ {
33
+ value: 'ONEZONE_IA',
34
+ label: 'One Zone-IA'
35
+ },
36
+ {
37
+ value: 'INTELLIGENT_TIERING',
38
+ label: 'Intelligent-Tiering'
39
+ },
40
+ {
41
+ value: 'GLACIER_IR',
42
+ label: 'Glacier Instant Retrieval'
43
+ }
44
+ ];
45
+ const createSchema = (hasExistingRules)=>joi.object({
46
+ role: hasExistingRules ? joi.string().optional() : joi.string().required().messages({
47
+ 'string.empty': 'Role ARN is required for first replication rule'
48
+ }),
49
+ ruleId: joi.string().required().max(AWS_RULE_LIMITS.RULE_ID_MAX_LENGTH).messages({
50
+ 'string.empty': 'Rule ID is required',
51
+ 'string.max': `Rule ID must not exceed ${AWS_RULE_LIMITS.RULE_ID_MAX_LENGTH} characters`
52
+ }),
53
+ status: joi.string().valid(...STATUS_OPTIONS.map((o)=>o.value)).required(),
54
+ priority: joi.number().integer().min(0).allow(null).optional().messages({
55
+ 'number.base': 'Priority must be a number',
56
+ 'number.min': 'Priority must be at least 0'
57
+ }),
58
+ ...createFilterValidationSchema(joi),
59
+ includeEncryptedObjects: joi.boolean(),
60
+ replicaModifications: joi.boolean(),
61
+ sameAccount: joi.boolean(),
62
+ targetBucket: joi.string().required().messages({
63
+ 'string.empty': 'Target bucket is required'
64
+ }),
65
+ targetAccountId: joi.when('sameAccount', {
66
+ is: false,
67
+ then: joi.string().required().messages({
68
+ 'string.empty': 'Target account ID is required for cross-account replication'
69
+ }),
70
+ otherwise: joi.string().allow('').optional()
71
+ }),
72
+ storageClass: joi.string().allow('').optional(),
73
+ encryptReplicatedObjects: joi.boolean().custom((value, helpers)=>{
74
+ const { includeEncryptedObjects } = helpers.state.ancestors[0];
75
+ if (includeEncryptedObjects && !value) return helpers.error('any.invalid', {
76
+ message: 'Encryption must be enabled when replicating encrypted objects'
77
+ });
78
+ return value;
79
+ }),
80
+ replicaKmsKeyId: joi.when('encryptReplicatedObjects', {
81
+ is: true,
82
+ then: joi.string().required().messages({
83
+ 'string.empty': 'Replica KMS Key ID is required when encrypting replicated objects'
84
+ }),
85
+ otherwise: joi.string().allow('').optional()
86
+ }),
87
+ enforceRTC: joi.boolean(),
88
+ enableRTCNotification: joi.when('enforceRTC', {
89
+ is: true,
90
+ then: joi.boolean().valid(true).messages({
91
+ 'any.only': 'Metrics must be enabled when RTC is enabled'
92
+ }),
93
+ otherwise: joi.boolean()
94
+ }),
95
+ deleteMarkerReplication: joi.boolean(),
96
+ switchObjectOwnership: joi.boolean()
97
+ });
98
+ const ruleToFormValues = (rule, role)=>{
99
+ const formValues = {
100
+ role,
101
+ ruleId: rule.ID || '',
102
+ status: rule.Status || 'Enabled',
103
+ priority: rule.Priority ?? null,
104
+ filterType: 'none',
105
+ prefix: '',
106
+ tags: [],
107
+ includeEncryptedObjects: false,
108
+ replicaModifications: false,
109
+ sameAccount: true,
110
+ targetBucket: '',
111
+ targetAccountId: '',
112
+ storageClass: '',
113
+ encryptReplicatedObjects: false,
114
+ replicaKmsKeyId: '',
115
+ enforceRTC: false,
116
+ enableRTCNotification: false,
117
+ deleteMarkerReplication: false,
118
+ switchObjectOwnership: false
119
+ };
120
+ if (void 0 !== rule.Prefix && '' !== rule.Prefix) {
121
+ formValues.filterType = 'prefix';
122
+ formValues.prefix = rule.Prefix;
123
+ } else if (rule.Filter) {
124
+ if (rule.Filter.And) {
125
+ formValues.filterType = 'and';
126
+ formValues.prefix = rule.Filter.And.Prefix || '';
127
+ formValues.tags = rule.Filter.And.Tags?.map((tag)=>({
128
+ key: tag.Key || '',
129
+ value: tag.Value || ''
130
+ })) || [];
131
+ } else if (void 0 !== rule.Filter.Prefix) {
132
+ formValues.filterType = 'prefix';
133
+ formValues.prefix = rule.Filter.Prefix;
134
+ } else if (rule.Filter.Tag) {
135
+ formValues.filterType = 'tags';
136
+ formValues.tags = [
137
+ {
138
+ key: rule.Filter.Tag.Key || '',
139
+ value: rule.Filter.Tag.Value || ''
140
+ }
141
+ ];
142
+ }
143
+ }
144
+ if (rule.SourceSelectionCriteria) {
145
+ formValues.includeEncryptedObjects = rule.SourceSelectionCriteria.SseKmsEncryptedObjects?.Status === 'Enabled';
146
+ formValues.replicaModifications = rule.SourceSelectionCriteria.ReplicaModifications?.Status === 'Enabled';
147
+ }
148
+ if (rule.Destination) {
149
+ const bucketArn = rule.Destination.Bucket || '';
150
+ const parts = bucketArn.split(':::');
151
+ formValues.targetBucket = parts[parts.length - 1] || bucketArn;
152
+ if (rule.Destination.Account) {
153
+ formValues.sameAccount = false;
154
+ formValues.targetAccountId = rule.Destination.Account;
155
+ } else formValues.sameAccount = true;
156
+ formValues.storageClass = rule.Destination.StorageClass || '';
157
+ formValues.switchObjectOwnership = rule.Destination.AccessControlTranslation?.Owner === 'Destination';
158
+ if (rule.Destination.ReplicationTime) formValues.enforceRTC = 'Enabled' === rule.Destination.ReplicationTime.Status;
159
+ if (rule.Destination.Metrics) formValues.enableRTCNotification = 'Enabled' === rule.Destination.Metrics.Status;
160
+ if (rule.Destination.EncryptionConfiguration) {
161
+ formValues.encryptReplicatedObjects = true;
162
+ formValues.replicaKmsKeyId = rule.Destination.EncryptionConfiguration.ReplicaKmsKeyID || '';
163
+ }
164
+ }
165
+ if (rule.DeleteMarkerReplication) formValues.deleteMarkerReplication = 'Enabled' === rule.DeleteMarkerReplication.Status;
166
+ return formValues;
167
+ };
168
+ const ToggleFormField = ({ name, label, id, control, labelHelpTooltip })=>/*#__PURE__*/ jsx(FormGroup, {
169
+ label: label,
170
+ id: id,
171
+ direction: "horizontal",
172
+ labelHelpTooltip: labelHelpTooltip,
173
+ content: /*#__PURE__*/ jsx(Controller, {
174
+ name: name,
175
+ control: control,
176
+ render: ({ field })=>/*#__PURE__*/ jsx(Toggle, {
177
+ toggle: field.value,
178
+ onChange: field.onChange,
179
+ label: field.value ? 'Enabled' : 'Disabled'
180
+ })
181
+ })
182
+ });
183
+ const buildDestination = (data)=>({
184
+ Bucket: `arn:aws:s3:::${data.targetBucket}`,
185
+ ...!data.sameAccount && data.targetAccountId && '' !== data.targetAccountId.trim() && {
186
+ Account: data.targetAccountId
187
+ },
188
+ ...data.storageClass && '' !== data.storageClass.trim() && {
189
+ StorageClass: data.storageClass
190
+ },
191
+ ...(data.enforceRTC || data.enableRTCNotification) && {
192
+ ReplicationTime: {
193
+ Status: data.enforceRTC ? 'Enabled' : 'Disabled',
194
+ Time: {
195
+ Minutes: 15
196
+ }
197
+ },
198
+ Metrics: {
199
+ Status: 'Enabled',
200
+ ...data.enforceRTC && {
201
+ EventThreshold: {
202
+ Minutes: 15
203
+ }
204
+ }
205
+ }
206
+ },
207
+ ...data.encryptReplicatedObjects && data.replicaKmsKeyId && '' !== data.replicaKmsKeyId.trim() && {
208
+ EncryptionConfiguration: {
209
+ ReplicaKmsKeyID: data.replicaKmsKeyId
210
+ }
211
+ },
212
+ ...!data.sameAccount && data.switchObjectOwnership && data.targetAccountId && '' !== data.targetAccountId.trim() && {
213
+ AccessControlTranslation: {
214
+ Owner: 'Destination'
215
+ }
216
+ }
217
+ });
218
+ const buildSourceSelectionCriteria = (data)=>{
219
+ if (data.includeEncryptedObjects || data.replicaModifications) return {
220
+ ...data.includeEncryptedObjects && {
221
+ SseKmsEncryptedObjects: {
222
+ Status: 'Enabled'
223
+ }
224
+ },
225
+ ...data.replicaModifications && {
226
+ ReplicaModifications: {
227
+ Status: 'Enabled'
228
+ }
229
+ }
230
+ };
231
+ };
232
+ const buildReplicationRule = (data)=>{
233
+ const rule = {
234
+ ID: data.ruleId,
235
+ Status: data.status,
236
+ Priority: data.priority ?? 0,
237
+ Destination: buildDestination(data)
238
+ };
239
+ const filter = buildS3Filter(data);
240
+ if (filter) rule.Filter = filter;
241
+ const sourceSelectionCriteria = buildSourceSelectionCriteria(data);
242
+ if (sourceSelectionCriteria) rule.SourceSelectionCriteria = sourceSelectionCriteria;
243
+ rule.DeleteMarkerReplication = {
244
+ Status: data.deleteMarkerReplication ? 'Enabled' : 'Disabled'
245
+ };
246
+ return rule;
247
+ };
248
+ function BucketReplicationFormPage() {
249
+ const { bucketName, ruleId } = useParams();
250
+ const navigate = useDataBrowserNavigate();
251
+ const { showToast } = useToast();
252
+ const isEditMode = !!ruleId;
253
+ const { data: replicationData, status: replicationStatus } = useGetBucketReplication({
254
+ Bucket: bucketName
255
+ });
256
+ const { data: bucketsData } = useBuckets();
257
+ const availableBuckets = bucketsData?.Buckets || [];
258
+ const existingRole = replicationData?.ReplicationConfiguration?.Role || '';
259
+ const hasExistingRules = (replicationData?.ReplicationConfiguration?.Rules || []).length > 0;
260
+ const existingRule = useMemo(()=>{
261
+ if (!isEditMode || !replicationData?.ReplicationConfiguration?.Rules || !ruleId) return null;
262
+ return replicationData.ReplicationConfiguration.Rules.find((rule)=>rule.ID === decodeURIComponent(ruleId)) || null;
263
+ }, [
264
+ isEditMode,
265
+ replicationData,
266
+ ruleId
267
+ ]);
268
+ const existingRuleIds = useMemo(()=>(replicationData?.ReplicationConfiguration?.Rules || []).map((rule)=>rule.ID).filter(Boolean).filter((id)=>!isEditMode || id !== existingRule?.ID), [
269
+ replicationData,
270
+ isEditMode,
271
+ existingRule
272
+ ]);
273
+ const nextAvailablePriority = useMemo(()=>{
274
+ const existingRules = replicationData?.ReplicationConfiguration?.Rules || [];
275
+ if (0 === existingRules.length) return 0;
276
+ const priorities = existingRules.map((rule)=>rule.Priority).filter((p)=>null != p);
277
+ if (0 === priorities.length) return 0;
278
+ return Math.max(...priorities) + 1;
279
+ }, [
280
+ replicationData
281
+ ]);
282
+ const dynamicSchema = useMemo(()=>createSchema(hasExistingRules).keys({
283
+ ruleId: joi.string().required().invalid(...existingRuleIds).messages({
284
+ 'string.empty': 'Rule ID is required',
285
+ 'any.invalid': 'A rule with this ID already exists'
286
+ })
287
+ }), [
288
+ existingRuleIds,
289
+ hasExistingRules
290
+ ]);
291
+ const methods = useForm({
292
+ resolver: joiResolver(dynamicSchema),
293
+ mode: 'onChange',
294
+ defaultValues: {
295
+ role: '',
296
+ ruleId: '',
297
+ status: 'Enabled',
298
+ priority: null,
299
+ filterType: 'none',
300
+ prefix: '',
301
+ tags: [],
302
+ includeEncryptedObjects: false,
303
+ replicaModifications: false,
304
+ sameAccount: true,
305
+ targetBucket: '',
306
+ targetAccountId: '',
307
+ storageClass: '',
308
+ encryptReplicatedObjects: false,
309
+ replicaKmsKeyId: '',
310
+ enforceRTC: false,
311
+ enableRTCNotification: false,
312
+ deleteMarkerReplication: false,
313
+ switchObjectOwnership: false
314
+ }
315
+ });
316
+ const { handleSubmit, register, control, watch, reset, formState: { isValid, isDirty, errors } } = methods;
317
+ const { fields: tagFields, append: appendTag, remove: removeTag } = useFieldArray({
318
+ control,
319
+ name: 'tags'
320
+ });
321
+ const filterType = watch('filterType');
322
+ const sameAccount = watch('sameAccount');
323
+ const encryptReplicatedObjects = watch('encryptReplicatedObjects');
324
+ const includeEncryptedObjects = watch('includeEncryptedObjects');
325
+ const deleteMarkerReplication = watch('deleteMarkerReplication');
326
+ const enforceRTC = watch('enforceRTC');
327
+ const { mutate: setReplication, isPending: isSaving } = useSetBucketReplication();
328
+ const loadedRuleIdRef = useRef(null);
329
+ useEffect(()=>{
330
+ if (isEditMode && existingRule) {
331
+ if (loadedRuleIdRef.current !== existingRule.ID) {
332
+ const formValues = ruleToFormValues(existingRule, existingRole);
333
+ reset(formValues);
334
+ loadedRuleIdRef.current = existingRule.ID || null;
335
+ }
336
+ } else if (!isEditMode && !isDirty) {
337
+ reset((prev)=>({
338
+ ...prev,
339
+ role: existingRole,
340
+ priority: nextAvailablePriority
341
+ }));
342
+ loadedRuleIdRef.current = null;
343
+ }
344
+ }, [
345
+ isEditMode,
346
+ existingRule,
347
+ existingRole,
348
+ nextAvailablePriority,
349
+ isDirty,
350
+ reset
351
+ ]);
352
+ const prevFilterTypeRef = useRef();
353
+ useEffect(()=>{
354
+ const prevFilterType = prevFilterTypeRef.current;
355
+ prevFilterTypeRef.current = filterType;
356
+ if (('tags' === filterType || 'and' === filterType) && 0 === tagFields.length) {
357
+ if (!isEditMode || void 0 !== prevFilterType && prevFilterType !== filterType) appendTag({
358
+ key: '',
359
+ value: ''
360
+ });
361
+ }
362
+ if (void 0 !== prevFilterType && prevFilterType !== filterType) {
363
+ if (('none' === filterType || 'prefix' === filterType) && tagFields.length > 0) tagFields.forEach((_, index)=>{
364
+ removeTag(tagFields.length - 1 - index);
365
+ });
366
+ if ('none' === filterType) methods.setValue('prefix', '', {
367
+ shouldDirty: true
368
+ });
369
+ }
370
+ }, [
371
+ isEditMode,
372
+ filterType,
373
+ tagFields,
374
+ appendTag,
375
+ removeTag,
376
+ methods
377
+ ]);
378
+ useEffect(()=>{
379
+ if (includeEncryptedObjects && !encryptReplicatedObjects) methods.setValue('encryptReplicatedObjects', true, {
380
+ shouldValidate: true
381
+ });
382
+ }, [
383
+ includeEncryptedObjects,
384
+ encryptReplicatedObjects,
385
+ methods
386
+ ]);
387
+ useEffect(()=>{
388
+ if (('tags' === filterType || 'and' === filterType) && deleteMarkerReplication) methods.setValue('deleteMarkerReplication', false, {
389
+ shouldValidate: true
390
+ });
391
+ }, [
392
+ filterType,
393
+ deleteMarkerReplication,
394
+ methods
395
+ ]);
396
+ useEffect(()=>{
397
+ if (enforceRTC) methods.setValue('enableRTCNotification', true, {
398
+ shouldValidate: true
399
+ });
400
+ }, [
401
+ enforceRTC,
402
+ methods
403
+ ]);
404
+ const handleCancel = useCallback(()=>{
405
+ navigate(`/buckets/${bucketName}?tab=replication`);
406
+ }, [
407
+ navigate,
408
+ bucketName
409
+ ]);
410
+ const onSubmit = useCallback((data)=>{
411
+ if (!bucketName) return;
412
+ const rule = buildReplicationRule(data);
413
+ const existingRules = replicationData?.ReplicationConfiguration?.Rules || [];
414
+ const updatedRules = isEditMode ? existingRules.map((r)=>r.ID === existingRule?.ID ? rule : r) : [
415
+ ...existingRules,
416
+ rule
417
+ ];
418
+ setReplication({
419
+ Bucket: bucketName,
420
+ ReplicationConfiguration: {
421
+ Role: data.role,
422
+ Rules: updatedRules
423
+ }
424
+ }, {
425
+ onSuccess: ()=>{
426
+ showToast({
427
+ open: true,
428
+ message: `Replication rule ${isEditMode ? 'updated' : 'created'} successfully`,
429
+ status: 'success'
430
+ });
431
+ navigate(`/buckets/${bucketName}?tab=replication`);
432
+ },
433
+ onError: (error)=>{
434
+ const errorMessage = error instanceof Error ? error.message : `Failed to ${isEditMode ? 'update' : 'create'} replication rule`;
435
+ showToast({
436
+ open: true,
437
+ message: errorMessage,
438
+ status: 'error'
439
+ });
440
+ }
441
+ });
442
+ }, [
443
+ bucketName,
444
+ setReplication,
445
+ navigate,
446
+ showToast,
447
+ replicationData,
448
+ isEditMode,
449
+ existingRule
450
+ ]);
451
+ if ('pending' === replicationStatus) return /*#__PURE__*/ jsx(Loader, {
452
+ centered: true,
453
+ children: /*#__PURE__*/ jsx(Text, {
454
+ children: "Loading..."
455
+ })
456
+ });
457
+ if (isEditMode && !existingRule) return /*#__PURE__*/ jsx(Box, {
458
+ padding: spacing.r16,
459
+ children: /*#__PURE__*/ jsx(Text, {
460
+ color: "statusCritical",
461
+ children: "Rule not found"
462
+ })
463
+ });
464
+ return /*#__PURE__*/ jsx(FormProvider, {
465
+ ...methods,
466
+ children: /*#__PURE__*/ jsxs(Form, {
467
+ layout: {
468
+ kind: 'page',
469
+ title: isEditMode ? 'Edit Replication Rule' : 'Create Replication Rule'
470
+ },
471
+ requireMode: "partial",
472
+ onSubmit: handleSubmit(onSubmit),
473
+ rightActions: /*#__PURE__*/ jsxs(Stack, {
474
+ gap: "r16",
475
+ children: [
476
+ /*#__PURE__*/ jsx(Button, {
477
+ id: "cancel-btn",
478
+ variant: "outline",
479
+ type: "button",
480
+ label: "Cancel",
481
+ onClick: handleCancel,
482
+ disabled: isSaving
483
+ }),
484
+ /*#__PURE__*/ jsx(Button, {
485
+ id: isEditMode ? 'save-replication-btn' : 'create-replication-btn',
486
+ type: "submit",
487
+ variant: "primary",
488
+ label: isEditMode ? 'Save' : 'Create',
489
+ icon: isEditMode ? /*#__PURE__*/ jsx(Icon, {
490
+ name: "Save"
491
+ }) : void 0,
492
+ disabled: !isDirty || !isValid || isSaving
493
+ })
494
+ ]
495
+ }),
496
+ children: [
497
+ /*#__PURE__*/ jsx(FormSection, {
498
+ title: {
499
+ name: 'Role'
500
+ },
501
+ forceLabelWidth: convertRemToPixels(15),
502
+ children: /*#__PURE__*/ jsx(FormGroup, {
503
+ label: "Role ARN",
504
+ id: "role",
505
+ direction: "horizontal",
506
+ error: errors?.role?.message,
507
+ helpErrorPosition: "bottom",
508
+ required: !hasExistingRules,
509
+ content: hasExistingRules ? /*#__PURE__*/ jsxs(Stack, {
510
+ direction: "vertical",
511
+ gap: "r8",
512
+ children: [
513
+ /*#__PURE__*/ jsx(Text, {
514
+ children: existingRole || 'Not set'
515
+ }),
516
+ /*#__PURE__*/ jsx(Text, {
517
+ color: "textSecondary",
518
+ children: "To change the Role, edit it through bucket configuration or delete all rules first"
519
+ })
520
+ ]
521
+ }) : /*#__PURE__*/ jsx(Input, {
522
+ id: "role",
523
+ placeholder: "arn:aws:iam::123456789012:role/replication-role",
524
+ ...register('role')
525
+ })
526
+ })
527
+ }),
528
+ /*#__PURE__*/ jsxs(FormSection, {
529
+ title: {
530
+ name: 'Rule Scope'
531
+ },
532
+ forceLabelWidth: convertRemToPixels(15),
533
+ children: [
534
+ /*#__PURE__*/ jsx(FormGroup, {
535
+ label: "Rule ID / Name",
536
+ id: "ruleId",
537
+ direction: "horizontal",
538
+ error: errors?.ruleId?.message,
539
+ helpErrorPosition: "bottom",
540
+ required: true,
541
+ content: isEditMode ? /*#__PURE__*/ jsx(Text, {
542
+ children: watch('ruleId')
543
+ }) : /*#__PURE__*/ jsx(Input, {
544
+ id: "ruleId",
545
+ ...register('ruleId')
546
+ })
547
+ }),
548
+ /*#__PURE__*/ jsx(FormGroup, {
549
+ label: "Status",
550
+ id: "status",
551
+ direction: "horizontal",
552
+ error: errors?.status?.message,
553
+ helpErrorPosition: "bottom",
554
+ required: true,
555
+ content: /*#__PURE__*/ jsx(Controller, {
556
+ name: "status",
557
+ control: control,
558
+ render: ({ field })=>/*#__PURE__*/ jsx(Select, {
559
+ id: "status",
560
+ value: field.value,
561
+ onChange: field.onChange,
562
+ children: STATUS_OPTIONS.map((option)=>/*#__PURE__*/ jsx(Select.Option, {
563
+ value: option.value,
564
+ children: option.label
565
+ }, option.value))
566
+ })
567
+ })
568
+ }),
569
+ /*#__PURE__*/ jsx(FormGroup, {
570
+ label: "Rule priority",
571
+ id: "priority",
572
+ direction: "horizontal",
573
+ error: errors?.priority?.message,
574
+ helpErrorPosition: "bottom",
575
+ labelHelpTooltip: "Lower numbers have higher priority. Rules are evaluated in priority order when filters overlap.",
576
+ content: /*#__PURE__*/ jsx(Box, {
577
+ flex: "1",
578
+ children: /*#__PURE__*/ jsx(Input, {
579
+ type: "number",
580
+ id: "priority",
581
+ placeholder: isEditMode ? void 0 : `Auto-assigned: ${nextAvailablePriority}`,
582
+ ...register('priority', {
583
+ setValueAs: (v)=>{
584
+ if ('' === v || null == v) return null;
585
+ const parsed = parseInt(v, 10);
586
+ return isNaN(parsed) ? null : parsed;
587
+ }
588
+ })
589
+ })
590
+ })
591
+ })
592
+ ]
593
+ }),
594
+ /*#__PURE__*/ jsx(FilterFormSection, {
595
+ filterType: filterType,
596
+ onFilterTypeChange: (value)=>methods.setValue('filterType', value),
597
+ prefixRegister: register('prefix'),
598
+ tagFields: tagFields,
599
+ tagKeyRegister: (index)=>register(`tags.${index}.key`),
600
+ tagValueRegister: (index)=>register(`tags.${index}.value`),
601
+ getTagKeyValue: (index)=>watch(`tags.${index}.key`),
602
+ getTagValueValue: (index)=>watch(`tags.${index}.value`),
603
+ appendTag: appendTag,
604
+ removeTag: removeTag,
605
+ errors: errors
606
+ }),
607
+ /*#__PURE__*/ jsxs(FormSection, {
608
+ title: {
609
+ name: 'Destination'
610
+ },
611
+ forceLabelWidth: convertRemToPixels(15),
612
+ children: [
613
+ /*#__PURE__*/ jsx(FormGroup, {
614
+ label: "Destination",
615
+ id: "sameAccount",
616
+ direction: "horizontal",
617
+ content: /*#__PURE__*/ jsx(Controller, {
618
+ name: "sameAccount",
619
+ control: control,
620
+ render: ({ field })=>/*#__PURE__*/ jsx(Toggle, {
621
+ toggle: field.value,
622
+ onChange: field.onChange,
623
+ label: field.value ? 'Same account destination' : 'Not same account destination'
624
+ })
625
+ })
626
+ }),
627
+ sameAccount ? /*#__PURE__*/ jsx(Fragment, {}) : /*#__PURE__*/ jsx(FormGroup, {
628
+ label: "Target account ID",
629
+ id: "targetAccountId",
630
+ direction: "horizontal",
631
+ error: errors?.targetAccountId?.message,
632
+ helpErrorPosition: "bottom",
633
+ required: true,
634
+ content: /*#__PURE__*/ jsx(Input, {
635
+ id: "targetAccountId",
636
+ placeholder: "Account ID",
637
+ ...register('targetAccountId')
638
+ })
639
+ }),
640
+ /*#__PURE__*/ jsx(FormGroup, {
641
+ label: "Target Bucket",
642
+ id: "targetBucket",
643
+ direction: "horizontal",
644
+ error: errors?.targetBucket?.message,
645
+ helpErrorPosition: "bottom",
646
+ required: true,
647
+ content: sameAccount ? /*#__PURE__*/ jsx(Controller, {
648
+ name: "targetBucket",
649
+ control: control,
650
+ render: ({ field })=>/*#__PURE__*/ jsx(Select, {
651
+ id: "targetBucket",
652
+ value: field.value,
653
+ onChange: field.onChange,
654
+ placeholder: "Select a bucket",
655
+ children: availableBuckets.filter((bucket)=>bucket.Name !== bucketName).map((bucket)=>/*#__PURE__*/ jsx(Select.Option, {
656
+ value: bucket.Name || '',
657
+ children: bucket.Name
658
+ }, bucket.Name))
659
+ })
660
+ }) : /*#__PURE__*/ jsx(Input, {
661
+ id: "targetBucket",
662
+ placeholder: "Bucket name",
663
+ ...register('targetBucket')
664
+ })
665
+ }),
666
+ /*#__PURE__*/ jsx(FormGroup, {
667
+ label: "Storage Class",
668
+ id: "storageClass",
669
+ direction: "horizontal",
670
+ error: errors?.storageClass?.message,
671
+ helpErrorPosition: "bottom",
672
+ labelHelpTooltip: "Storage class for replicated objects in destination bucket",
673
+ content: /*#__PURE__*/ jsx(Controller, {
674
+ name: "storageClass",
675
+ control: control,
676
+ render: ({ field })=>/*#__PURE__*/ jsx(Select, {
677
+ id: "storageClass",
678
+ value: field.value,
679
+ onChange: field.onChange,
680
+ children: storageClassOptions.map((option)=>/*#__PURE__*/ jsx(Select.Option, {
681
+ value: option.value,
682
+ children: option.label
683
+ }, option.value))
684
+ })
685
+ })
686
+ }),
687
+ sameAccount ? /*#__PURE__*/ jsx(Fragment, {}) : /*#__PURE__*/ jsx(ToggleFormField, {
688
+ name: "switchObjectOwnership",
689
+ label: "Switch Object ownership",
690
+ id: "switchObjectOwnership",
691
+ control: control,
692
+ labelHelpTooltip: "Change replica ownership to destination bucket owner (AccessControlTranslation)"
693
+ })
694
+ ]
695
+ }),
696
+ /*#__PURE__*/ jsxs(FormSection, {
697
+ title: {
698
+ name: 'Encryption'
699
+ },
700
+ forceLabelWidth: convertRemToPixels(15),
701
+ children: [
702
+ /*#__PURE__*/ jsx(ToggleFormField, {
703
+ name: "includeEncryptedObjects",
704
+ label: "Replicate encrypted objects",
705
+ id: "includeEncryptedObjects",
706
+ control: control,
707
+ labelHelpTooltip: "Replicate objects encrypted with KMS from source bucket"
708
+ }),
709
+ /*#__PURE__*/ jsx(FormGroup, {
710
+ label: "Encrypt replicated objects",
711
+ id: "encryptReplicatedObjects",
712
+ direction: "horizontal",
713
+ error: errors?.encryptReplicatedObjects?.message,
714
+ helpErrorPosition: "bottom",
715
+ labelHelpTooltip: "Encrypt objects in destination bucket using KMS",
716
+ required: includeEncryptedObjects,
717
+ content: /*#__PURE__*/ jsxs(Stack, {
718
+ direction: "vertical",
719
+ gap: "r8",
720
+ children: [
721
+ /*#__PURE__*/ jsx(Controller, {
722
+ name: "encryptReplicatedObjects",
723
+ control: control,
724
+ render: ({ field })=>/*#__PURE__*/ jsx(Toggle, {
725
+ toggle: field.value,
726
+ onChange: field.onChange,
727
+ label: field.value ? 'Enabled' : 'Disabled',
728
+ disabled: includeEncryptedObjects
729
+ })
730
+ }),
731
+ includeEncryptedObjects && /*#__PURE__*/ jsx(Text, {
732
+ color: "textSecondary",
733
+ children: "Encryption is required when replicating encrypted objects"
734
+ })
735
+ ]
736
+ })
737
+ }),
738
+ encryptReplicatedObjects ? /*#__PURE__*/ jsx(FormGroup, {
739
+ label: "Replica KMS Key ID",
740
+ id: "replicaKmsKeyId",
741
+ direction: "horizontal",
742
+ error: errors?.replicaKmsKeyId?.message,
743
+ helpErrorPosition: "bottom",
744
+ labelHelpTooltip: "KMS key ID or ARN to use for encrypting replicated objects",
745
+ required: true,
746
+ content: /*#__PURE__*/ jsx(Input, {
747
+ id: "replicaKmsKeyId",
748
+ placeholder: "KMS Key ID or ARN",
749
+ ...register('replicaKmsKeyId')
750
+ })
751
+ }) : /*#__PURE__*/ jsx(Fragment, {})
752
+ ]
753
+ }),
754
+ /*#__PURE__*/ jsxs(FormSection, {
755
+ title: {
756
+ name: 'Additional Options'
757
+ },
758
+ forceLabelWidth: convertRemToPixels(15),
759
+ children: [
760
+ /*#__PURE__*/ jsx(ToggleFormField, {
761
+ name: "enforceRTC",
762
+ label: "Replication Time Control (RTC)",
763
+ id: "enforceRTC",
764
+ control: control,
765
+ labelHelpTooltip: "Guarantees replication within 15 minutes with SLA monitoring"
766
+ }),
767
+ /*#__PURE__*/ jsx(FormGroup, {
768
+ label: "RTC metrics and notifications",
769
+ id: "enableRTCNotification",
770
+ direction: "horizontal",
771
+ labelHelpTooltip: "Emit S3 events when replication exceeds 15-minute RTC threshold",
772
+ required: enforceRTC,
773
+ content: /*#__PURE__*/ jsxs(Stack, {
774
+ direction: "vertical",
775
+ gap: "r8",
776
+ children: [
777
+ /*#__PURE__*/ jsx(Controller, {
778
+ name: "enableRTCNotification",
779
+ control: control,
780
+ render: ({ field })=>/*#__PURE__*/ jsx(Toggle, {
781
+ toggle: field.value,
782
+ onChange: field.onChange,
783
+ label: field.value ? 'Enabled' : 'Disabled',
784
+ disabled: enforceRTC
785
+ })
786
+ }),
787
+ enforceRTC && /*#__PURE__*/ jsx(Text, {
788
+ color: "textSecondary",
789
+ children: "Metrics must be enabled when RTC is enabled"
790
+ })
791
+ ]
792
+ })
793
+ }),
794
+ /*#__PURE__*/ jsx(ToggleFormField, {
795
+ name: "replicaModifications",
796
+ label: "Replica modification sync",
797
+ id: "replicaModifications",
798
+ control: control,
799
+ labelHelpTooltip: "Replicate metadata changes made to replica objects"
800
+ }),
801
+ /*#__PURE__*/ jsx(FormGroup, {
802
+ label: "Delete marker replication",
803
+ id: "deleteMarkerReplication",
804
+ direction: "horizontal",
805
+ error: errors?.deleteMarkerReplication?.message,
806
+ helpErrorPosition: "bottom",
807
+ labelHelpTooltip: "Replicate delete markers created when objects are deleted in versioned buckets",
808
+ content: /*#__PURE__*/ jsxs(Stack, {
809
+ direction: "vertical",
810
+ gap: "r8",
811
+ children: [
812
+ /*#__PURE__*/ jsx(Controller, {
813
+ name: "deleteMarkerReplication",
814
+ control: control,
815
+ render: ({ field })=>/*#__PURE__*/ jsx(Toggle, {
816
+ toggle: field.value,
817
+ onChange: field.onChange,
818
+ label: field.value ? 'Enabled' : 'Disabled',
819
+ disabled: 'tags' === filterType || 'and' === filterType
820
+ })
821
+ }),
822
+ ('tags' === filterType || 'and' === filterType) && /*#__PURE__*/ jsx(Text, {
823
+ color: "textSecondary",
824
+ children: "Delete marker replication is not supported for tag-based filters"
825
+ })
826
+ ]
827
+ })
828
+ })
829
+ ]
830
+ })
831
+ ]
832
+ })
833
+ });
834
+ }
835
+ export { BucketReplicationFormPage };