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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (285) hide show
  1. package/dist/components/DataBrowserUI.d.ts +12 -0
  2. package/dist/components/DataBrowserUI.js +99 -0
  3. package/dist/components/Editor.d.ts +1 -1
  4. package/dist/components/Editor.js +3 -3
  5. package/dist/components/__tests__/BucketAccessor.test.js +214 -0
  6. package/dist/components/__tests__/BucketCorsPage.test.d.ts +1 -0
  7. package/dist/components/__tests__/BucketCorsPage.test.js +263 -0
  8. package/dist/components/__tests__/BucketCreate.test.js +271 -105
  9. package/dist/components/__tests__/BucketDetails.test.d.ts +1 -0
  10. package/dist/components/__tests__/BucketDetails.test.js +421 -0
  11. package/dist/components/__tests__/BucketLifecycleFormPage.test.d.ts +13 -0
  12. package/dist/components/__tests__/BucketLifecycleFormPage.test.js +178 -178
  13. package/dist/components/__tests__/BucketLifecycleList.test.js +85 -85
  14. package/dist/components/__tests__/BucketList.test.js +463 -239
  15. package/dist/components/__tests__/BucketNotificationFormPage.test.d.ts +1 -0
  16. package/dist/components/__tests__/BucketNotificationFormPage.test.js +348 -0
  17. package/dist/components/__tests__/BucketNotificationList.test.d.ts +1 -0
  18. package/dist/components/__tests__/BucketNotificationList.test.js +379 -0
  19. package/dist/components/__tests__/BucketOverview.test.js +281 -266
  20. package/dist/components/__tests__/BucketPolicyPage.test.js +151 -99
  21. package/dist/components/__tests__/BucketReplicationFormPage.test.d.ts +15 -0
  22. package/dist/components/__tests__/BucketReplicationFormPage.test.js +544 -544
  23. package/dist/components/__tests__/BucketReplicationList.test.js +106 -106
  24. package/dist/components/__tests__/CreateFolderButton.test.js +56 -56
  25. package/dist/components/__tests__/DeleteBucketButton.test.js +64 -64
  26. package/dist/components/__tests__/DeleteBucketConfigRuleButton.test.js +47 -47
  27. package/dist/components/__tests__/DeleteObjectButton.test.js +64 -64
  28. package/dist/components/__tests__/EmptyBucketButton.test.js +59 -59
  29. package/dist/components/__tests__/MetadataSearch.test.js +65 -65
  30. package/dist/components/__tests__/ObjectList.test.js +741 -240
  31. package/dist/components/__tests__/UploadButton.test.js +45 -45
  32. package/dist/components/breadcrumb/Breadcrumb.d.ts +6 -0
  33. package/dist/components/breadcrumb/Breadcrumb.js +37 -0
  34. package/dist/components/breadcrumb/DataBrowserBreadcrumb.d.ts +1 -0
  35. package/dist/components/breadcrumb/DataBrowserBreadcrumb.js +10 -0
  36. package/dist/components/breadcrumb/__tests__/Breadcrumb.test.d.ts +1 -0
  37. package/dist/components/breadcrumb/__tests__/Breadcrumb.test.js +196 -0
  38. package/dist/components/breadcrumb/__tests__/DataBrowserBreadcrumb.test.d.ts +1 -0
  39. package/dist/components/breadcrumb/__tests__/DataBrowserBreadcrumb.test.js +153 -0
  40. package/dist/components/breadcrumb/__tests__/useBreadcrumbPaths.test.d.ts +1 -0
  41. package/dist/components/breadcrumb/__tests__/useBreadcrumbPaths.test.js +134 -0
  42. package/dist/components/breadcrumb/index.d.ts +8 -0
  43. package/dist/components/breadcrumb/index.js +4 -0
  44. package/dist/components/breadcrumb/useBreadcrumbPaths.d.ts +2 -0
  45. package/dist/components/breadcrumb/useBreadcrumbPaths.js +82 -0
  46. package/dist/components/buckets/BucketAccessor.d.ts +2 -0
  47. package/dist/components/buckets/BucketAccessor.js +125 -0
  48. package/dist/components/buckets/BucketConfigEditButton.d.ts +8 -0
  49. package/dist/components/buckets/{BucketPolicyButton.js → BucketConfigEditButton.js} +9 -5
  50. package/dist/components/buckets/BucketCorsPage.d.ts +1 -0
  51. package/dist/components/buckets/BucketCorsPage.js +234 -0
  52. package/dist/components/buckets/BucketCreate.d.ts +3 -2
  53. package/dist/components/buckets/BucketCreate.js +89 -47
  54. package/dist/components/buckets/BucketDetails.d.ts +42 -0
  55. package/dist/components/buckets/BucketDetails.js +249 -85
  56. package/dist/components/buckets/BucketLifecycleFormPage.js +206 -190
  57. package/dist/components/buckets/BucketLifecycleList.d.ts +2 -2
  58. package/dist/components/buckets/BucketLifecycleList.js +47 -47
  59. package/dist/components/buckets/BucketList.d.ts +7 -8
  60. package/dist/components/buckets/BucketList.js +158 -101
  61. package/dist/components/buckets/BucketLocation.js +4 -4
  62. package/dist/components/buckets/BucketOverview.d.ts +22 -2
  63. package/dist/components/buckets/BucketOverview.js +394 -187
  64. package/dist/components/buckets/BucketPage.js +43 -21
  65. package/dist/components/buckets/BucketPolicyPage.js +155 -127
  66. package/dist/components/buckets/BucketReplicationFormPage.js +134 -133
  67. package/dist/components/buckets/BucketReplicationList.d.ts +2 -2
  68. package/dist/components/buckets/BucketReplicationList.js +42 -42
  69. package/dist/components/buckets/BucketVersioning.d.ts +4 -0
  70. package/dist/components/buckets/BucketVersioning.js +76 -0
  71. package/dist/components/buckets/DeleteBucketButton.js +8 -8
  72. package/dist/components/buckets/DeleteBucketConfigRuleButton.d.ts +2 -2
  73. package/dist/components/buckets/DeleteBucketConfigRuleButton.js +2 -2
  74. package/dist/components/buckets/EmptyBucketButton.js +24 -24
  75. package/dist/components/buckets/EmptyBucketSummary.d.ts +2 -2
  76. package/dist/components/buckets/EmptyBucketSummary.js +1 -1
  77. package/dist/components/buckets/EmptyBucketSummaryList.d.ts +1 -1
  78. package/dist/components/buckets/EmptyBucketSummaryList.js +22 -22
  79. package/dist/components/buckets/__tests__/BucketVersioning.test.d.ts +1 -0
  80. package/dist/components/buckets/__tests__/BucketVersioning.test.js +163 -0
  81. package/dist/components/buckets/notifications/BucketNotificationFormPage.d.ts +1 -0
  82. package/dist/components/buckets/notifications/BucketNotificationFormPage.js +316 -0
  83. package/dist/components/buckets/notifications/BucketNotificationList.d.ts +10 -0
  84. package/dist/components/buckets/notifications/BucketNotificationList.js +267 -0
  85. package/dist/components/buckets/notifications/EventsSection.js +145 -29
  86. package/dist/components/buckets/notifications/__tests__/events.test.d.ts +1 -0
  87. package/dist/components/buckets/notifications/__tests__/events.test.js +56 -0
  88. package/dist/components/buckets/notifications/events.d.ts +71 -7
  89. package/dist/components/buckets/notifications/events.js +98 -16
  90. package/dist/components/index.d.ts +27 -20
  91. package/dist/components/index.js +17 -10
  92. package/dist/components/layouts/ArrowNavigation.d.ts +3 -0
  93. package/dist/components/layouts/ArrowNavigation.js +28 -0
  94. package/dist/components/layouts/BrowserPageLayout.d.ts +5 -1
  95. package/dist/components/layouts/BrowserPageLayout.js +10 -5
  96. package/dist/components/objects/CreateFolderButton.d.ts +2 -2
  97. package/dist/components/objects/CreateFolderButton.js +12 -12
  98. package/dist/components/objects/DeleteObjectButton.d.ts +1 -1
  99. package/dist/components/objects/DeleteObjectButton.js +19 -21
  100. package/dist/components/objects/GetPresignedUrlButton.d.ts +7 -0
  101. package/dist/components/objects/GetPresignedUrlButton.js +255 -0
  102. package/dist/components/objects/ObjectDetails/ObjectMetadata.d.ts +2 -2
  103. package/dist/components/objects/ObjectDetails/ObjectMetadata.js +263 -230
  104. package/dist/components/objects/ObjectDetails/ObjectSummary.d.ts +2 -2
  105. package/dist/components/objects/ObjectDetails/ObjectSummary.js +540 -138
  106. package/dist/components/objects/ObjectDetails/ObjectTags.d.ts +2 -2
  107. package/dist/components/objects/ObjectDetails/ObjectTags.js +95 -123
  108. package/dist/components/objects/ObjectDetails/__tests__/ObjectDetails.test.d.ts +1 -0
  109. package/dist/components/objects/ObjectDetails/__tests__/ObjectDetails.test.js +516 -0
  110. package/dist/components/objects/ObjectDetails/__tests__/ObjectSummary.test.d.ts +1 -0
  111. package/dist/components/objects/ObjectDetails/__tests__/ObjectSummary.test.js +1064 -0
  112. package/dist/components/objects/ObjectDetails/index.d.ts +18 -2
  113. package/dist/components/objects/ObjectDetails/index.js +152 -40
  114. package/dist/components/objects/ObjectList.d.ts +12 -10
  115. package/dist/components/objects/ObjectList.js +590 -263
  116. package/dist/components/objects/ObjectLock/EditRetentionButton.js +4 -4
  117. package/dist/components/objects/ObjectLock/ObjectLockRetentionSettings.js +15 -15
  118. package/dist/components/objects/ObjectLock/ObjectLockSettings.d.ts +1 -1
  119. package/dist/components/objects/ObjectLock/ObjectLockSettings.js +32 -31
  120. package/dist/components/objects/ObjectLock/ObjectLockSettingsUtils.d.ts +1 -1
  121. package/dist/components/objects/ObjectLock/ObjectLockSettingsUtils.js +6 -6
  122. package/dist/components/objects/ObjectLock/__tests__/EditRetentionButton.test.js +51 -51
  123. package/dist/components/objects/ObjectLock/__tests__/ObjectLockSettings.test.js +78 -78
  124. package/dist/components/objects/ObjectPage.js +12 -8
  125. package/dist/components/objects/UploadButton.d.ts +3 -3
  126. package/dist/components/objects/UploadButton.js +10 -10
  127. package/dist/components/objects/__tests__/GetPresignedUrlButton.test.d.ts +1 -0
  128. package/dist/components/objects/__tests__/GetPresignedUrlButton.test.js +531 -0
  129. package/dist/components/providers/DataBrowserProvider.d.ts +23 -12
  130. package/dist/components/providers/DataBrowserProvider.js +60 -38
  131. package/dist/components/providers/QueryProvider.d.ts +9 -0
  132. package/dist/components/providers/QueryProvider.js +21 -0
  133. package/dist/components/search/MetadataSearch.js +29 -28
  134. package/dist/components/search/SearchHints.js +1 -1
  135. package/dist/components/ui/ArrayFieldActions.js +12 -7
  136. package/dist/components/ui/ConfirmDeleteRuleModal.d.ts +2 -2
  137. package/dist/components/ui/ConfirmDeleteRuleModal.js +6 -1
  138. package/dist/components/ui/DeleteObjectModalContent.d.ts +1 -1
  139. package/dist/components/ui/DeleteObjectModalContent.js +12 -12
  140. package/dist/components/ui/FilterFormSection.d.ts +2 -2
  141. package/dist/components/ui/FilterFormSection.js +29 -29
  142. package/dist/components/ui/Search.elements.d.ts +2 -2
  143. package/dist/components/ui/Search.elements.js +7 -7
  144. package/dist/components/ui/Table.elements.d.ts +2 -1
  145. package/dist/components/ui/Table.elements.js +18 -12
  146. package/dist/config/__tests__/factory.test.d.ts +1 -0
  147. package/dist/config/__tests__/factory.test.js +311 -0
  148. package/dist/config/factory.d.ts +10 -56
  149. package/dist/config/factory.js +23 -71
  150. package/dist/config/types.d.ts +212 -34
  151. package/dist/contexts/DataBrowserUICustomizationContext.d.ts +27 -0
  152. package/dist/contexts/DataBrowserUICustomizationContext.js +13 -0
  153. package/dist/hooks/__tests__/useAccessibleBuckets.test.d.ts +1 -0
  154. package/dist/hooks/__tests__/useAccessibleBuckets.test.js +145 -0
  155. package/dist/hooks/__tests__/useISVBucketDetection.test.js +45 -45
  156. package/dist/hooks/__tests__/useIsBucketEmpty.test.js +27 -27
  157. package/dist/hooks/__tests__/useLoginMutation.test.d.ts +1 -0
  158. package/dist/hooks/__tests__/useLoginMutation.test.js +194 -0
  159. package/dist/hooks/bucketConfiguration.d.ts +8 -1
  160. package/dist/hooks/bucketConfiguration.js +52 -51
  161. package/dist/hooks/bucketOperations.d.ts +10 -1
  162. package/dist/hooks/bucketOperations.js +10 -9
  163. package/dist/hooks/factories/__tests__/useCreateS3FunctionMutationHook.test.js +80 -80
  164. package/dist/hooks/factories/__tests__/useCreateS3InfiniteQueryHook.test.js +80 -80
  165. package/dist/hooks/factories/__tests__/useCreateS3LoginHook.test.js +44 -44
  166. package/dist/hooks/factories/__tests__/useCreateS3MutationHook.test.js +63 -63
  167. package/dist/hooks/factories/__tests__/useCreateS3QueryHook.test.js +65 -65
  168. package/dist/hooks/factories/index.d.ts +4 -4
  169. package/dist/hooks/factories/index.js +2 -2
  170. package/dist/hooks/factories/useCreateS3InfiniteQueryHook.d.ts +2 -2
  171. package/dist/hooks/factories/useCreateS3InfiniteQueryHook.js +16 -13
  172. package/dist/hooks/factories/useCreateS3LoginHook.d.ts +2 -2
  173. package/dist/hooks/factories/useCreateS3LoginHook.js +1 -1
  174. package/dist/hooks/factories/useCreateS3MutationHook.d.ts +3 -3
  175. package/dist/hooks/factories/useCreateS3MutationHook.js +7 -2
  176. package/dist/hooks/factories/useCreateS3QueryHook.d.ts +2 -2
  177. package/dist/hooks/factories/useCreateS3QueryHook.js +11 -6
  178. package/dist/hooks/index.d.ts +19 -12
  179. package/dist/hooks/index.js +16 -9
  180. package/dist/hooks/loginOperations.d.ts +1 -1
  181. package/dist/hooks/loginOperations.js +1 -1
  182. package/dist/hooks/objectOperations.d.ts +2 -2
  183. package/dist/hooks/objectOperations.js +50 -49
  184. package/dist/hooks/presignedOperations.d.ts +4 -4
  185. package/dist/hooks/presignedOperations.js +5 -5
  186. package/dist/hooks/useAccessibleBuckets.d.ts +11 -0
  187. package/dist/hooks/useAccessibleBuckets.js +115 -0
  188. package/dist/hooks/useBatchObjectLegalHold.d.ts +11 -0
  189. package/dist/hooks/useBatchObjectLegalHold.js +48 -0
  190. package/dist/hooks/useBucketConfigEditor.d.ts +31 -0
  191. package/dist/hooks/useBucketConfigEditor.js +82 -0
  192. package/dist/hooks/useDataBrowserNavigate.d.ts +28 -0
  193. package/dist/hooks/useDataBrowserNavigate.js +24 -0
  194. package/dist/hooks/useDeleteBucketConfigRule.d.ts +2 -2
  195. package/dist/hooks/useDeleteBucketConfigRule.js +4 -4
  196. package/dist/hooks/useEmptyBucket.js +11 -11
  197. package/dist/hooks/useFeatures.d.ts +7 -0
  198. package/dist/hooks/useFeatures.js +8 -0
  199. package/dist/hooks/useISVBucketDetection.js +6 -6
  200. package/dist/hooks/useIsBucketEmpty.js +4 -4
  201. package/dist/hooks/useLimitedAccessFlow.d.ts +48 -0
  202. package/dist/hooks/useLimitedAccessFlow.js +23 -0
  203. package/dist/hooks/useS3Client.d.ts +6 -0
  204. package/dist/hooks/useS3Client.js +3 -2
  205. package/dist/hooks/useS3ConfigSwitch.d.ts +11 -0
  206. package/dist/hooks/useS3ConfigSwitch.js +37 -0
  207. package/dist/hooks/useSupportedNotificationEvents.d.ts +6 -0
  208. package/dist/hooks/useSupportedNotificationEvents.js +8 -0
  209. package/dist/index.d.ts +6 -6
  210. package/dist/index.js +2 -2
  211. package/dist/schemas/bucketPolicySchema.json +3 -13
  212. package/dist/test/msw/handlers/deleteBucket.d.ts +1 -1
  213. package/dist/test/msw/handlers/deleteBucket.js +20 -10
  214. package/dist/test/msw/handlers/getBucketAcl.d.ts +1 -1
  215. package/dist/test/msw/handlers/getBucketAcl.js +29 -17
  216. package/dist/test/msw/handlers/getBucketLocation.d.ts +1 -1
  217. package/dist/test/msw/handlers/getBucketLocation.js +29 -15
  218. package/dist/test/msw/handlers/getBucketPolicy.d.ts +1 -1
  219. package/dist/test/msw/handlers/getBucketPolicy.js +52 -32
  220. package/dist/test/msw/handlers/headObject.d.ts +1 -1
  221. package/dist/test/msw/handlers/headObject.js +31 -13
  222. package/dist/test/msw/handlers/listBuckets.d.ts +1 -1
  223. package/dist/test/msw/handlers/listBuckets.js +5 -3
  224. package/dist/test/msw/handlers/listObjectVersions.d.ts +1 -1
  225. package/dist/test/msw/handlers/listObjectVersions.js +38 -26
  226. package/dist/test/msw/handlers/listObjects.d.ts +1 -1
  227. package/dist/test/msw/handlers/listObjects.js +35 -23
  228. package/dist/test/msw/handlers/objectLegalHold.d.ts +1 -1
  229. package/dist/test/msw/handlers/objectLegalHold.js +32 -17
  230. package/dist/test/msw/handlers/objectRetention.d.ts +1 -1
  231. package/dist/test/msw/handlers/objectRetention.js +31 -17
  232. package/dist/test/msw/handlers/putBucketAcl.d.ts +1 -1
  233. package/dist/test/msw/handlers/putBucketAcl.js +29 -14
  234. package/dist/test/msw/handlers/putObject.d.ts +1 -1
  235. package/dist/test/msw/handlers/putObject.js +27 -12
  236. package/dist/test/msw/handlers.d.ts +3 -3
  237. package/dist/test/msw/handlers.js +77 -54
  238. package/dist/test/msw/index.d.ts +2 -2
  239. package/dist/test/msw/index.js +1 -1
  240. package/dist/test/msw/server.d.ts +1 -1
  241. package/dist/test/msw/server.js +1 -1
  242. package/dist/test/msw/utils.js +2 -2
  243. package/dist/test/setup.d.ts +1 -1
  244. package/dist/test/setup.js +13 -30
  245. package/dist/test/testUtils.d.ts +85 -33
  246. package/dist/test/testUtils.js +176 -111
  247. package/dist/test/utils/errorHandling.test.js +119 -119
  248. package/dist/types/index.d.ts +49 -36
  249. package/dist/types/monaco.d.ts +13 -0
  250. package/dist/types/monaco.js +0 -0
  251. package/dist/utils/__tests__/proxyMiddleware.test.d.ts +1 -0
  252. package/dist/utils/__tests__/proxyMiddleware.test.js +579 -0
  253. package/dist/utils/__tests__/s3Client.test.d.ts +1 -0
  254. package/dist/utils/__tests__/s3Client.test.js +340 -0
  255. package/dist/utils/__tests__/s3ConfigIdentifier.test.d.ts +1 -0
  256. package/dist/utils/__tests__/s3ConfigIdentifier.test.js +437 -0
  257. package/dist/utils/constants.d.ts +10 -0
  258. package/dist/utils/constants.js +19 -9
  259. package/dist/utils/deletion/index.d.ts +2 -2
  260. package/dist/utils/deletion/index.js +1 -1
  261. package/dist/utils/deletion/messages.d.ts +1 -1
  262. package/dist/utils/deletion/messages.js +4 -4
  263. package/dist/utils/errorHandling.d.ts +3 -3
  264. package/dist/utils/errorHandling.js +6 -6
  265. package/dist/utils/hooks.js +8 -8
  266. package/dist/utils/index.d.ts +5 -4
  267. package/dist/utils/index.js +4 -2
  268. package/dist/utils/proxyMiddleware.d.ts +32 -13
  269. package/dist/utils/proxyMiddleware.js +90 -36
  270. package/dist/utils/s3Client.d.ts +14 -4
  271. package/dist/utils/s3Client.js +5 -26
  272. package/dist/utils/s3ConfigIdentifier.d.ts +79 -0
  273. package/dist/utils/s3ConfigIdentifier.js +57 -0
  274. package/dist/utils/s3RuleUtils.d.ts +5 -5
  275. package/dist/utils/s3RuleUtils.js +17 -17
  276. package/package.json +10 -8
  277. package/dist/components/__tests__/BucketNotificationCreatePage.test.js +0 -316
  278. package/dist/components/buckets/BucketPolicyButton.d.ts +0 -7
  279. package/dist/components/buckets/notifications/BucketNotificationCreatePage.d.ts +0 -1
  280. package/dist/components/buckets/notifications/BucketNotificationCreatePage.js +0 -234
  281. package/dist/hooks/useLoginMutation.d.ts +0 -21
  282. package/dist/hooks/useLoginMutation.js +0 -9
  283. package/dist/utils/useFeatures.d.ts +0 -1
  284. package/dist/utils/useFeatures.js +0 -7
  285. /package/dist/components/__tests__/{BucketNotificationCreatePage.test.d.ts → BucketAccessor.test.d.ts} +0 -0
