@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,1086 @@
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 { useGetBucketLifecycle, useSetBucketLifecycle } from "../../hooks/bucketConfiguration.js";
11
+ import { useDataBrowserNavigate } from "../../hooks/useDataBrowserNavigate.js";
12
+ import { AWS_RULE_LIMITS, STATUS_OPTIONS, buildS3Filter } from "../../utils/s3RuleUtils.js";
13
+ import { ArrayFieldActions } from "../ui/ArrayFieldActions.js";
14
+ import { FilterFormSection, createFilterValidationSchema } from "../ui/FilterFormSection.js";
15
+ const storageClassOptions = [
16
+ {
17
+ value: 'GLACIER',
18
+ label: 'Glacier'
19
+ },
20
+ {
21
+ value: 'DEEP_ARCHIVE',
22
+ label: 'Glacier Deep Archive'
23
+ },
24
+ {
25
+ value: 'STANDARD_IA',
26
+ label: 'Standard-IA'
27
+ },
28
+ {
29
+ value: 'ONEZONE_IA',
30
+ label: 'One Zone-IA'
31
+ },
32
+ {
33
+ value: 'INTELLIGENT_TIERING',
34
+ label: 'Intelligent-Tiering'
35
+ },
36
+ {
37
+ value: 'GLACIER_IR',
38
+ label: 'Glacier Instant Retrieval'
39
+ }
40
+ ];
41
+ const STORAGE_CLASS_MIN_DAYS = {
42
+ GLACIER_IR: 0,
43
+ STANDARD_IA: 30,
44
+ ONEZONE_IA: 30,
45
+ INTELLIGENT_TIERING: 30,
46
+ GLACIER: 90,
47
+ DEEP_ARCHIVE: 180
48
+ };
49
+ const LIFECYCLE_LIMITS = {
50
+ NONCURRENT_TRANSITION_MIN_DAYS: 30,
51
+ ABORT_MPU_MIN_DAYS: 1
52
+ };
53
+ const schema = joi.object({
54
+ ruleId: joi.string().required().max(AWS_RULE_LIMITS.RULE_ID_MAX_LENGTH).messages({
55
+ 'string.empty': 'Rule ID is required',
56
+ 'string.max': `Rule ID must not exceed ${AWS_RULE_LIMITS.RULE_ID_MAX_LENGTH} characters`
57
+ }),
58
+ status: joi.string().valid(...STATUS_OPTIONS.map((o)=>o.value)).required(),
59
+ ...createFilterValidationSchema(joi),
60
+ transitionsEnabled: joi.boolean(),
61
+ transitions: joi.when('transitionsEnabled', {
62
+ is: true,
63
+ then: joi.array().items(joi.object({
64
+ timeType: joi.string().valid('days', 'date').required(),
65
+ days: joi.when('timeType', {
66
+ is: 'days',
67
+ then: joi.number().integer().min(0).required().messages({
68
+ 'number.base': 'Days must be a number',
69
+ 'number.min': 'Days must be at least 0'
70
+ }),
71
+ otherwise: joi.any()
72
+ }),
73
+ date: joi.when('timeType', {
74
+ is: 'date',
75
+ then: joi.string().required().messages({
76
+ 'string.empty': 'Date is required'
77
+ }),
78
+ otherwise: joi.any()
79
+ }),
80
+ storageClass: joi.string().valid(...storageClassOptions.map((o)=>o.value)).required().messages({
81
+ 'string.empty': 'Storage class is required'
82
+ })
83
+ }).custom((value, helpers)=>{
84
+ if ('days' === value.timeType && value.storageClass && value.days < STORAGE_CLASS_MIN_DAYS[value.storageClass]) return helpers.error('any.custom', {
85
+ message: `${value.storageClass} requires at least ${STORAGE_CLASS_MIN_DAYS[value.storageClass]} days`
86
+ });
87
+ return value;
88
+ })).min(1).messages({
89
+ 'array.min': 'At least one transition is required when enabled'
90
+ }),
91
+ otherwise: joi.any()
92
+ }),
93
+ expirationEnabled: joi.boolean(),
94
+ expirationType: joi.when('expirationEnabled', {
95
+ is: true,
96
+ then: joi.string().valid('days', 'date').required(),
97
+ otherwise: joi.any()
98
+ }),
99
+ expirationDays: joi.when('expirationType', {
100
+ is: 'days',
101
+ then: joi.number().integer().min(1).required().messages({
102
+ 'number.base': 'Days must be a number',
103
+ 'number.min': 'Days must be at least 1'
104
+ }),
105
+ otherwise: joi.any()
106
+ }),
107
+ expirationDate: joi.when('expirationType', {
108
+ is: 'date',
109
+ then: joi.string().required().messages({
110
+ 'string.empty': 'Date is required'
111
+ }),
112
+ otherwise: joi.any()
113
+ }),
114
+ expiredObjectDeleteMarker: joi.boolean(),
115
+ noncurrentTransitionsEnabled: joi.boolean(),
116
+ noncurrentTransitions: joi.when('noncurrentTransitionsEnabled', {
117
+ is: true,
118
+ then: joi.array().items(joi.object({
119
+ noncurrentDays: joi.number().integer().min(LIFECYCLE_LIMITS.NONCURRENT_TRANSITION_MIN_DAYS).required().messages({
120
+ 'number.base': 'Noncurrent days must be a number',
121
+ 'number.min': `Noncurrent days must be at least ${LIFECYCLE_LIMITS.NONCURRENT_TRANSITION_MIN_DAYS}`
122
+ }),
123
+ storageClass: joi.string().valid(...storageClassOptions.map((o)=>o.value)).required().messages({
124
+ 'string.empty': 'Storage class is required'
125
+ }),
126
+ newerNoncurrentVersions: joi.number().integer().min(0).optional().allow(null, '')
127
+ })).min(1).messages({
128
+ 'array.min': 'At least one noncurrent transition is required when enabled'
129
+ }),
130
+ otherwise: joi.any()
131
+ }),
132
+ noncurrentExpirationEnabled: joi.boolean(),
133
+ noncurrentExpirationDays: joi.when('noncurrentExpirationEnabled', {
134
+ is: true,
135
+ then: joi.number().integer().min(1).required().messages({
136
+ 'number.base': 'Noncurrent days must be a number',
137
+ 'number.min': 'Noncurrent days must be at least 1'
138
+ }),
139
+ otherwise: joi.any()
140
+ }),
141
+ noncurrentNewerVersions: joi.number().integer().min(0).optional().allow(null, ''),
142
+ abortMpuEnabled: joi.boolean(),
143
+ abortMpuDays: joi.when('abortMpuEnabled', {
144
+ is: true,
145
+ then: joi.number().integer().min(LIFECYCLE_LIMITS.ABORT_MPU_MIN_DAYS).required().messages({
146
+ 'number.base': 'Days must be a number',
147
+ 'number.min': `Days must be at least ${LIFECYCLE_LIMITS.ABORT_MPU_MIN_DAYS}`
148
+ }),
149
+ otherwise: joi.any()
150
+ })
151
+ }).custom((value, helpers)=>{
152
+ const hasAtLeastOneAction = value.transitionsEnabled || value.expirationEnabled || value.expiredObjectDeleteMarker || value.noncurrentTransitionsEnabled || value.noncurrentExpirationEnabled || value.abortMpuEnabled;
153
+ if (!hasAtLeastOneAction) return helpers.error('any.custom', {
154
+ message: 'At least one lifecycle action must be enabled (transition, expiration, or abort multipart upload)'
155
+ });
156
+ if (value.expirationEnabled && value.expiredObjectDeleteMarker) return helpers.error('any.custom', {
157
+ message: 'Expired delete markers removal cannot be combined with Days/Date expiration on the same rule'
158
+ });
159
+ if (('tags' === value.filterType || 'and' === value.filterType) && value.abortMpuEnabled) return helpers.error('any.custom', {
160
+ message: 'Tag-based filter cannot be used with Abort Incomplete Multipart Upload'
161
+ });
162
+ return value;
163
+ });
164
+ const getArrayFieldError = (errors, fieldName, index, propertyName)=>{
165
+ const fieldErrors = errors?.[fieldName];
166
+ if (!fieldErrors?.[index]) return;
167
+ if (propertyName) return fieldErrors[index]?.[propertyName]?.message;
168
+ return fieldErrors[index]?.message;
169
+ };
170
+ const ruleToFormValues = (rule)=>{
171
+ const formValues = {
172
+ ruleId: rule.ID || '',
173
+ status: rule.Status || 'Enabled',
174
+ filterType: 'none',
175
+ prefix: '',
176
+ tags: [],
177
+ transitionsEnabled: false,
178
+ transitions: [],
179
+ expirationEnabled: false,
180
+ expirationType: 'days',
181
+ expirationDays: 30,
182
+ expirationDate: '',
183
+ expiredObjectDeleteMarker: false,
184
+ noncurrentTransitionsEnabled: false,
185
+ noncurrentTransitions: [],
186
+ noncurrentExpirationEnabled: false,
187
+ noncurrentExpirationDays: 30,
188
+ noncurrentNewerVersions: 0,
189
+ abortMpuEnabled: false,
190
+ abortMpuDays: 7
191
+ };
192
+ if (void 0 !== rule.Prefix && '' !== rule.Prefix) {
193
+ formValues.filterType = 'prefix';
194
+ formValues.prefix = rule.Prefix;
195
+ } else if (rule.Filter) {
196
+ if (rule.Filter.And) {
197
+ formValues.filterType = 'and';
198
+ formValues.prefix = rule.Filter.And.Prefix || '';
199
+ formValues.tags = rule.Filter.And.Tags?.map((tag)=>({
200
+ key: tag.Key || '',
201
+ value: tag.Value || ''
202
+ })) || [];
203
+ } else if (void 0 !== rule.Filter.Prefix) {
204
+ formValues.filterType = 'prefix';
205
+ formValues.prefix = rule.Filter.Prefix;
206
+ } else if (rule.Filter.Tag) {
207
+ formValues.filterType = 'tags';
208
+ formValues.tags = [
209
+ {
210
+ key: rule.Filter.Tag.Key || '',
211
+ value: rule.Filter.Tag.Value || ''
212
+ }
213
+ ];
214
+ }
215
+ }
216
+ if (rule.Transitions && rule.Transitions.length > 0) {
217
+ formValues.transitionsEnabled = true;
218
+ formValues.transitions = rule.Transitions.map((t)=>({
219
+ timeType: void 0 !== t.Days ? 'days' : 'date',
220
+ days: t.Days || 30,
221
+ date: t.Date ? new Date(t.Date).toISOString().split('T')[0] : '',
222
+ storageClass: t.StorageClass || 'GLACIER'
223
+ }));
224
+ }
225
+ if (rule.Expiration) {
226
+ if (rule.Expiration.Days) {
227
+ formValues.expirationEnabled = true;
228
+ formValues.expirationType = 'days';
229
+ formValues.expirationDays = rule.Expiration.Days;
230
+ } else if (rule.Expiration.Date) {
231
+ formValues.expirationEnabled = true;
232
+ formValues.expirationType = 'date';
233
+ formValues.expirationDate = new Date(rule.Expiration.Date).toISOString().split('T')[0];
234
+ }
235
+ if (rule.Expiration.ExpiredObjectDeleteMarker) formValues.expiredObjectDeleteMarker = true;
236
+ }
237
+ if (rule.NoncurrentVersionTransitions && rule.NoncurrentVersionTransitions.length > 0) {
238
+ formValues.noncurrentTransitionsEnabled = true;
239
+ formValues.noncurrentTransitions = rule.NoncurrentVersionTransitions.map((t)=>({
240
+ noncurrentDays: t.NoncurrentDays || 30,
241
+ storageClass: t.StorageClass || 'GLACIER',
242
+ newerNoncurrentVersions: t.NewerNoncurrentVersions || 0
243
+ }));
244
+ }
245
+ if (rule.NoncurrentVersionExpiration) {
246
+ formValues.noncurrentExpirationEnabled = true;
247
+ formValues.noncurrentExpirationDays = rule.NoncurrentVersionExpiration.NoncurrentDays || 30;
248
+ formValues.noncurrentNewerVersions = rule.NoncurrentVersionExpiration.NewerNoncurrentVersions || 0;
249
+ }
250
+ if (rule.AbortIncompleteMultipartUpload) {
251
+ formValues.abortMpuEnabled = true;
252
+ formValues.abortMpuDays = rule.AbortIncompleteMultipartUpload.DaysAfterInitiation || 7;
253
+ }
254
+ return formValues;
255
+ };
256
+ const generateStorageClassHelpText = ()=>{
257
+ const hints = [];
258
+ storageClassOptions.forEach((option)=>{
259
+ const minDays = STORAGE_CLASS_MIN_DAYS[option.value];
260
+ if (minDays > 0) hints.push(`<li>${option.label}: min ${minDays} days</li>`);
261
+ });
262
+ return hints.length > 0 ? `Storage class requirements:<ul>${hints.join('')}</ul>` : void 0;
263
+ };
264
+ function BucketLifecycleFormPage() {
265
+ const { bucketName, ruleId } = useParams();
266
+ const navigate = useDataBrowserNavigate();
267
+ const { showToast } = useToast();
268
+ const isEditMode = !!ruleId;
269
+ const { data: lifecycleData, status: lifecycleStatus } = useGetBucketLifecycle({
270
+ Bucket: bucketName
271
+ });
272
+ const existingRule = useMemo(()=>{
273
+ if (!isEditMode || !lifecycleData?.Rules || !ruleId) return null;
274
+ return lifecycleData.Rules.find((rule)=>rule.ID === decodeURIComponent(ruleId)) || null;
275
+ }, [
276
+ isEditMode,
277
+ lifecycleData,
278
+ ruleId
279
+ ]);
280
+ const existingRuleIds = useMemo(()=>(lifecycleData?.Rules || []).map((rule)=>rule.ID).filter(Boolean).filter((id)=>!isEditMode || id !== existingRule?.ID), [
281
+ lifecycleData,
282
+ isEditMode,
283
+ existingRule
284
+ ]);
285
+ const dynamicSchema = useMemo(()=>schema.keys({
286
+ ruleId: joi.string().required().invalid(...existingRuleIds).messages({
287
+ 'string.empty': 'Rule ID is required',
288
+ 'any.invalid': 'A rule with this ID already exists'
289
+ })
290
+ }), [
291
+ existingRuleIds
292
+ ]);
293
+ const methods = useForm({
294
+ resolver: joiResolver(dynamicSchema),
295
+ mode: 'onChange',
296
+ defaultValues: {
297
+ ruleId: '',
298
+ status: 'Enabled',
299
+ filterType: 'none',
300
+ prefix: '',
301
+ tags: [],
302
+ transitionsEnabled: false,
303
+ transitions: [],
304
+ expirationEnabled: false,
305
+ expirationType: 'days',
306
+ expirationDays: 30,
307
+ expirationDate: '',
308
+ expiredObjectDeleteMarker: false,
309
+ noncurrentTransitionsEnabled: false,
310
+ noncurrentTransitions: [],
311
+ noncurrentExpirationEnabled: false,
312
+ noncurrentExpirationDays: 30,
313
+ noncurrentNewerVersions: 0,
314
+ abortMpuEnabled: false,
315
+ abortMpuDays: 7
316
+ }
317
+ });
318
+ const { handleSubmit, register, control, watch, reset, formState: { isValid, isDirty, errors } } = methods;
319
+ const { fields: transitionFields, append: appendTransition, remove: removeTransition } = useFieldArray({
320
+ control,
321
+ name: 'transitions'
322
+ });
323
+ const { fields: noncurrentTransitionFields, append: appendNoncurrentTransition, remove: removeNoncurrentTransition } = useFieldArray({
324
+ control,
325
+ name: 'noncurrentTransitions'
326
+ });
327
+ const { fields: tagFields, append: appendTag, remove: removeTag } = useFieldArray({
328
+ control,
329
+ name: 'tags'
330
+ });
331
+ const filterType = watch('filterType');
332
+ const transitionsEnabled = watch('transitionsEnabled');
333
+ const expirationEnabled = watch('expirationEnabled');
334
+ const expirationType = watch('expirationType');
335
+ const expiredObjectDeleteMarker = watch('expiredObjectDeleteMarker');
336
+ const noncurrentTransitionsEnabled = watch('noncurrentTransitionsEnabled');
337
+ const noncurrentExpirationEnabled = watch('noncurrentExpirationEnabled');
338
+ const abortMpuEnabled = watch('abortMpuEnabled');
339
+ const { mutate: setLifecycle, isPending: isSaving } = useSetBucketLifecycle();
340
+ const transitionsHelpText = useMemo(()=>{
341
+ if (!transitionsEnabled || 0 === transitionFields.length) return;
342
+ return generateStorageClassHelpText();
343
+ }, [
344
+ transitionsEnabled,
345
+ transitionFields.length
346
+ ]);
347
+ const noncurrentTransitionsHelpText = useMemo(()=>{
348
+ if (!noncurrentTransitionsEnabled || 0 === noncurrentTransitionFields.length) return;
349
+ return generateStorageClassHelpText();
350
+ }, [
351
+ noncurrentTransitionsEnabled,
352
+ noncurrentTransitionFields.length
353
+ ]);
354
+ useEffect(()=>{
355
+ if (isEditMode && existingRule) {
356
+ const formValues = ruleToFormValues(existingRule);
357
+ reset(formValues);
358
+ }
359
+ }, [
360
+ isEditMode,
361
+ existingRule,
362
+ reset
363
+ ]);
364
+ const prevTransitionsEnabledRef = useRef(null);
365
+ const prevNoncurrentTransitionsEnabledRef = useRef(null);
366
+ useEffect(()=>{
367
+ const prevValue = prevTransitionsEnabledRef.current;
368
+ prevTransitionsEnabledRef.current = transitionsEnabled;
369
+ if (!isEditMode && null !== prevValue && !prevValue && transitionsEnabled && 0 === transitionFields.length) appendTransition({
370
+ timeType: 'days',
371
+ days: 30,
372
+ date: '',
373
+ storageClass: 'STANDARD_IA'
374
+ });
375
+ }, [
376
+ isEditMode,
377
+ transitionsEnabled,
378
+ transitionFields.length,
379
+ appendTransition
380
+ ]);
381
+ useEffect(()=>{
382
+ const prevValue = prevNoncurrentTransitionsEnabledRef.current;
383
+ prevNoncurrentTransitionsEnabledRef.current = noncurrentTransitionsEnabled;
384
+ if (!isEditMode && null !== prevValue && !prevValue && noncurrentTransitionsEnabled && 0 === noncurrentTransitionFields.length) appendNoncurrentTransition({
385
+ noncurrentDays: 30,
386
+ storageClass: 'GLACIER',
387
+ newerNoncurrentVersions: 0
388
+ });
389
+ }, [
390
+ isEditMode,
391
+ noncurrentTransitionsEnabled,
392
+ noncurrentTransitionFields.length,
393
+ appendNoncurrentTransition
394
+ ]);
395
+ const prevFilterTypeRef = useRef();
396
+ useEffect(()=>{
397
+ const prevFilterType = prevFilterTypeRef.current;
398
+ prevFilterTypeRef.current = filterType;
399
+ if (('tags' === filterType || 'and' === filterType) && 0 === tagFields.length) {
400
+ if (!isEditMode || void 0 !== prevFilterType && prevFilterType !== filterType) appendTag({
401
+ key: '',
402
+ value: ''
403
+ });
404
+ }
405
+ if (void 0 !== prevFilterType && prevFilterType !== filterType) {
406
+ if (('none' === filterType || 'prefix' === filterType) && tagFields.length > 0) tagFields.forEach((_, index)=>{
407
+ removeTag(tagFields.length - 1 - index);
408
+ });
409
+ if ('none' === filterType) methods.setValue('prefix', '', {
410
+ shouldDirty: true
411
+ });
412
+ }
413
+ }, [
414
+ isEditMode,
415
+ filterType,
416
+ tagFields,
417
+ appendTag,
418
+ removeTag,
419
+ methods
420
+ ]);
421
+ const handleCancel = useCallback(()=>{
422
+ navigate(`/buckets/${bucketName}?tab=lifecycle`);
423
+ }, [
424
+ navigate,
425
+ bucketName
426
+ ]);
427
+ const onSubmit = useCallback((data)=>{
428
+ if (!bucketName) return;
429
+ const rule = {
430
+ ID: data.ruleId,
431
+ Status: data.status
432
+ };
433
+ rule.Filter = buildS3Filter(data);
434
+ if (data.transitionsEnabled && data.transitions.length > 0) rule.Transitions = data.transitions.map((transition)=>{
435
+ const t = {
436
+ StorageClass: transition.storageClass
437
+ };
438
+ if ('days' === transition.timeType) t.Days = transition.days;
439
+ else t.Date = new Date(transition.date);
440
+ return t;
441
+ });
442
+ if (data.expirationEnabled || data.expiredObjectDeleteMarker) {
443
+ rule.Expiration = {};
444
+ if (data.expirationEnabled) {
445
+ if ('days' === data.expirationType) rule.Expiration.Days = data.expirationDays;
446
+ else if ('date' === data.expirationType) rule.Expiration.Date = new Date(data.expirationDate);
447
+ }
448
+ if (data.expiredObjectDeleteMarker) rule.Expiration.ExpiredObjectDeleteMarker = true;
449
+ }
450
+ if (data.noncurrentTransitionsEnabled && data.noncurrentTransitions.length > 0) rule.NoncurrentVersionTransitions = data.noncurrentTransitions.map((transition)=>({
451
+ NoncurrentDays: transition.noncurrentDays,
452
+ StorageClass: transition.storageClass,
453
+ ...transition.newerNoncurrentVersions && transition.newerNoncurrentVersions > 0 && {
454
+ NewerNoncurrentVersions: transition.newerNoncurrentVersions
455
+ }
456
+ }));
457
+ if (data.noncurrentExpirationEnabled) rule.NoncurrentVersionExpiration = {
458
+ NoncurrentDays: data.noncurrentExpirationDays,
459
+ ...data.noncurrentNewerVersions && data.noncurrentNewerVersions > 0 && {
460
+ NewerNoncurrentVersions: data.noncurrentNewerVersions
461
+ }
462
+ };
463
+ if (data.abortMpuEnabled) rule.AbortIncompleteMultipartUpload = {
464
+ DaysAfterInitiation: data.abortMpuDays
465
+ };
466
+ const existingRules = lifecycleData?.Rules || [];
467
+ const updatedRules = isEditMode ? existingRules.map((r)=>r.ID === existingRule?.ID ? rule : r) : [
468
+ ...existingRules,
469
+ rule
470
+ ];
471
+ setLifecycle({
472
+ Bucket: bucketName,
473
+ LifecycleConfiguration: {
474
+ Rules: updatedRules
475
+ }
476
+ }, {
477
+ onSuccess: ()=>{
478
+ showToast({
479
+ open: true,
480
+ message: `Lifecycle rule ${isEditMode ? 'updated' : 'created'} successfully`,
481
+ status: 'success'
482
+ });
483
+ navigate(`/buckets/${bucketName}?tab=lifecycle`);
484
+ },
485
+ onError: (error)=>{
486
+ const errorMessage = error instanceof Error ? error.message : `Failed to ${isEditMode ? 'update' : 'create'} lifecycle rule`;
487
+ showToast({
488
+ open: true,
489
+ message: errorMessage,
490
+ status: 'error'
491
+ });
492
+ }
493
+ });
494
+ }, [
495
+ bucketName,
496
+ setLifecycle,
497
+ navigate,
498
+ showToast,
499
+ lifecycleData,
500
+ isEditMode,
501
+ existingRule
502
+ ]);
503
+ if ('pending' === lifecycleStatus) return /*#__PURE__*/ jsx(Loader, {
504
+ centered: true,
505
+ children: /*#__PURE__*/ jsx(Text, {
506
+ children: "Loading..."
507
+ })
508
+ });
509
+ if (isEditMode && !existingRule) return /*#__PURE__*/ jsx(Box, {
510
+ padding: spacing.r16,
511
+ children: /*#__PURE__*/ jsx(Text, {
512
+ color: "statusCritical",
513
+ children: "Rule not found"
514
+ })
515
+ });
516
+ return /*#__PURE__*/ jsx(FormProvider, {
517
+ ...methods,
518
+ children: /*#__PURE__*/ jsxs(Form, {
519
+ layout: {
520
+ kind: 'page',
521
+ title: isEditMode ? 'Edit Lifecycle Rule' : 'Create Lifecycle Rule'
522
+ },
523
+ requireMode: "partial",
524
+ onSubmit: handleSubmit(onSubmit),
525
+ rightActions: /*#__PURE__*/ jsxs(Stack, {
526
+ gap: "r16",
527
+ children: [
528
+ /*#__PURE__*/ jsx(Button, {
529
+ id: "cancel-btn",
530
+ variant: "outline",
531
+ type: "button",
532
+ label: "Cancel",
533
+ onClick: handleCancel,
534
+ disabled: isSaving
535
+ }),
536
+ /*#__PURE__*/ jsx(Button, {
537
+ id: isEditMode ? 'save-lifecycle-btn' : 'create-lifecycle-btn',
538
+ type: "submit",
539
+ variant: "primary",
540
+ label: isEditMode ? 'Save' : 'Create',
541
+ icon: isEditMode ? /*#__PURE__*/ jsx(Icon, {
542
+ name: "Save"
543
+ }) : void 0,
544
+ disabled: isEditMode ? !isDirty || !isValid || isSaving : !isValid || isSaving
545
+ })
546
+ ]
547
+ }),
548
+ children: [
549
+ /*#__PURE__*/ jsxs(FormSection, {
550
+ title: {
551
+ name: 'Rule Scope'
552
+ },
553
+ forceLabelWidth: convertRemToPixels(15),
554
+ children: [
555
+ /*#__PURE__*/ jsx(FormGroup, {
556
+ label: "Rule ID",
557
+ id: "ruleId",
558
+ direction: "horizontal",
559
+ error: errors?.ruleId?.message,
560
+ helpErrorPosition: "bottom",
561
+ required: true,
562
+ content: isEditMode ? /*#__PURE__*/ jsx(Text, {
563
+ children: watch('ruleId')
564
+ }) : /*#__PURE__*/ jsx(Input, {
565
+ id: "ruleId",
566
+ ...register('ruleId')
567
+ })
568
+ }),
569
+ /*#__PURE__*/ jsx(FormGroup, {
570
+ label: "Status",
571
+ id: "status",
572
+ direction: "horizontal",
573
+ error: errors?.status?.message,
574
+ helpErrorPosition: "bottom",
575
+ required: true,
576
+ content: /*#__PURE__*/ jsx(Controller, {
577
+ name: "status",
578
+ control: control,
579
+ render: ({ field })=>/*#__PURE__*/ jsx(Select, {
580
+ id: "status",
581
+ value: field.value,
582
+ onChange: field.onChange,
583
+ children: STATUS_OPTIONS.map((option)=>/*#__PURE__*/ jsx(Select.Option, {
584
+ value: option.value,
585
+ children: option.label
586
+ }, option.value))
587
+ })
588
+ })
589
+ })
590
+ ]
591
+ }),
592
+ /*#__PURE__*/ jsx(FilterFormSection, {
593
+ filterType: filterType,
594
+ onFilterTypeChange: (value)=>methods.setValue('filterType', value),
595
+ prefixRegister: register('prefix'),
596
+ tagFields: tagFields,
597
+ tagKeyRegister: (index)=>register(`tags.${index}.key`),
598
+ tagValueRegister: (index)=>register(`tags.${index}.value`),
599
+ getTagKeyValue: (index)=>watch(`tags.${index}.key`),
600
+ getTagValueValue: (index)=>watch(`tags.${index}.value`),
601
+ appendTag: appendTag,
602
+ removeTag: removeTag,
603
+ errors: errors
604
+ }),
605
+ /*#__PURE__*/ jsxs(FormSection, {
606
+ title: {
607
+ name: transitionsEnabled || expirationEnabled || noncurrentTransitionsEnabled || noncurrentExpirationEnabled || abortMpuEnabled ? 'Lifecycle Rule' : 'Lifecycle Rule (At least one action must be enabled)'
608
+ },
609
+ forceLabelWidth: convertRemToPixels(18),
610
+ children: [
611
+ /*#__PURE__*/ jsx(FormGroup, {
612
+ label: "Transition current version",
613
+ id: "transitionsEnabled",
614
+ direction: "horizontal",
615
+ labelHelpTooltip: transitionsHelpText,
616
+ content: /*#__PURE__*/ jsx(Controller, {
617
+ name: "transitionsEnabled",
618
+ control: control,
619
+ render: ({ field })=>/*#__PURE__*/ jsx(Toggle, {
620
+ toggle: field.value,
621
+ onChange: field.onChange,
622
+ label: field.value ? 'Enabled' : 'Disabled'
623
+ })
624
+ })
625
+ }),
626
+ transitionsEnabled ? /*#__PURE__*/ jsx(FormGroup, {
627
+ label: "",
628
+ id: "transitions",
629
+ direction: "vertical",
630
+ error: errors?.transitions?.message,
631
+ helpErrorPosition: "bottom",
632
+ content: /*#__PURE__*/ jsxs(Stack, {
633
+ direction: "vertical",
634
+ gap: "r16",
635
+ children: [
636
+ /*#__PURE__*/ jsxs(Stack, {
637
+ gap: "r40",
638
+ direction: "horizontal",
639
+ children: [
640
+ /*#__PURE__*/ jsx(Box, {
641
+ flex: "1/2",
642
+ children: /*#__PURE__*/ jsx(Text, {
643
+ color: "textSecondary",
644
+ children: "Time Type"
645
+ })
646
+ }),
647
+ /*#__PURE__*/ jsx(Box, {
648
+ flex: "1/2",
649
+ children: /*#__PURE__*/ jsx(Text, {
650
+ color: "textSecondary",
651
+ children: "Value"
652
+ })
653
+ }),
654
+ /*#__PURE__*/ jsx(Box, {
655
+ width: convertRemToPixels(4)
656
+ }),
657
+ /*#__PURE__*/ jsx(Box, {
658
+ flex: "1",
659
+ children: /*#__PURE__*/ jsx(Text, {
660
+ color: "textSecondary",
661
+ children: "Storage Class"
662
+ })
663
+ })
664
+ ]
665
+ }),
666
+ transitionFields.map((field, index)=>/*#__PURE__*/ jsxs(Stack, {
667
+ gap: "r20",
668
+ direction: "vertical",
669
+ children: [
670
+ /*#__PURE__*/ jsxs(Stack, {
671
+ gap: "r20",
672
+ children: [
673
+ /*#__PURE__*/ jsx(Box, {
674
+ flex: "1",
675
+ children: /*#__PURE__*/ jsx(Controller, {
676
+ name: `transitions.${index}.timeType`,
677
+ control: control,
678
+ render: ({ field })=>/*#__PURE__*/ jsxs(Select, {
679
+ id: `transition-time-type-${index}`,
680
+ value: field.value,
681
+ onChange: field.onChange,
682
+ size: "1/3",
683
+ children: [
684
+ /*#__PURE__*/ jsx(Select.Option, {
685
+ value: "days",
686
+ children: "Days"
687
+ }),
688
+ /*#__PURE__*/ jsx(Select.Option, {
689
+ value: "date",
690
+ children: "Date"
691
+ })
692
+ ]
693
+ })
694
+ })
695
+ }),
696
+ /*#__PURE__*/ jsx(Box, {
697
+ flex: "1",
698
+ children: 'days' === watch(`transitions.${index}.timeType`) ? /*#__PURE__*/ jsx(Input, {
699
+ id: `transition-days-${index}`,
700
+ type: "number",
701
+ placeholder: "Days",
702
+ size: "1/2",
703
+ ...register(`transitions.${index}.days`, {
704
+ valueAsNumber: true
705
+ })
706
+ }) : /*#__PURE__*/ jsx(Input, {
707
+ id: `transition-date-${index}`,
708
+ type: "date",
709
+ size: "1/2",
710
+ ...register(`transitions.${index}.date`)
711
+ })
712
+ }),
713
+ /*#__PURE__*/ jsx(Box, {
714
+ flex: "1",
715
+ children: /*#__PURE__*/ jsx(Controller, {
716
+ name: `transitions.${index}.storageClass`,
717
+ control: control,
718
+ render: ({ field })=>/*#__PURE__*/ jsx(Select, {
719
+ id: `transition-storage-class-${index}`,
720
+ value: field.value,
721
+ onChange: field.onChange,
722
+ placeholder: "Storage Class",
723
+ size: "2/3",
724
+ children: storageClassOptions.map((option)=>/*#__PURE__*/ jsx(Select.Option, {
725
+ value: option.value,
726
+ children: option.label
727
+ }, option.value))
728
+ })
729
+ })
730
+ }),
731
+ /*#__PURE__*/ jsx(ArrayFieldActions, {
732
+ showAdd: index === transitionFields.length - 1,
733
+ onRemove: ()=>removeTransition(index),
734
+ onAdd: ()=>appendTransition({
735
+ timeType: 'days',
736
+ days: 30,
737
+ date: '',
738
+ storageClass: 'STANDARD_IA'
739
+ }),
740
+ canRemove: transitionFields.length > 1
741
+ })
742
+ ]
743
+ }),
744
+ getArrayFieldError(errors, 'transitions', index) && /*#__PURE__*/ jsx(Text, {
745
+ color: "statusCritical",
746
+ children: getArrayFieldError(errors, 'transitions', index)
747
+ }),
748
+ getArrayFieldError(errors, 'transitions', index, 'days') && /*#__PURE__*/ jsx(Text, {
749
+ color: "statusCritical",
750
+ children: getArrayFieldError(errors, 'transitions', index, 'days')
751
+ }),
752
+ getArrayFieldError(errors, 'transitions', index, 'storageClass') && /*#__PURE__*/ jsx(Text, {
753
+ color: "statusCritical",
754
+ children: getArrayFieldError(errors, 'transitions', index, 'storageClass')
755
+ }),
756
+ getArrayFieldError(errors, 'transitions', index, 'date') && /*#__PURE__*/ jsx(Text, {
757
+ color: "statusCritical",
758
+ children: getArrayFieldError(errors, 'transitions', index, 'date')
759
+ })
760
+ ]
761
+ }, field.id))
762
+ ]
763
+ })
764
+ }) : /*#__PURE__*/ jsx(Fragment, {}),
765
+ /*#__PURE__*/ jsx(FormGroup, {
766
+ label: "Expiration current version",
767
+ id: "expirationEnabled",
768
+ direction: "horizontal",
769
+ labelHelpTooltip: "Expire objects after a specified time. Cannot be combined with expired delete markers removal.",
770
+ content: /*#__PURE__*/ jsx(Controller, {
771
+ name: "expirationEnabled",
772
+ control: control,
773
+ render: ({ field })=>/*#__PURE__*/ jsx(Toggle, {
774
+ toggle: field.value,
775
+ onChange: (value)=>{
776
+ field.onChange(value);
777
+ if (value && expiredObjectDeleteMarker) methods.setValue('expiredObjectDeleteMarker', false, {
778
+ shouldDirty: true
779
+ });
780
+ },
781
+ label: field.value ? 'Enabled' : 'Disabled',
782
+ disabled: expiredObjectDeleteMarker
783
+ })
784
+ })
785
+ }),
786
+ expirationEnabled ? /*#__PURE__*/ jsxs(Fragment, {
787
+ children: [
788
+ /*#__PURE__*/ jsx(FormGroup, {
789
+ label: "Expiration type",
790
+ id: "expirationType",
791
+ direction: "horizontal",
792
+ content: /*#__PURE__*/ jsx(Controller, {
793
+ name: "expirationType",
794
+ control: control,
795
+ render: ({ field })=>/*#__PURE__*/ jsxs(Select, {
796
+ id: "expirationType",
797
+ value: field.value,
798
+ onChange: field.onChange,
799
+ children: [
800
+ /*#__PURE__*/ jsx(Select.Option, {
801
+ value: "days",
802
+ children: "Days"
803
+ }),
804
+ /*#__PURE__*/ jsx(Select.Option, {
805
+ value: "date",
806
+ children: "Date"
807
+ })
808
+ ]
809
+ })
810
+ })
811
+ }),
812
+ 'days' === expirationType && /*#__PURE__*/ jsx(FormGroup, {
813
+ label: "Days",
814
+ id: "expirationDays",
815
+ direction: "horizontal",
816
+ error: errors?.expirationDays?.message,
817
+ helpErrorPosition: "bottom",
818
+ content: /*#__PURE__*/ jsx(Box, {
819
+ flex: "1",
820
+ children: /*#__PURE__*/ jsx(Input, {
821
+ type: "number",
822
+ id: "expirationDays",
823
+ ...register('expirationDays', {
824
+ valueAsNumber: true
825
+ })
826
+ })
827
+ })
828
+ }),
829
+ 'date' === expirationType && /*#__PURE__*/ jsx(FormGroup, {
830
+ label: "Date",
831
+ id: "expirationDate",
832
+ direction: "horizontal",
833
+ error: errors?.expirationDate?.message,
834
+ helpErrorPosition: "bottom",
835
+ content: /*#__PURE__*/ jsx(Input, {
836
+ type: "date",
837
+ id: "expirationDate",
838
+ ...register('expirationDate')
839
+ })
840
+ })
841
+ ]
842
+ }) : /*#__PURE__*/ jsx(Fragment, {}),
843
+ /*#__PURE__*/ jsx(FormGroup, {
844
+ label: "Remove expired delete markers",
845
+ id: "expiredObjectDeleteMarker",
846
+ direction: "horizontal",
847
+ labelHelpTooltip: "Automatically remove expired object delete markers in versioned buckets. Cannot be combined with Days/Date expiration.",
848
+ content: /*#__PURE__*/ jsx(Controller, {
849
+ name: "expiredObjectDeleteMarker",
850
+ control: control,
851
+ render: ({ field })=>/*#__PURE__*/ jsx(Toggle, {
852
+ toggle: field.value,
853
+ onChange: (value)=>{
854
+ field.onChange(value);
855
+ if (value && expirationEnabled) methods.setValue('expirationEnabled', false, {
856
+ shouldDirty: true
857
+ });
858
+ },
859
+ label: field.value ? 'Enabled' : 'Disabled',
860
+ disabled: expirationEnabled
861
+ })
862
+ })
863
+ }),
864
+ /*#__PURE__*/ jsx(FormGroup, {
865
+ label: "Transition noncurrent version",
866
+ id: "noncurrentTransitionsEnabled",
867
+ direction: "horizontal",
868
+ content: /*#__PURE__*/ jsx(Controller, {
869
+ name: "noncurrentTransitionsEnabled",
870
+ control: control,
871
+ render: ({ field })=>/*#__PURE__*/ jsx(Toggle, {
872
+ toggle: field.value,
873
+ onChange: field.onChange,
874
+ label: field.value ? 'Enabled' : 'Disabled'
875
+ })
876
+ })
877
+ }),
878
+ noncurrentTransitionsEnabled ? /*#__PURE__*/ jsx(FormGroup, {
879
+ label: "",
880
+ id: "noncurrentTransitions",
881
+ direction: "vertical",
882
+ error: errors?.noncurrentTransitions?.message,
883
+ helpErrorPosition: "bottom",
884
+ labelHelpTooltip: noncurrentTransitionsHelpText,
885
+ content: /*#__PURE__*/ jsxs(Stack, {
886
+ direction: "vertical",
887
+ gap: "r16",
888
+ children: [
889
+ /*#__PURE__*/ jsxs(Stack, {
890
+ gap: "r40",
891
+ direction: "horizontal",
892
+ children: [
893
+ /*#__PURE__*/ jsx(Box, {
894
+ flex: "1/2",
895
+ children: /*#__PURE__*/ jsx(Text, {
896
+ color: "textSecondary",
897
+ children: "Noncurrent Days"
898
+ })
899
+ }),
900
+ /*#__PURE__*/ jsx(Box, {
901
+ flex: "1/2",
902
+ children: /*#__PURE__*/ jsx(Text, {
903
+ color: "textSecondary",
904
+ children: "Keep Versions"
905
+ })
906
+ }),
907
+ /*#__PURE__*/ jsx(Box, {
908
+ flex: "1",
909
+ children: /*#__PURE__*/ jsx(Text, {
910
+ color: "textSecondary",
911
+ children: "Storage Class"
912
+ })
913
+ })
914
+ ]
915
+ }),
916
+ noncurrentTransitionFields.map((field, index)=>/*#__PURE__*/ jsxs(Stack, {
917
+ gap: "r16",
918
+ direction: "vertical",
919
+ children: [
920
+ /*#__PURE__*/ jsxs(Stack, {
921
+ gap: "r16",
922
+ children: [
923
+ /*#__PURE__*/ jsx(Box, {
924
+ flex: "1",
925
+ children: /*#__PURE__*/ jsx(Input, {
926
+ id: `noncurrent-transition-days-${index}`,
927
+ type: "number",
928
+ placeholder: "Noncurrent days",
929
+ size: "1/3",
930
+ ...register(`noncurrentTransitions.${index}.noncurrentDays`, {
931
+ valueAsNumber: true
932
+ })
933
+ })
934
+ }),
935
+ /*#__PURE__*/ jsx(Box, {
936
+ width: convertRemToPixels(2)
937
+ }),
938
+ /*#__PURE__*/ jsx(Box, {
939
+ flex: "1",
940
+ children: /*#__PURE__*/ jsx(Input, {
941
+ id: `noncurrent-transition-keep-versions-${index}`,
942
+ type: "number",
943
+ placeholder: "Keep versions",
944
+ size: "1/3",
945
+ ...register(`noncurrentTransitions.${index}.newerNoncurrentVersions`, {
946
+ valueAsNumber: true
947
+ })
948
+ })
949
+ }),
950
+ /*#__PURE__*/ jsx(Box, {
951
+ width: convertRemToPixels(0.5)
952
+ }),
953
+ /*#__PURE__*/ jsx(Box, {
954
+ flex: "1",
955
+ children: /*#__PURE__*/ jsx(Controller, {
956
+ name: `noncurrentTransitions.${index}.storageClass`,
957
+ control: control,
958
+ render: ({ field })=>/*#__PURE__*/ jsx(Select, {
959
+ id: `noncurrent-transition-storage-class-${index}`,
960
+ value: field.value,
961
+ onChange: field.onChange,
962
+ placeholder: "Storage Class",
963
+ size: "2/3",
964
+ children: storageClassOptions.map((option)=>/*#__PURE__*/ jsx(Select.Option, {
965
+ value: option.value,
966
+ children: option.label
967
+ }, option.value))
968
+ })
969
+ })
970
+ }),
971
+ /*#__PURE__*/ jsx(ArrayFieldActions, {
972
+ showAdd: index === noncurrentTransitionFields.length - 1,
973
+ onRemove: ()=>removeNoncurrentTransition(index),
974
+ onAdd: ()=>appendNoncurrentTransition({
975
+ noncurrentDays: 30,
976
+ storageClass: 'GLACIER',
977
+ newerNoncurrentVersions: 0
978
+ }),
979
+ canRemove: noncurrentTransitionFields.length > 1
980
+ })
981
+ ]
982
+ }),
983
+ getArrayFieldError(errors, 'noncurrentTransitions', index, 'noncurrentDays') && /*#__PURE__*/ jsx(Text, {
984
+ color: "statusCritical",
985
+ children: getArrayFieldError(errors, 'noncurrentTransitions', index, 'noncurrentDays')
986
+ }),
987
+ getArrayFieldError(errors, 'noncurrentTransitions', index, 'storageClass') && /*#__PURE__*/ jsx(Text, {
988
+ color: "statusCritical",
989
+ children: getArrayFieldError(errors, 'noncurrentTransitions', index, 'storageClass')
990
+ })
991
+ ]
992
+ }, field.id))
993
+ ]
994
+ })
995
+ }) : /*#__PURE__*/ jsx(Fragment, {}),
996
+ /*#__PURE__*/ jsx(FormGroup, {
997
+ label: "Expiration noncurrent version",
998
+ id: "noncurrentExpirationEnabled",
999
+ direction: "horizontal",
1000
+ content: /*#__PURE__*/ jsx(Controller, {
1001
+ name: "noncurrentExpirationEnabled",
1002
+ control: control,
1003
+ render: ({ field })=>/*#__PURE__*/ jsx(Toggle, {
1004
+ toggle: field.value,
1005
+ onChange: field.onChange,
1006
+ label: field.value ? 'Enabled' : 'Disabled'
1007
+ })
1008
+ })
1009
+ }),
1010
+ noncurrentExpirationEnabled ? /*#__PURE__*/ jsxs(Fragment, {
1011
+ children: [
1012
+ /*#__PURE__*/ jsx(FormGroup, {
1013
+ label: "Noncurrent days",
1014
+ id: "noncurrentExpirationDays",
1015
+ direction: "horizontal",
1016
+ error: errors?.noncurrentExpirationDays?.message,
1017
+ helpErrorPosition: "bottom",
1018
+ content: /*#__PURE__*/ jsx(Box, {
1019
+ flex: "1",
1020
+ children: /*#__PURE__*/ jsx(Input, {
1021
+ type: "number",
1022
+ id: "noncurrentExpirationDays",
1023
+ ...register('noncurrentExpirationDays', {
1024
+ valueAsNumber: true
1025
+ })
1026
+ })
1027
+ })
1028
+ }),
1029
+ /*#__PURE__*/ jsx(FormGroup, {
1030
+ label: "Keep newer versions",
1031
+ id: "noncurrentNewerVersions",
1032
+ direction: "horizontal",
1033
+ content: /*#__PURE__*/ jsx(Box, {
1034
+ flex: "1",
1035
+ children: /*#__PURE__*/ jsx(Input, {
1036
+ type: "number",
1037
+ id: "noncurrentNewerVersions",
1038
+ placeholder: "0",
1039
+ ...register('noncurrentNewerVersions', {
1040
+ valueAsNumber: true
1041
+ })
1042
+ })
1043
+ })
1044
+ })
1045
+ ]
1046
+ }) : /*#__PURE__*/ jsx(Fragment, {}),
1047
+ /*#__PURE__*/ jsx(FormGroup, {
1048
+ label: "Expire incomplete multipart upload",
1049
+ id: "abortMpuEnabled",
1050
+ direction: "horizontal",
1051
+ error: ('tags' === filterType || 'and' === filterType) && abortMpuEnabled ? 'Tag-based filter cannot be used with Abort Incomplete Multipart Upload' : void 0,
1052
+ helpErrorPosition: "bottom",
1053
+ content: /*#__PURE__*/ jsx(Controller, {
1054
+ name: "abortMpuEnabled",
1055
+ control: control,
1056
+ render: ({ field })=>/*#__PURE__*/ jsx(Toggle, {
1057
+ toggle: field.value,
1058
+ onChange: field.onChange,
1059
+ label: field.value ? 'Enabled' : 'Disabled'
1060
+ })
1061
+ })
1062
+ }),
1063
+ abortMpuEnabled ? /*#__PURE__*/ jsx(FormGroup, {
1064
+ label: "Days after initiation",
1065
+ id: "abortMpuDays",
1066
+ direction: "horizontal",
1067
+ error: errors?.abortMpuDays?.message,
1068
+ helpErrorPosition: "bottom",
1069
+ content: /*#__PURE__*/ jsx(Box, {
1070
+ flex: "1",
1071
+ children: /*#__PURE__*/ jsx(Input, {
1072
+ type: "number",
1073
+ id: "abortMpuDays",
1074
+ ...register('abortMpuDays', {
1075
+ valueAsNumber: true
1076
+ })
1077
+ })
1078
+ })
1079
+ }) : /*#__PURE__*/ jsx(Fragment, {})
1080
+ ]
1081
+ })
1082
+ ]
1083
+ })
1084
+ });
1085
+ }
1086
+ export { BucketLifecycleFormPage };