@@ -0,0 +1,267 @@
1
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
2
+ import { ConstrainedText, Icon, Stack, Tooltip, spacing, useToast } from "@scality/core-ui";
3
+ import { Box, Button, Table } from "@scality/core-ui/dist/next";
4
+ import { useMemo, useState } from "react";
5
+ import { useSetBucketNotification } from "../../../hooks/bucketConfiguration.js";
6
+ import { useTableRowSelection } from "../../../hooks/useTableRowSelection.js";
7
+ import { ConfirmDeleteRuleModal } from "../../ui/ConfirmDeleteRuleModal.js";
8
+ const MAX_VISIBLE_EVENTS = 3;
9
+ function BucketNotificationList({ bucketName, notificationRules, notificationStatus, onCreateRule, onEditRule }) {
10
+ const { showToast } = useToast();
11
+ const updateNotificationMutation = useSetBucketNotification();
12
+ const [deleteModalState, setDeleteModalState] = useState({
13
+ isOpen: false,
14
+ ruleId: ''
15
+ });
16
+ const handleDeleteConfirm = ()=>{
17
+ if (!deleteModalState.ruleId) {
18
+ showToast({
19
+ open: true,
20
+ message: 'Cannot delete rule: Invalid rule ID',
21
+ status: 'error'
22
+ });
23
+ setDeleteModalState({
24
+ isOpen: false,
25
+ ruleId: ''
26
+ });
27
+ return;
28
+ }
29
+ const remainingRules = notificationRules.filter((rule)=>rule.Id !== deleteModalState.ruleId);
30
+ updateNotificationMutation.mutate({
31
+ Bucket: bucketName,
32
+ NotificationConfiguration: {
33
+ QueueConfigurations: remainingRules
34
+ }
35
+ }, {
36
+ onSuccess: ()=>{
37
+ showToast({
38
+ open: true,
39
+ message: 'Notification rule deleted successfully',
40
+ status: 'success'
41
+ });
42
+ setDeleteModalState({
43
+ isOpen: false,
44
+ ruleId: ''
45
+ });
46
+ },
47
+ onError: (error)=>{
48
+ const errorMessage = error instanceof Error ? error.message : 'Failed to delete notification rule';
49
+ showToast({
50
+ open: true,
51
+ message: errorMessage,
52
+ status: 'error'
53
+ });
54
+ setDeleteModalState({
55
+ isOpen: false,
56
+ ruleId: ''
57
+ });
58
+ }
59
+ });
60
+ };
61
+ const columns = useMemo(()=>[
62
+ {
63
+ Header: 'Rule Name',
64
+ accessor: 'ID',
65
+ id: 'id',
66
+ Cell: ({ value })=>/*#__PURE__*/ jsx(ConstrainedText, {
67
+ text: value || '-',
68
+ lineClamp: 2
69
+ }),
70
+ cellStyle: {
71
+ flex: '1',
72
+ width: 'unset'
73
+ }
74
+ },
75
+ {
76
+ Header: 'Events',
77
+ accessor: 'Events',
78
+ id: 'events',
79
+ Cell: ({ value })=>{
80
+ if (!value || 0 === value.length) return /*#__PURE__*/ jsx("span", {
81
+ children: "-"
82
+ });
83
+ const visibleEvents = value.slice(0, MAX_VISIBLE_EVENTS);
84
+ const remainingCount = value.length - MAX_VISIBLE_EVENTS;
85
+ const allEventsTooltip = /*#__PURE__*/ jsx("ul", {
86
+ style: {
87
+ margin: 0,
88
+ paddingLeft: '1.5rem'
89
+ },
90
+ children: value.map((event)=>/*#__PURE__*/ jsx("li", {
91
+ children: event
92
+ }, event))
93
+ });
94
+ return /*#__PURE__*/ jsxs(Stack, {
95
+ direction: "horizontal",
96
+ gap: "r8",
97
+ children: [
98
+ /*#__PURE__*/ jsxs(Box, {
99
+ display: "flex",
100
+ flexDirection: "column",
101
+ gap: spacing.r4,
102
+ style: {
103
+ borderLeft: '2px solid currentColor',
104
+ paddingLeft: spacing.r8,
105
+ opacity: 0.8
106
+ },
107
+ children: [
108
+ visibleEvents.map((event)=>/*#__PURE__*/ jsx("span", {
109
+ children: event
110
+ }, event)),
111
+ remainingCount > 0 && /*#__PURE__*/ jsxs("span", {
112
+ style: {
113
+ fontStyle: 'italic'
114
+ },
115
+ children: [
116
+ "+",
117
+ remainingCount,
118
+ " more"
119
+ ]
120
+ })
121
+ ]
122
+ }),
123
+ remainingCount > 0 && /*#__PURE__*/ jsx(Tooltip, {
124
+ overlay: allEventsTooltip,
125
+ placement: "top",
126
+ overlayStyle: {
127
+ maxWidth: '30rem'
128
+ },
129
+ children: /*#__PURE__*/ jsx("span", {
130
+ style: {
131
+ cursor: 'help'
132
+ },
133
+ children: /*#__PURE__*/ jsx(Icon, {
134
+ name: "Info",
135
+ size: "sm"
136
+ })
137
+ })
138
+ })
139
+ ]
140
+ });
141
+ },
142
+ cellStyle: {
143
+ width: 'unset',
144
+ flex: '2',
145
+ alignItems: 'flex-start',
146
+ paddingTop: spacing.r8,
147
+ paddingBottom: spacing.r8
148
+ }
149
+ },
150
+ {
151
+ Header: '',
152
+ accessor: 'rule',
153
+ id: 'operations',
154
+ cellStyle: {
155
+ flex: '0.5',
156
+ textAlign: 'right',
157
+ paddingRight: spacing.r16,
158
+ width: 'unset'
159
+ },
160
+ Cell: ({ value })=>{
161
+ const hasValidId = !!value.Id;
162
+ return /*#__PURE__*/ jsxs(Box, {
163
+ display: "flex",
164
+ gap: spacing.r8,
165
+ justifyContent: "flex-end",
166
+ children: [
167
+ /*#__PURE__*/ jsx(Button, {
168
+ icon: /*#__PURE__*/ jsx(Icon, {
169
+ name: "Edit"
170
+ }),
171
+ variant: "secondary",
172
+ type: "button",
173
+ disabled: !hasValidId,
174
+ onClick: (e)=>{
175
+ e.stopPropagation();
176
+ if (hasValidId) onEditRule?.(value.Id);
177
+ },
178
+ "aria-label": "Edit rule",
179
+ tooltip: {
180
+ overlay: hasValidId ? 'Edit rule' : 'Cannot edit rule without ID'
181
+ }
182
+ }),
183
+ /*#__PURE__*/ jsx(Button, {
184
+ icon: /*#__PURE__*/ jsx(Icon, {
185
+ name: "Delete"
186
+ }),
187
+ variant: "danger",
188
+ type: "button",
189
+ disabled: !hasValidId,
190
+ onClick: (e)=>{
191
+ e.stopPropagation();
192
+ if (hasValidId) setDeleteModalState({
193
+ isOpen: true,
194
+ ruleId: value.Id
195
+ });
196
+ },
197
+ "aria-label": "Delete rule",
198
+ tooltip: {
199
+ overlay: hasValidId ? 'Delete rule' : 'Cannot delete rule without ID'
200
+ }
201
+ })
202
+ ]
203
+ });
204
+ }
205
+ }
206
+ ], [
207
+ onEditRule
208
+ ]);
209
+ const tableData = useMemo(()=>notificationRules.map((rule)=>({
210
+ ID: rule.Id || '-',
211
+ Events: rule.Events || [],
212
+ rule
213
+ })), [
214
+ notificationRules
215
+ ]);
216
+ const { selectedId, onRowSelected } = useTableRowSelection(tableData);
217
+ return /*#__PURE__*/ jsxs(Fragment, {
218
+ children: [
219
+ /*#__PURE__*/ jsxs(Table, {
220
+ columns: columns,
221
+ data: tableData,
222
+ status: notificationStatus,
223
+ defaultSortingKey: "id",
224
+ entityName: {
225
+ en: {
226
+ singular: 'notification rule',
227
+ plural: 'notification rules'
228
+ }
229
+ },
230
+ children: [
231
+ /*#__PURE__*/ jsx(Box, {
232
+ display: "flex",
233
+ justifyContent: "flex-end",
234
+ padding: spacing.r16,
235
+ children: /*#__PURE__*/ jsx(Button, {
236
+ icon: /*#__PURE__*/ jsx(Icon, {
237
+ name: "Create-add"
238
+ }),
239
+ label: "Add Notification",
240
+ variant: "primary",
241
+ onClick: onCreateRule,
242
+ type: "button"
243
+ })
244
+ }),
245
+ /*#__PURE__*/ jsx(Table.SingleSelectableContent, {
246
+ rowHeight: "h64",
247
+ separationLineVariant: "backgroundLevel1",
248
+ selectedId: selectedId?.toString(),
249
+ onRowSelected: onRowSelected
250
+ })
251
+ ]
252
+ }),
253
+ /*#__PURE__*/ jsx(ConfirmDeleteRuleModal, {
254
+ isOpen: deleteModalState.isOpen,
255
+ ruleId: deleteModalState.ruleId,
256
+ ruleType: "notification",
257
+ isDeleting: updateNotificationMutation.isPending,
258
+ onConfirm: handleDeleteConfirm,
259
+ onCancel: ()=>setDeleteModalState({
260
+ isOpen: false,
261
+ ruleId: ''
262
+ })
263
+ })
264
+ ]
265
+ });
266
+ }
267
+ export { BucketNotificationList };
@@ -1,39 +1,70 @@
1
1
  import { jsx, jsxs } from "react/jsx-runtime";
2
2
  import { Checkbox, FormGroup, FormSection, Stack, Text, Wrap } from "@scality/core-ui";
3
- import { useCallback } from "react";
4
- import { Controller, useFormContext } from "react-hook-form";
5
- import { objectCreationEvents, objectDeletionEvents, othersEvents } from "./events.js";
6
3
  import { Box } from "@scality/core-ui/dist/next";
4
+ import { useCallback, useMemo } from "react";
5
+ import { Controller, useFormContext } from "react-hook-form";
6
+ import { useSupportedNotificationEvents } from "../../../hooks/useSupportedNotificationEvents.js";
7
+ import { getFilteredEventGroups } from "./events.js";
7
8
  function EventsSection() {
8
9
  const { control, formState: { errors } } = useFormContext();
10
+ const supportedEvents = useSupportedNotificationEvents();
11
+ const eventGroups = useMemo(()=>getFilteredEventGroups(supportedEvents), [
12
+ supportedEvents
13
+ ]);
14
+ const { objectCreation, objectDeletion, objectRestoration, lifecycle, replication, objectTagging, storageAccess, testing } = eventGroups;
15
+ const getRelatedEvents = useCallback((eventValue)=>{
16
+ const basePattern = eventValue.slice(0, -1);
17
+ const eventGroupMap = {
18
+ 's3:ObjectCreated': objectCreation.events,
19
+ 's3:ObjectRemoved': objectDeletion.events,
20
+ 's3:ObjectRestore': objectRestoration.events,
21
+ 's3:Replication': replication.events,
22
+ 's3:ObjectTagging': objectTagging.events
23
+ };
24
+ for (const [prefix, events] of Object.entries(eventGroupMap))if (eventValue.startsWith(prefix)) return events;
25
+ if (eventValue.startsWith('s3:LifecycleExpiration')) return lifecycle.events.filter((e)=>e.startsWith(basePattern));
26
+ return [
27
+ eventValue
28
+ ];
29
+ }, [
30
+ objectCreation.events,
31
+ objectDeletion.events,
32
+ objectRestoration.events,
33
+ lifecycle.events,
34
+ replication.events,
35
+ objectTagging.events
36
+ ]);
9
37
  const toggleEvent = useCallback((currentEvents, eventValue, onChange)=>{
10
- const isWildcard = eventValue.endsWith("*");
38
+ const isWildcard = eventValue.endsWith('*');
11
39
  const isSelected = currentEvents.includes(eventValue);
12
- if (isWildcard) if (isSelected) {
13
- const relatedEvents = eventValue.startsWith("s3:ObjectCreated") ? objectCreationEvents.events : eventValue.startsWith("s3:ObjectRemoved") ? objectDeletionEvents.events : eventValue.startsWith("s3:LifecycleExpiration") ? othersEvents.events.filter((e)=>e.startsWith("s3:LifecycleExpiration")) : [
14
- eventValue
15
- ];
16
- onChange(currentEvents.filter((e)=>!relatedEvents.includes(e)));
17
- } else {
18
- const relatedEvents = eventValue.startsWith("s3:ObjectCreated") ? objectCreationEvents.events : eventValue.startsWith("s3:ObjectRemoved") ? objectDeletionEvents.events : eventValue.startsWith("s3:LifecycleExpiration") ? othersEvents.events.filter((e)=>e.startsWith("s3:LifecycleExpiration")) : [
40
+ if (!isWildcard) {
41
+ const newEvents = isSelected ? currentEvents.filter((e)=>e !== eventValue) : [
42
+ ...currentEvents,
19
43
  eventValue
20
44
  ];
45
+ onChange(newEvents);
46
+ return;
47
+ }
48
+ const relatedEvents = getRelatedEvents(eventValue);
49
+ if (isSelected) onChange(currentEvents.filter((e)=>!relatedEvents.includes(e)));
50
+ else {
21
51
  const newEvents = [
22
52
  ...currentEvents.filter((e)=>!relatedEvents.includes(e)),
23
53
  ...relatedEvents
24
54
  ];
25
55
  onChange(newEvents);
26
56
  }
27
- else onChange(isSelected ? currentEvents.filter((e)=>e !== eventValue) : [
28
- ...currentEvents,
29
- eventValue
30
- ]);
31
- }, []);
57
+ }, [
58
+ getRelatedEvents
59
+ ]);
32
60
  const isEventDisabled = (event, selectedEvents)=>{
33
- if (event.endsWith("*")) return false;
34
- if (event.startsWith("s3:ObjectCreated")) return selectedEvents.includes("s3:ObjectCreated:*");
35
- if (event.startsWith("s3:ObjectRemoved")) return selectedEvents.includes("s3:ObjectRemoved:*");
36
- if (event.startsWith("s3:LifecycleExpiration")) return selectedEvents.includes("s3:LifecycleExpiration:*");
61
+ if (event.endsWith('*')) return false;
62
+ if (event.startsWith('s3:ObjectCreated')) return selectedEvents.includes('s3:ObjectCreated:*');
63
+ if (event.startsWith('s3:ObjectRemoved')) return selectedEvents.includes('s3:ObjectRemoved:*');
64
+ if (event.startsWith('s3:ObjectRestore')) return selectedEvents.includes('s3:ObjectRestore:*');
65
+ if (event.startsWith('s3:LifecycleExpiration')) return selectedEvents.includes('s3:LifecycleExpiration:*');
66
+ if (event.startsWith('s3:Replication')) return selectedEvents.includes('s3:Replication:*');
67
+ else if (event.startsWith('s3:ObjectTagging')) return selectedEvents.includes('s3:ObjectTagging:*');
37
68
  return false;
38
69
  };
39
70
  return /*#__PURE__*/ jsxs(FormSection, {
@@ -62,15 +93,100 @@ function EventsSection() {
62
93
  direction: "vertical",
63
94
  gap: "r16",
64
95
  children: [
65
- /*#__PURE__*/ jsxs(Stack, {
96
+ objectCreation.events.length > 0 && /*#__PURE__*/ jsxs(Stack, {
97
+ direction: "vertical",
98
+ gap: "r8",
99
+ children: [
100
+ /*#__PURE__*/ jsx(Text, {
101
+ color: "textPrimary",
102
+ children: objectCreation.label
103
+ }),
104
+ objectCreation.events.map((event)=>/*#__PURE__*/ jsx(Checkbox, {
105
+ id: event,
106
+ label: event,
107
+ checked: value.includes(event),
108
+ disabled: isEventDisabled(event, value),
109
+ onChange: ()=>toggleEvent(value, event, onChange)
110
+ }, event))
111
+ ]
112
+ }),
113
+ objectDeletion.events.length > 0 && /*#__PURE__*/ jsxs(Stack, {
114
+ direction: "vertical",
115
+ gap: "r8",
116
+ children: [
117
+ /*#__PURE__*/ jsx(Text, {
118
+ color: "textPrimary",
119
+ children: objectDeletion.label
120
+ }),
121
+ objectDeletion.events.map((event)=>/*#__PURE__*/ jsx(Checkbox, {
122
+ id: event,
123
+ label: event,
124
+ checked: value.includes(event),
125
+ disabled: isEventDisabled(event, value),
126
+ onChange: ()=>toggleEvent(value, event, onChange)
127
+ }, event))
128
+ ]
129
+ }),
130
+ objectRestoration.events.length > 0 && /*#__PURE__*/ jsxs(Stack, {
131
+ direction: "vertical",
132
+ gap: "r8",
133
+ children: [
134
+ /*#__PURE__*/ jsx(Text, {
135
+ color: "textPrimary",
136
+ children: objectRestoration.label
137
+ }),
138
+ objectRestoration.events.map((event)=>/*#__PURE__*/ jsx(Checkbox, {
139
+ id: event,
140
+ label: event,
141
+ checked: value.includes(event),
142
+ disabled: isEventDisabled(event, value),
143
+ onChange: ()=>toggleEvent(value, event, onChange)
144
+ }, event))
145
+ ]
146
+ }),
147
+ lifecycle.events.length > 0 && /*#__PURE__*/ jsxs(Stack, {
148
+ direction: "vertical",
149
+ gap: "r8",
150
+ children: [
151
+ /*#__PURE__*/ jsx(Text, {
152
+ color: "textPrimary",
153
+ children: lifecycle.label
154
+ }),
155
+ lifecycle.events.map((event)=>/*#__PURE__*/ jsx(Checkbox, {
156
+ id: event,
157
+ label: event,
158
+ checked: value.includes(event),
159
+ disabled: isEventDisabled(event, value),
160
+ onChange: ()=>toggleEvent(value, event, onChange)
161
+ }, event))
162
+ ]
163
+ }),
164
+ replication.events.length > 0 && /*#__PURE__*/ jsxs(Stack, {
165
+ direction: "vertical",
166
+ gap: "r8",
167
+ children: [
168
+ /*#__PURE__*/ jsx(Text, {
169
+ color: "textPrimary",
170
+ children: replication.label
171
+ }),
172
+ replication.events.map((event)=>/*#__PURE__*/ jsx(Checkbox, {
173
+ id: event,
174
+ label: event,
175
+ checked: value.includes(event),
176
+ disabled: isEventDisabled(event, value),
177
+ onChange: ()=>toggleEvent(value, event, onChange)
178
+ }, event))
179
+ ]
180
+ }),
181
+ objectTagging.events.length > 0 && /*#__PURE__*/ jsxs(Stack, {
66
182
  direction: "vertical",
67
183
  gap: "r8",
68
184
  children: [
69
185
  /*#__PURE__*/ jsx(Text, {
70
186
  color: "textPrimary",
71
- children: objectCreationEvents.label
187
+ children: objectTagging.label
72
188
  }),
73
- objectCreationEvents.events.map((event)=>/*#__PURE__*/ jsx(Checkbox, {
189
+ objectTagging.events.map((event)=>/*#__PURE__*/ jsx(Checkbox, {
74
190
  id: event,
75
191
  label: event,
76
192
  checked: value.includes(event),
@@ -79,15 +195,15 @@ function EventsSection() {
79
195
  }, event))
80
196
  ]
81
197
  }),
82
- /*#__PURE__*/ jsxs(Stack, {
198
+ storageAccess.events.length > 0 && /*#__PURE__*/ jsxs(Stack, {
83
199
  direction: "vertical",
84
200
  gap: "r8",
85
201
  children: [
86
202
  /*#__PURE__*/ jsx(Text, {
87
203
  color: "textPrimary",
88
- children: objectDeletionEvents.label
204
+ children: storageAccess.label
89
205
  }),
90
- objectDeletionEvents.events.map((event)=>/*#__PURE__*/ jsx(Checkbox, {
206
+ storageAccess.events.map((event)=>/*#__PURE__*/ jsx(Checkbox, {
91
207
  id: event,
92
208
  label: event,
93
209
  checked: value.includes(event),
@@ -96,15 +212,15 @@ function EventsSection() {
96
212
  }, event))
97
213
  ]
98
214
  }),
99
- /*#__PURE__*/ jsxs(Stack, {
215
+ testing.events.length > 0 && /*#__PURE__*/ jsxs(Stack, {
100
216
  direction: "vertical",
101
217
  gap: "r8",
102
218
  children: [
103
219
  /*#__PURE__*/ jsx(Text, {
104
220
  color: "textPrimary",
105
- children: othersEvents.label
221
+ children: testing.label
106
222
  }),
107
- othersEvents.events.map((event)=>/*#__PURE__*/ jsx(Checkbox, {
223
+ testing.events.map((event)=>/*#__PURE__*/ jsx(Checkbox, {
108
224
  id: event,
109
225
  label: event,
110
226
  checked: value.includes(event),
@@ -0,0 +1,56 @@
1
+ import { filterSupportedEvents, getFilteredEventGroups } from "../events.js";
2
+ describe('events', ()=>{
3
+ it('returns all events when supportedEvents is not configured', ()=>{
4
+ const events = [
5
+ 's3:ObjectCreated:*',
6
+ 's3:ObjectCreated:Put'
7
+ ];
8
+ const result = filterSupportedEvents(events);
9
+ expect(result).toEqual(events);
10
+ });
11
+ it('filters events to only include supported ones', ()=>{
12
+ const events = [
13
+ 's3:ObjectCreated:*',
14
+ 's3:ObjectCreated:Put',
15
+ 's3:ObjectCreated:Copy'
16
+ ];
17
+ const supportedEvents = [
18
+ 's3:ObjectCreated:*',
19
+ 's3:ObjectCreated:Put'
20
+ ];
21
+ const result = filterSupportedEvents(events, supportedEvents);
22
+ expect(result).toEqual([
23
+ 's3:ObjectCreated:*',
24
+ 's3:ObjectCreated:Put'
25
+ ]);
26
+ });
27
+ it('filters event groups based on supported events', ()=>{
28
+ const supportedEvents = [
29
+ 's3:ObjectCreated:Put',
30
+ 's3:ObjectRemoved:Delete',
31
+ 's3:Replication:OperationFailedReplication'
32
+ ];
33
+ const result = getFilteredEventGroups(supportedEvents);
34
+ expect(result.objectCreation.events).toEqual([
35
+ 's3:ObjectCreated:Put'
36
+ ]);
37
+ expect(result.objectDeletion.events).toEqual([
38
+ 's3:ObjectRemoved:Delete'
39
+ ]);
40
+ expect(result.replication.events).toEqual([
41
+ 's3:Replication:OperationFailedReplication'
42
+ ]);
43
+ expect(result.lifecycle.events).toEqual([]);
44
+ });
45
+ it('preserves category labels in filtered groups', ()=>{
46
+ const result = getFilteredEventGroups();
47
+ expect(result.objectCreation.label).toBe('Object Creation');
48
+ expect(result.objectDeletion.label).toBe('Object Deletion');
49
+ expect(result.objectRestoration.label).toBe('Object Restoration');
50
+ expect(result.lifecycle.label).toBe('Lifecycle');
51
+ expect(result.replication.label).toBe('Replication');
52
+ expect(result.objectTagging.label).toBe('Object Tagging');
53
+ expect(result.storageAccess.label).toBe('Storage & Access');
54
+ expect(result.testing.label).toBe('Testing');
55
+ });
56
+ });
@@ -1,12 +1,76 @@
1
+ import type { S3EventCategory, S3EventType } from '../../../config/types';
1
2
  export declare const objectCreationEvents: {
2
- label: string;
3
- events: string[];
3
+ label: S3EventCategory;
4
+ events: S3EventType[];
4
5
  };
5
6
  export declare const objectDeletionEvents: {
6
- label: string;
7
- events: string[];
7
+ label: S3EventCategory;
8
+ events: S3EventType[];
8
9
  };
9
- export declare const othersEvents: {
10
- label: string;
11
- events: string[];
10
+ export declare const objectRestorationEvents: {
11
+ label: S3EventCategory;
12
+ events: S3EventType[];
13
+ };
14
+ export declare const lifecycleEvents: {
15
+ label: S3EventCategory;
16
+ events: S3EventType[];
17
+ };
18
+ export declare const replicationEvents: {
19
+ label: S3EventCategory;
20
+ events: S3EventType[];
21
+ };
22
+ export declare const objectTaggingEvents: {
23
+ label: S3EventCategory;
24
+ events: S3EventType[];
25
+ };
26
+ export declare const storageAccessEvents: {
27
+ label: S3EventCategory;
28
+ events: S3EventType[];
29
+ };
30
+ export declare const testingEvents: {
31
+ label: S3EventCategory;
32
+ events: S3EventType[];
33
+ };
34
+ /**
35
+ * Filters events to only include supported ones
36
+ * If no supported events are configured, all events are returned
37
+ */
38
+ export declare function filterSupportedEvents(events: S3EventType[], supportedEvents?: S3EventType[]): S3EventType[];
39
+ /**
40
+ * Gets filtered event groups based on supported events
41
+ * If a wildcard is not supported, but specific events are, the wildcard is filtered out
42
+ */
43
+ export declare function getFilteredEventGroups(supportedEvents?: S3EventType[]): {
44
+ objectCreation: {
45
+ label: S3EventCategory;
46
+ events: S3EventType[];
47
+ };
48
+ objectDeletion: {
49
+ label: S3EventCategory;
50
+ events: S3EventType[];
51
+ };
52
+ objectRestoration: {
53
+ label: S3EventCategory;
54
+ events: S3EventType[];
55
+ };
56
+ lifecycle: {
57
+ label: S3EventCategory;
58
+ events: S3EventType[];
59
+ };
60
+ replication: {
61
+ label: S3EventCategory;
62
+ events: S3EventType[];
63
+ };
64
+ objectTagging: {
65
+ label: S3EventCategory;
66
+ events: S3EventType[];
67
+ };
68
+ storageAccess: {
69
+ label: S3EventCategory;
70
+ events: S3EventType[];
71
+ };
72
+ testing: {
73
+ label: S3EventCategory;
74
+ events: S3EventType[];
75
+ };
12
76
  };