@scality/data-browser-library 1.0.0-preview.13 → 1.0.0-preview.16

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 (212) hide show
  1. package/dist/components/DataBrowserUI.d.ts +6 -14
  2. package/dist/components/DataBrowserUI.js +79 -55
  3. package/dist/components/Editor.d.ts +1 -1
  4. package/dist/components/Editor.js +3 -3
  5. package/dist/components/__tests__/BucketCreate.test.js +102 -102
  6. package/dist/components/__tests__/BucketDetails.test.js +122 -123
  7. package/dist/components/__tests__/BucketLifecycleFormPage.test.js +177 -177
  8. package/dist/components/__tests__/BucketLifecycleList.test.js +85 -85
  9. package/dist/components/__tests__/BucketList.test.js +175 -176
  10. package/dist/components/__tests__/BucketNotificationCreatePage.test.js +84 -84
  11. package/dist/components/__tests__/BucketOverview.test.js +257 -201
  12. package/dist/components/__tests__/BucketPolicyPage.test.js +62 -62
  13. package/dist/components/__tests__/BucketReplicationFormPage.test.js +542 -542
  14. package/dist/components/__tests__/BucketReplicationList.test.js +106 -106
  15. package/dist/components/__tests__/CreateFolderButton.test.js +56 -56
  16. package/dist/components/__tests__/DeleteBucketButton.test.js +62 -62
  17. package/dist/components/__tests__/DeleteBucketConfigRuleButton.test.js +47 -47
  18. package/dist/components/__tests__/DeleteObjectButton.test.js +63 -63
  19. package/dist/components/__tests__/EmptyBucketButton.test.js +56 -56
  20. package/dist/components/__tests__/MetadataSearch.test.js +65 -65
  21. package/dist/components/__tests__/ObjectList.test.js +252 -251
  22. package/dist/components/__tests__/UploadButton.test.js +45 -45
  23. package/dist/components/buckets/BucketCreate.d.ts +2 -2
  24. package/dist/components/buckets/BucketCreate.js +41 -41
  25. package/dist/components/buckets/BucketDetails.d.ts +2 -2
  26. package/dist/components/buckets/BucketDetails.js +48 -36
  27. package/dist/components/buckets/BucketLifecycleFormPage.js +161 -160
  28. package/dist/components/buckets/BucketLifecycleList.d.ts +2 -2
  29. package/dist/components/buckets/BucketLifecycleList.js +46 -46
  30. package/dist/components/buckets/BucketList.d.ts +2 -2
  31. package/dist/components/buckets/BucketList.js +28 -27
  32. package/dist/components/buckets/BucketLocation.js +3 -3
  33. package/dist/components/buckets/BucketOverview.d.ts +1 -1
  34. package/dist/components/buckets/BucketOverview.js +64 -65
  35. package/dist/components/buckets/BucketPage.js +19 -11
  36. package/dist/components/buckets/BucketPolicyButton.js +2 -2
  37. package/dist/components/buckets/BucketPolicyPage.js +27 -25
  38. package/dist/components/buckets/BucketReplicationFormPage.js +133 -132
  39. package/dist/components/buckets/BucketReplicationList.d.ts +2 -2
  40. package/dist/components/buckets/BucketReplicationList.js +41 -41
  41. package/dist/components/buckets/BucketVersioning.js +11 -11
  42. package/dist/components/buckets/DeleteBucketButton.js +5 -5
  43. package/dist/components/buckets/DeleteBucketConfigRuleButton.d.ts +2 -2
  44. package/dist/components/buckets/DeleteBucketConfigRuleButton.js +1 -1
  45. package/dist/components/buckets/EmptyBucketButton.js +19 -19
  46. package/dist/components/buckets/EmptyBucketSummary.d.ts +1 -1
  47. package/dist/components/buckets/EmptyBucketSummary.js +1 -1
  48. package/dist/components/buckets/EmptyBucketSummaryList.js +22 -22
  49. package/dist/components/buckets/__tests__/BucketVersioning.test.js +45 -45
  50. package/dist/components/buckets/notifications/BucketNotificationCreatePage.js +34 -33
  51. package/dist/components/buckets/notifications/EventsSection.js +144 -28
  52. package/dist/components/buckets/notifications/__tests__/events.test.d.ts +1 -0
  53. package/dist/components/buckets/notifications/__tests__/events.test.js +56 -0
  54. package/dist/components/buckets/notifications/events.d.ts +71 -7
  55. package/dist/components/buckets/notifications/events.js +98 -16
  56. package/dist/components/index.d.ts +24 -22
  57. package/dist/components/index.js +5 -3
  58. package/dist/components/layouts/ArrowNavigation.d.ts +1 -2
  59. package/dist/components/layouts/ArrowNavigation.js +3 -3
  60. package/dist/components/layouts/BrowserPageLayout.d.ts +2 -3
  61. package/dist/components/layouts/BrowserPageLayout.js +1 -1
  62. package/dist/components/objects/CreateFolderButton.d.ts +2 -2
  63. package/dist/components/objects/CreateFolderButton.js +9 -9
  64. package/dist/components/objects/DeleteObjectButton.d.ts +1 -1
  65. package/dist/components/objects/DeleteObjectButton.js +20 -20
  66. package/dist/components/objects/ObjectDetails/ObjectMetadata.d.ts +1 -1
  67. package/dist/components/objects/ObjectDetails/ObjectMetadata.js +56 -56
  68. package/dist/components/objects/ObjectDetails/ObjectSummary.d.ts +1 -1
  69. package/dist/components/objects/ObjectDetails/ObjectSummary.js +39 -39
  70. package/dist/components/objects/ObjectDetails/ObjectTags.d.ts +1 -1
  71. package/dist/components/objects/ObjectDetails/ObjectTags.js +25 -25
  72. package/dist/components/objects/ObjectDetails/__tests__/ObjectDetails.test.js +119 -119
  73. package/dist/components/objects/ObjectDetails/__tests__/ObjectSummary.test.js +211 -211
  74. package/dist/components/objects/ObjectDetails/index.d.ts +1 -1
  75. package/dist/components/objects/ObjectDetails/index.js +30 -30
  76. package/dist/components/objects/ObjectList.d.ts +5 -5
  77. package/dist/components/objects/ObjectList.js +113 -112
  78. package/dist/components/objects/ObjectLock/EditRetentionButton.js +3 -3
  79. package/dist/components/objects/ObjectLock/ObjectLockRetentionSettings.js +14 -14
  80. package/dist/components/objects/ObjectLock/ObjectLockSettings.d.ts +1 -1
  81. package/dist/components/objects/ObjectLock/ObjectLockSettings.js +29 -28
  82. package/dist/components/objects/ObjectLock/ObjectLockSettingsUtils.d.ts +1 -1
  83. package/dist/components/objects/ObjectLock/ObjectLockSettingsUtils.js +6 -6
  84. package/dist/components/objects/ObjectLock/__tests__/EditRetentionButton.test.js +50 -50
  85. package/dist/components/objects/ObjectLock/__tests__/ObjectLockSettings.test.js +77 -77
  86. package/dist/components/objects/ObjectPage.js +5 -4
  87. package/dist/components/objects/UploadButton.d.ts +3 -3
  88. package/dist/components/objects/UploadButton.js +5 -5
  89. package/dist/components/providers/DataBrowserProvider.d.ts +23 -12
  90. package/dist/components/providers/DataBrowserProvider.js +60 -38
  91. package/dist/components/providers/QueryProvider.d.ts +9 -0
  92. package/dist/components/providers/QueryProvider.js +22 -0
  93. package/dist/components/search/MetadataSearch.js +26 -25
  94. package/dist/components/search/SearchHints.js +1 -1
  95. package/dist/components/ui/ArrayFieldActions.js +4 -4
  96. package/dist/components/ui/ConfirmDeleteRuleModal.d.ts +1 -1
  97. package/dist/components/ui/ConfirmDeleteRuleModal.js +1 -1
  98. package/dist/components/ui/DeleteObjectModalContent.d.ts +1 -1
  99. package/dist/components/ui/DeleteObjectModalContent.js +12 -12
  100. package/dist/components/ui/FilterFormSection.d.ts +2 -2
  101. package/dist/components/ui/FilterFormSection.js +29 -29
  102. package/dist/components/ui/Search.elements.d.ts +1 -1
  103. package/dist/components/ui/Search.elements.js +7 -7
  104. package/dist/components/ui/Table.elements.js +5 -5
  105. package/dist/config/factory.d.ts +23 -10
  106. package/dist/config/factory.js +22 -7
  107. package/dist/config/types.d.ts +20 -3
  108. package/dist/contexts/DataBrowserUICustomizationContext.d.ts +2 -2
  109. package/dist/hooks/__tests__/useISVBucketDetection.test.js +42 -42
  110. package/dist/hooks/__tests__/useIsBucketEmpty.test.js +25 -25
  111. package/dist/hooks/bucketConfiguration.d.ts +1 -1
  112. package/dist/hooks/bucketConfiguration.js +48 -48
  113. package/dist/hooks/bucketOperations.d.ts +1 -1
  114. package/dist/hooks/bucketOperations.js +6 -6
  115. package/dist/hooks/factories/__tests__/useCreateS3FunctionMutationHook.test.js +78 -78
  116. package/dist/hooks/factories/__tests__/useCreateS3InfiniteQueryHook.test.js +78 -78
  117. package/dist/hooks/factories/__tests__/useCreateS3LoginHook.test.js +42 -42
  118. package/dist/hooks/factories/__tests__/useCreateS3MutationHook.test.js +61 -61
  119. package/dist/hooks/factories/__tests__/useCreateS3QueryHook.test.js +63 -63
  120. package/dist/hooks/factories/index.d.ts +4 -4
  121. package/dist/hooks/factories/useCreateS3InfiniteQueryHook.d.ts +2 -2
  122. package/dist/hooks/factories/useCreateS3InfiniteQueryHook.js +15 -12
  123. package/dist/hooks/factories/useCreateS3LoginHook.d.ts +2 -2
  124. package/dist/hooks/factories/useCreateS3MutationHook.d.ts +3 -3
  125. package/dist/hooks/factories/useCreateS3MutationHook.js +6 -1
  126. package/dist/hooks/factories/useCreateS3QueryHook.d.ts +2 -2
  127. package/dist/hooks/factories/useCreateS3QueryHook.js +8 -5
  128. package/dist/hooks/index.d.ts +16 -13
  129. package/dist/hooks/index.js +4 -1
  130. package/dist/hooks/loginOperations.d.ts +1 -1
  131. package/dist/hooks/loginOperations.js +1 -1
  132. package/dist/hooks/objectOperations.d.ts +2 -2
  133. package/dist/hooks/objectOperations.js +49 -49
  134. package/dist/hooks/presignedOperations.d.ts +2 -2
  135. package/dist/hooks/presignedOperations.js +3 -3
  136. package/dist/hooks/useBatchObjectLegalHold.js +7 -4
  137. package/dist/hooks/useDataBrowserNavigate.d.ts +28 -0
  138. package/dist/hooks/useDataBrowserNavigate.js +24 -0
  139. package/dist/hooks/useDeleteBucketConfigRule.d.ts +2 -2
  140. package/dist/hooks/useDeleteBucketConfigRule.js +4 -4
  141. package/dist/hooks/useEmptyBucket.js +10 -10
  142. package/dist/hooks/useFeatures.d.ts +7 -0
  143. package/dist/hooks/useFeatures.js +8 -0
  144. package/dist/hooks/useISVBucketDetection.js +5 -5
  145. package/dist/hooks/useIsBucketEmpty.js +4 -4
  146. package/dist/hooks/useLoginMutation.d.ts +1 -1
  147. package/dist/hooks/useLoginMutation.js +1 -1
  148. package/dist/hooks/useS3Client.d.ts +6 -0
  149. package/dist/hooks/useS3Client.js +3 -2
  150. package/dist/hooks/useS3ConfigSwitch.d.ts +11 -0
  151. package/dist/hooks/useS3ConfigSwitch.js +37 -0
  152. package/dist/hooks/useSupportedNotificationEvents.d.ts +6 -0
  153. package/dist/hooks/useSupportedNotificationEvents.js +8 -0
  154. package/dist/index.d.ts +6 -6
  155. package/dist/test/msw/handlers/deleteBucket.d.ts +1 -1
  156. package/dist/test/msw/handlers/deleteBucket.js +20 -10
  157. package/dist/test/msw/handlers/getBucketAcl.d.ts +1 -1
  158. package/dist/test/msw/handlers/getBucketAcl.js +29 -17
  159. package/dist/test/msw/handlers/getBucketLocation.d.ts +1 -1
  160. package/dist/test/msw/handlers/getBucketLocation.js +29 -15
  161. package/dist/test/msw/handlers/getBucketPolicy.d.ts +1 -1
  162. package/dist/test/msw/handlers/getBucketPolicy.js +52 -32
  163. package/dist/test/msw/handlers/headObject.d.ts +1 -1
  164. package/dist/test/msw/handlers/headObject.js +31 -13
  165. package/dist/test/msw/handlers/listBuckets.d.ts +1 -1
  166. package/dist/test/msw/handlers/listBuckets.js +5 -3
  167. package/dist/test/msw/handlers/listObjectVersions.d.ts +1 -1
  168. package/dist/test/msw/handlers/listObjectVersions.js +38 -26
  169. package/dist/test/msw/handlers/listObjects.d.ts +1 -1
  170. package/dist/test/msw/handlers/listObjects.js +35 -23
  171. package/dist/test/msw/handlers/objectLegalHold.d.ts +1 -1
  172. package/dist/test/msw/handlers/objectLegalHold.js +31 -16
  173. package/dist/test/msw/handlers/objectRetention.d.ts +1 -1
  174. package/dist/test/msw/handlers/objectRetention.js +31 -17
  175. package/dist/test/msw/handlers/putBucketAcl.d.ts +1 -1
  176. package/dist/test/msw/handlers/putBucketAcl.js +29 -14
  177. package/dist/test/msw/handlers/putObject.d.ts +1 -1
  178. package/dist/test/msw/handlers/putObject.js +27 -12
  179. package/dist/test/msw/handlers.d.ts +3 -3
  180. package/dist/test/msw/handlers.js +72 -49
  181. package/dist/test/msw/index.d.ts +2 -2
  182. package/dist/test/msw/server.d.ts +1 -1
  183. package/dist/test/msw/server.js +1 -1
  184. package/dist/test/msw/utils.js +2 -2
  185. package/dist/test/setup.d.ts +1 -1
  186. package/dist/test/setup.js +19 -19
  187. package/dist/test/testUtils.d.ts +9 -15
  188. package/dist/test/testUtils.js +73 -91
  189. package/dist/test/utils/errorHandling.test.js +119 -119
  190. package/dist/types/index.d.ts +6 -31
  191. package/dist/utils/__tests__/s3ConfigIdentifier.test.d.ts +1 -0
  192. package/dist/utils/__tests__/s3ConfigIdentifier.test.js +429 -0
  193. package/dist/utils/constants.js +8 -8
  194. package/dist/utils/deletion/index.d.ts +2 -2
  195. package/dist/utils/deletion/messages.d.ts +1 -1
  196. package/dist/utils/deletion/messages.js +4 -4
  197. package/dist/utils/errorHandling.d.ts +3 -3
  198. package/dist/utils/errorHandling.js +6 -6
  199. package/dist/utils/hooks.js +8 -8
  200. package/dist/utils/index.d.ts +5 -4
  201. package/dist/utils/index.js +2 -0
  202. package/dist/utils/proxyMiddleware.d.ts +1 -1
  203. package/dist/utils/proxyMiddleware.js +6 -11
  204. package/dist/utils/s3Client.d.ts +2 -2
  205. package/dist/utils/s3Client.js +1 -1
  206. package/dist/utils/s3ConfigIdentifier.d.ts +68 -0
  207. package/dist/utils/s3ConfigIdentifier.js +55 -0
  208. package/dist/utils/s3RuleUtils.d.ts +5 -5
  209. package/dist/utils/s3RuleUtils.js +17 -17
  210. package/package.json +2 -2
  211. package/dist/utils/useFeatures.d.ts +0 -1
  212. package/dist/utils/useFeatures.js +0 -7
@@ -3,10 +3,10 @@ import { fireEvent, render, screen, waitFor } from "@testing-library/react";
3
3
  import user_event from "@testing-library/user-event";
4
4
  import { createTestWrapper } from "../../test/testUtils.js";
5
5
  import { UploadButton } from "../objects/UploadButton.js";
6
- describe("UploadButton - Core Functionality", ()=>{
6
+ describe('UploadButton - Core Functionality', ()=>{
7
7
  const defaultProps = {
8
- bucket: "test-bucket",
9
- prefix: "test-prefix"
8
+ bucket: 'test-bucket',
9
+ prefix: 'test-prefix'
10
10
  };
11
11
  const renderUploadButton = (props = {})=>{
12
12
  const Wrapper = createTestWrapper();
@@ -17,128 +17,128 @@ describe("UploadButton - Core Functionality", ()=>{
17
17
  })
18
18
  }));
19
19
  };
20
- it("renders upload button with default label", ()=>{
20
+ it('renders upload button with default label', ()=>{
21
21
  renderUploadButton();
22
- expect(screen.getByRole("button", {
22
+ expect(screen.getByRole('button', {
23
23
  name: /upload/i
24
24
  })).toBeInTheDocument();
25
25
  });
26
- it("renders upload button", ()=>{
26
+ it('renders upload button', ()=>{
27
27
  renderUploadButton();
28
- expect(screen.getByRole("button", {
28
+ expect(screen.getByRole('button', {
29
29
  name: /upload/i
30
30
  })).toBeInTheDocument();
31
31
  });
32
- it("opens modal when upload button is clicked", async ()=>{
32
+ it('opens modal when upload button is clicked', async ()=>{
33
33
  renderUploadButton();
34
- const uploadButton = screen.getByRole("button", {
34
+ const uploadButton = screen.getByRole('button', {
35
35
  name: /upload/i
36
36
  });
37
37
  fireEvent.click(uploadButton);
38
38
  await waitFor(()=>{
39
- expect(screen.getByText("Upload Files")).toBeInTheDocument();
39
+ expect(screen.getByText('Upload Files')).toBeInTheDocument();
40
40
  });
41
41
  });
42
- it("closes modal when cancel button is clicked", async ()=>{
42
+ it('closes modal when cancel button is clicked', async ()=>{
43
43
  renderUploadButton();
44
- const uploadButton = screen.getByRole("button", {
44
+ const uploadButton = screen.getByRole('button', {
45
45
  name: /upload/i
46
46
  });
47
47
  fireEvent.click(uploadButton);
48
48
  await waitFor(()=>{
49
- expect(screen.getByText("Upload Files")).toBeInTheDocument();
49
+ expect(screen.getByText('Upload Files')).toBeInTheDocument();
50
50
  });
51
- const cancelButton = screen.getByRole("button", {
51
+ const cancelButton = screen.getByRole('button', {
52
52
  name: /cancel/i
53
53
  });
54
54
  fireEvent.click(cancelButton);
55
55
  await waitFor(()=>{
56
- expect(screen.queryByText("Upload Files")).not.toBeInTheDocument();
56
+ expect(screen.queryByText('Upload Files')).not.toBeInTheDocument();
57
57
  });
58
58
  });
59
- it("displays empty state initially", async ()=>{
59
+ it('displays empty state initially', async ()=>{
60
60
  renderUploadButton();
61
- const uploadButton = screen.getByRole("button", {
61
+ const uploadButton = screen.getByRole('button', {
62
62
  name: /upload/i
63
63
  });
64
64
  fireEvent.click(uploadButton);
65
65
  await waitFor(()=>{
66
- expect(screen.getByText("Drag and drop files and folders here")).toBeInTheDocument();
67
- expect(screen.getByRole("button", {
66
+ expect(screen.getByText('Drag and drop files and folders here')).toBeInTheDocument();
67
+ expect(screen.getByRole('button', {
68
68
  name: /add files/i
69
69
  })).toBeInTheDocument();
70
70
  });
71
71
  });
72
- it("can add files and shows upload button enabled", async ()=>{
72
+ it('can add files and shows upload button enabled', async ()=>{
73
73
  const onUploadSuccess = jest.fn();
74
74
  renderUploadButton({
75
75
  onUploadSuccess
76
76
  });
77
- const uploadButton = screen.getByRole("button", {
77
+ const uploadButton = screen.getByRole('button', {
78
78
  name: /upload/i
79
79
  });
80
80
  fireEvent.click(uploadButton);
81
81
  await waitFor(()=>{
82
- expect(screen.getByText("Upload Files")).toBeInTheDocument();
82
+ expect(screen.getByText('Upload Files')).toBeInTheDocument();
83
83
  });
84
- const uploadButtons = screen.getAllByRole("button", {
85
- name: "Upload"
84
+ const uploadButtons = screen.getAllByRole('button', {
85
+ name: 'Upload'
86
86
  });
87
- const modalUploadButton = uploadButtons.find((button)=>!button.querySelector("svg"));
87
+ const modalUploadButton = uploadButtons.find((button)=>!button.querySelector('svg'));
88
88
  expect(modalUploadButton).toBeDisabled();
89
- const fileInput = screen.getByRole("presentation").querySelector('input[type="file"]');
89
+ const fileInput = screen.getByRole('presentation').querySelector('input[type="file"]');
90
90
  const testFile = new File([
91
- "test content"
92
- ], "test.txt", {
93
- type: "text/plain"
91
+ 'test content'
92
+ ], 'test.txt', {
93
+ type: 'text/plain'
94
94
  });
95
95
  await user_event.upload(fileInput, testFile);
96
96
  await waitFor(()=>{
97
- expect(screen.getByText("test.txt")).toBeInTheDocument();
98
- expect(screen.getByText("12 B")).toBeInTheDocument();
97
+ expect(screen.getByText('test.txt')).toBeInTheDocument();
98
+ expect(screen.getByText('12 B')).toBeInTheDocument();
99
99
  });
100
100
  expect(modalUploadButton).toBeEnabled();
101
101
  });
102
- it("displays correct bucket and prefix information", ()=>{
103
- const customBucket = "custom-bucket";
104
- const customPrefix = "custom/prefix";
102
+ it('displays correct bucket and prefix information', ()=>{
103
+ const customBucket = 'custom-bucket';
104
+ const customPrefix = 'custom/prefix';
105
105
  renderUploadButton({
106
106
  bucket: customBucket,
107
107
  prefix: customPrefix
108
108
  });
109
- expect(screen.getByRole("button", {
109
+ expect(screen.getByRole('button', {
110
110
  name: /upload/i
111
111
  })).toBeInTheDocument();
112
112
  });
113
- it("handles different button variants", ()=>{
113
+ it('handles different button variants', ()=>{
114
114
  renderUploadButton({
115
- variant: "primary"
115
+ variant: 'primary'
116
116
  });
117
- const button = screen.getByRole("button", {
117
+ const button = screen.getByRole('button', {
118
118
  name: /upload/i
119
119
  });
120
120
  expect(button).toBeInTheDocument();
121
121
  });
122
- it("resets state when modal is closed", async ()=>{
122
+ it('resets state when modal is closed', async ()=>{
123
123
  renderUploadButton();
124
- const uploadButton = screen.getByRole("button", {
124
+ const uploadButton = screen.getByRole('button', {
125
125
  name: /upload/i
126
126
  });
127
127
  fireEvent.click(uploadButton);
128
128
  await waitFor(()=>{
129
- expect(screen.getByText("Upload Files")).toBeInTheDocument();
129
+ expect(screen.getByText('Upload Files')).toBeInTheDocument();
130
130
  });
131
- const cancelButton = screen.getByRole("button", {
131
+ const cancelButton = screen.getByRole('button', {
132
132
  name: /cancel/i
133
133
  });
134
134
  fireEvent.click(cancelButton);
135
135
  await waitFor(()=>{
136
- expect(screen.queryByText("Upload Files")).not.toBeInTheDocument();
136
+ expect(screen.queryByText('Upload Files')).not.toBeInTheDocument();
137
137
  });
138
138
  fireEvent.click(uploadButton);
139
139
  await waitFor(()=>{
140
- expect(screen.getByText("Upload Files")).toBeInTheDocument();
141
- expect(screen.getByText("Drag and drop files and folders here")).toBeInTheDocument();
140
+ expect(screen.getByText('Upload Files')).toBeInTheDocument();
141
+ expect(screen.getByText('Drag and drop files and folders here')).toBeInTheDocument();
142
142
  });
143
143
  });
144
144
  });
@@ -1,5 +1,5 @@
1
- import Joi from "joi";
2
- import { ObjectLockRetentionMode } from "@aws-sdk/client-s3";
1
+ import Joi from 'joi';
2
+ import { ObjectLockRetentionMode } from '@aws-sdk/client-s3';
3
3
  export declare const bucketErrorMessage = "Bucket names can include only lowercase letters, numbers, dots (.), and hyphens (-)";
4
4
  export declare const bucketNameValidationSchema: Joi.StringSchema<string>;
5
5
  export declare const baseBucketCreateSchema: Joi.ObjectSchema<any>;
@@ -5,69 +5,69 @@ import { Button, Input } from "@scality/core-ui/dist/next";
5
5
  import { convertRemToPixels } from "@scality/core-ui/dist/utils";
6
6
  import joi from "joi";
7
7
  import { FormProvider, useForm } from "react-hook-form";
8
- import { useNavigate } from "react-router";
9
8
  import ObjectLockRetentionSettings from "../objects/ObjectLock/ObjectLockRetentionSettings.js";
9
+ import { useDataBrowserNavigate } from "../../hooks/useDataBrowserNavigate.js";
10
10
  import { objectLockRetentionSettingsValidationRules } from "../objects/ObjectLock/ObjectLockSettings.js";
11
11
  import { useCreateBucket, useSetBucketObjectLockConfiguration, useSetBucketVersioning } from "../../hooks/index.js";
12
- const bucketErrorMessage = "Bucket names can include only lowercase letters, numbers, dots (.), and hyphens (-)";
13
- const bucketNameValidationSchema = joi.string().label("Bucket Name").required().min(3).max(63).pattern(/^[a-z0-9]([a-z0-9.-]*[a-z0-9])?$/, {
14
- name: "bucketName",
12
+ const bucketErrorMessage = 'Bucket names can include only lowercase letters, numbers, dots (.), and hyphens (-)';
13
+ const bucketNameValidationSchema = joi.string().label('Bucket Name').required().min(3).max(63).pattern(/^[a-z0-9]([a-z0-9.-]*[a-z0-9])?$/, {
14
+ name: 'bucketName',
15
15
  invert: false
16
16
  }).messages({
17
- "string.pattern.name": bucketErrorMessage
17
+ 'string.pattern.name': bucketErrorMessage
18
18
  }).custom((value, helpers)=>{
19
- if (value.includes("..")) return helpers.message({
20
- custom: "Bucket names cannot contain two adjacent periods"
19
+ if (value.includes('..')) return helpers.message({
20
+ custom: 'Bucket names cannot contain two adjacent periods'
21
21
  });
22
22
  if (/^(\d{1,3}\.){3}\d{1,3}$/.test(value)) return helpers.message({
23
- custom: "Bucket names must not be formatted as an IP address"
23
+ custom: 'Bucket names must not be formatted as an IP address'
24
24
  });
25
25
  const forbiddenPrefixes = [
26
- "xn--",
27
- "sthree-",
28
- "amzn-s3-demo-"
26
+ 'xn--',
27
+ 'sthree-',
28
+ 'amzn-s3-demo-'
29
29
  ];
30
30
  if (forbiddenPrefixes.some((prefix)=>value.startsWith(prefix))) return helpers.message({
31
- custom: `Bucket names must not start with ${forbiddenPrefixes.join(", ")}`
31
+ custom: `Bucket names must not start with ${forbiddenPrefixes.join(', ')}`
32
32
  });
33
33
  const forbiddenSuffixes = [
34
- "-s3alias",
35
- "--ol-s3",
36
- "--x-s3",
37
- ".mrap"
34
+ '-s3alias',
35
+ '--ol-s3',
36
+ '--x-s3',
37
+ '.mrap'
38
38
  ];
39
39
  if (forbiddenSuffixes.some((suffix)=>value.endsWith(suffix))) return helpers.message({
40
- custom: `Bucket names must not end with ${forbiddenSuffixes.join(", ")}`
40
+ custom: `Bucket names must not end with ${forbiddenSuffixes.join(', ')}`
41
41
  });
42
42
  const existingBuckets = helpers.prefs.context?.existingBuckets;
43
43
  if (Array.isArray(existingBuckets)) {
44
44
  const isDuplicate = existingBuckets.some((bucketName)=>bucketName.toLowerCase() === value.toLowerCase());
45
45
  if (isDuplicate) return helpers.message({
46
- custom: "A bucket with this name already exists"
46
+ custom: 'A bucket with this name already exists'
47
47
  });
48
48
  }
49
49
  return value;
50
- }, "AWS S3 bucket naming rules");
50
+ }, 'AWS S3 bucket naming rules');
51
51
  const baseBucketCreateSchema = joi.object({
52
52
  name: bucketNameValidationSchema,
53
53
  isVersioning: joi.boolean(),
54
54
  ...objectLockRetentionSettingsValidationRules
55
55
  });
56
56
  const BucketCreate = ({ subTitle, validationSchema, validationContext, defaultValues: customDefaultValues, children, onSubmit: onSubmitProp, onCancel: onCancelProp })=>{
57
- const navigate = useNavigate();
57
+ const navigate = useDataBrowserNavigate();
58
58
  const { showToast } = useToast();
59
59
  const baseDefaultValues = {
60
- name: "",
60
+ name: '',
61
61
  isVersioning: false,
62
62
  isObjectLockEnabled: false,
63
63
  isDefaultRetentionEnabled: false,
64
- retentionMode: "GOVERNANCE",
64
+ retentionMode: 'GOVERNANCE',
65
65
  retentionPeriod: 1,
66
- retentionPeriodFrequencyChoice: "DAYS",
66
+ retentionPeriodFrequencyChoice: 'DAYS',
67
67
  ...customDefaultValues
68
68
  };
69
69
  const useFormMethods = useForm({
70
- mode: "all",
70
+ mode: 'all',
71
71
  resolver: joiResolver(validationSchema || baseBucketCreateSchema, {
72
72
  context: validationContext || {}
73
73
  }),
@@ -76,19 +76,19 @@ const BucketCreate = ({ subTitle, validationSchema, validationContext, defaultVa
76
76
  });
77
77
  const { register, handleSubmit, formState, watch } = useFormMethods;
78
78
  const { isValid, errors } = formState;
79
- const isObjectLockEnabled = watch("isObjectLockEnabled");
79
+ const isObjectLockEnabled = watch('isObjectLockEnabled');
80
80
  const { mutate: createBucket, isPending: isCreatingBucket } = useCreateBucket();
81
81
  const { mutate: setBucketVersioning } = useSetBucketVersioning();
82
82
  const { mutate: setObjectLockConfig } = useSetBucketObjectLockConfiguration();
83
83
  const handleCancel = ()=>{
84
84
  if (onCancelProp) onCancelProp();
85
- else navigate("/buckets");
85
+ else navigate('/buckets');
86
86
  };
87
87
  const handleSuccess = (bucketName)=>{
88
88
  showToast({
89
89
  open: true,
90
90
  message: `Bucket "${bucketName}" created successfully`,
91
- status: "success"
91
+ status: 'success'
92
92
  });
93
93
  navigate(`/buckets/${bucketName}`);
94
94
  };
@@ -96,7 +96,7 @@ const BucketCreate = ({ subTitle, validationSchema, validationContext, defaultVa
96
96
  showToast({
97
97
  open: true,
98
98
  message: error instanceof Error ? error.message : `Failed to ${operation}`,
99
- status: "error"
99
+ status: 'error'
100
100
  });
101
101
  };
102
102
  const onSubmit = (data)=>{
@@ -112,41 +112,41 @@ const BucketCreate = ({ subTitle, validationSchema, validationContext, defaultVa
112
112
  if (needsExplicitVersioning) setBucketVersioning({
113
113
  Bucket: bucketName,
114
114
  VersioningConfiguration: {
115
- Status: "Enabled"
115
+ Status: 'Enabled'
116
116
  }
117
117
  }, {
118
118
  onSuccess: ()=>handleSuccess(bucketName),
119
- onError: (error)=>handleError(error, "enable versioning")
119
+ onError: (error)=>handleError(error, 'enable versioning')
120
120
  });
121
121
  else if (needsRetentionConfig) {
122
122
  const retentionConfig = {
123
123
  Bucket: bucketName,
124
124
  ObjectLockConfiguration: {
125
- ObjectLockEnabled: "Enabled",
125
+ ObjectLockEnabled: 'Enabled',
126
126
  Rule: {
127
127
  DefaultRetention: {
128
128
  Mode: data.retentionMode,
129
- Days: "DAYS" === data.retentionPeriodFrequencyChoice ? data.retentionPeriod : void 0,
130
- Years: "YEARS" === data.retentionPeriodFrequencyChoice ? data.retentionPeriod : void 0
129
+ Days: 'DAYS' === data.retentionPeriodFrequencyChoice ? data.retentionPeriod : void 0,
130
+ Years: 'YEARS' === data.retentionPeriodFrequencyChoice ? data.retentionPeriod : void 0
131
131
  }
132
132
  }
133
133
  }
134
134
  };
135
135
  setObjectLockConfig(retentionConfig, {
136
136
  onSuccess: ()=>handleSuccess(bucketName),
137
- onError: (error)=>handleError(error, "configure object lock retention")
137
+ onError: (error)=>handleError(error, 'configure object lock retention')
138
138
  });
139
139
  } else handleSuccess(bucketName);
140
140
  },
141
- onError: (error)=>handleError(error, "create bucket")
141
+ onError: (error)=>handleError(error, 'create bucket')
142
142
  });
143
143
  };
144
144
  return /*#__PURE__*/ jsx(FormProvider, {
145
145
  ...useFormMethods,
146
146
  children: /*#__PURE__*/ jsxs(Form, {
147
147
  layout: {
148
- kind: "page",
149
- title: "Create a New Bucket",
148
+ kind: 'page',
149
+ title: 'Create a New Bucket',
150
150
  subTitle
151
151
  },
152
152
  requireMode: "partial",
@@ -184,7 +184,7 @@ const BucketCreate = ({ subTitle, validationSchema, validationContext, defaultVa
184
184
  content: /*#__PURE__*/ jsx(Input, {
185
185
  id: "name",
186
186
  autoFocus: true,
187
- ...register("name")
187
+ ...register('name')
188
188
  }),
189
189
  labelHelpTooltip: /*#__PURE__*/ jsxs("ul", {
190
190
  children: [
@@ -200,7 +200,7 @@ const BucketCreate = ({ subTitle, validationSchema, validationContext, defaultVa
200
200
  ]
201
201
  }),
202
202
  helpErrorPosition: "bottom",
203
- error: errors.name ? errors.name?.type === "string.pattern.base" ? bucketErrorMessage : errors.name?.message : void 0
203
+ error: errors.name ? errors.name?.type === 'string.pattern.base' ? bucketErrorMessage : errors.name?.message : void 0
204
204
  }),
205
205
  children,
206
206
  /*#__PURE__*/ jsx(FormGroup, {
@@ -217,12 +217,12 @@ const BucketCreate = ({ subTitle, validationSchema, validationContext, defaultVa
217
217
  })
218
218
  ]
219
219
  }),
220
- help: isObjectLockEnabled ? "Automatically activated when Object-lock is Enabled" : void 0,
220
+ help: isObjectLockEnabled ? 'Automatically activated when Object-lock is Enabled' : void 0,
221
221
  helpErrorPosition: "bottom",
222
222
  content: /*#__PURE__*/ jsx(Checkbox, {
223
223
  id: "isVersioning",
224
224
  disabled: isObjectLockEnabled,
225
- ...register("isVersioning")
225
+ ...register('isVersioning')
226
226
  })
227
227
  })
228
228
  ]
@@ -1,7 +1,7 @@
1
- import { useNavigate } from "react-router-dom";
1
+ import { useDataBrowserNavigate } from '../../hooks/useDataBrowserNavigate';
2
2
  interface BucketDetailsContextValue {
3
3
  bucketName: string;
4
- navigate: ReturnType<typeof useNavigate>;
4
+ navigate: ReturnType<typeof useDataBrowserNavigate>;
5
5
  }
6
6
  /**
7
7
  * Context for BucketDetails component.
@@ -1,6 +1,6 @@
1
1
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
2
2
  import { createContext, memo, useCallback, useContext, useMemo } from "react";
3
- import { useNavigate, useParams } from "react-router-dom";
3
+ import { useParams } from "react-router";
4
4
  import { Tabs } from "@scality/core-ui/dist/next";
5
5
  import { useDataBrowserUICustomization } from "../../contexts/DataBrowserUICustomizationContext.js";
6
6
  import { useGetBucketLifecycle, useGetBucketReplication } from "../../hooks/bucketConfiguration.js";
@@ -12,20 +12,26 @@ import { BucketReplicationList } from "./BucketReplicationList.js";
12
12
  import { BucketVersioning } from "./BucketVersioning.js";
13
13
  import { DeleteBucketButton } from "./DeleteBucketButton.js";
14
14
  import { EmptyBucketButton } from "./EmptyBucketButton.js";
15
+ import { useDataBrowserNavigate } from "../../hooks/useDataBrowserNavigate.js";
15
16
  const BucketDetailsContext = /*#__PURE__*/ createContext(null);
16
17
  function useBucketDetailsContext() {
17
18
  const context = useContext(BucketDetailsContext);
18
- if (!context) throw new Error("BucketDetails components must be used within BucketDetails");
19
+ if (!context) throw new Error('BucketDetails components must be used within BucketDetails');
19
20
  return context;
20
21
  }
21
22
  const getEffectiveStatus = (status, error)=>{
22
- if (isNotFoundError(error)) return "success";
23
- if ("pending" === status) return "loading";
24
- if ("error" === status) return "error";
25
- return "success";
23
+ if (isNotFoundError(error)) return 'success';
24
+ if ('pending' === status) return 'loading';
25
+ if ('error' === status) return 'error';
26
+ return 'success';
26
27
  };
28
+ const ExtraSectionContent = /*#__PURE__*/ memo(({ render })=>/*#__PURE__*/ jsx(Fragment, {
29
+ children: render()
30
+ }));
31
+ ExtraSectionContent.displayName = 'BucketDetails.ExtraSectionContent';
27
32
  const OverviewTab = /*#__PURE__*/ memo(()=>{
28
33
  const { bucketName, navigate } = useBucketDetailsContext();
34
+ const { extraBucketOverviewSections } = useDataBrowserUICustomization();
29
35
  const renderDeleteButton = useCallback((name)=>/*#__PURE__*/ jsx(DeleteBucketButton, {
30
36
  bucketName: name
31
37
  }), []);
@@ -48,6 +54,12 @@ const OverviewTab = /*#__PURE__*/ memo(()=>{
48
54
  /*#__PURE__*/ jsx(BucketOverview.GeneralSection, {
49
55
  renderVersioning: renderVersioning
50
56
  }),
57
+ extraBucketOverviewSections?.map((section)=>/*#__PURE__*/ jsx(BucketOverview.Section, {
58
+ title: section.title,
59
+ children: /*#__PURE__*/ jsx(ExtraSectionContent, {
60
+ render: section.render
61
+ })
62
+ }, section.id)),
51
63
  /*#__PURE__*/ jsx(BucketOverview.DataProtectionSection, {}),
52
64
  /*#__PURE__*/ jsx(BucketOverview.PermissionsSection, {
53
65
  onEditPolicy: handleEditPolicy
@@ -57,7 +69,7 @@ const OverviewTab = /*#__PURE__*/ memo(()=>{
57
69
  ]
58
70
  });
59
71
  });
60
- OverviewTab.displayName = "BucketDetails.OverviewTab";
72
+ OverviewTab.displayName = 'BucketDetails.OverviewTab';
61
73
  const LifecycleTab = /*#__PURE__*/ memo(()=>{
62
74
  const { bucketName, navigate } = useBucketDetailsContext();
63
75
  const { data: lifecycleData, status: lifecycleStatus, error: lifecycleError } = useGetBucketLifecycle({
@@ -81,14 +93,14 @@ const LifecycleTab = /*#__PURE__*/ memo(()=>{
81
93
  onEditRule: handleEditRule
82
94
  });
83
95
  });
84
- LifecycleTab.displayName = "BucketDetails.LifecycleTab";
96
+ LifecycleTab.displayName = 'BucketDetails.LifecycleTab';
85
97
  const ReplicationTab = /*#__PURE__*/ memo(()=>{
86
98
  const { bucketName, navigate } = useBucketDetailsContext();
87
99
  const { data: replicationData, status: replicationStatus, error: replicationError } = useGetBucketReplication({
88
100
  Bucket: bucketName
89
101
  });
90
102
  const replicationRules = replicationData?.ReplicationConfiguration?.Rules || [];
91
- const replicationRole = replicationData?.ReplicationConfiguration?.Role || "";
103
+ const replicationRole = replicationData?.ReplicationConfiguration?.Role || '';
92
104
  const effectiveStatus = getEffectiveStatus(replicationStatus, replicationError);
93
105
  const handleCreateRule = useCallback(()=>navigate(BUCKET_ROUTES.replicationCreate(bucketName)), [
94
106
  navigate,
@@ -107,64 +119,64 @@ const ReplicationTab = /*#__PURE__*/ memo(()=>{
107
119
  onEditRule: handleEditRule
108
120
  });
109
121
  });
110
- ReplicationTab.displayName = "BucketDetails.ReplicationTab";
122
+ ReplicationTab.displayName = 'BucketDetails.ReplicationTab';
111
123
  const CustomTab = ({ config })=>/*#__PURE__*/ jsx(Fragment, {
112
124
  children: config.render()
113
125
  });
114
- CustomTab.displayName = "BucketDetails.CustomTab";
126
+ CustomTab.displayName = 'BucketDetails.CustomTab';
115
127
  const BucketDetailsRoot = ({ children })=>{
116
128
  const { bucketName } = useParams();
117
- const navigate = useNavigate();
118
- if (!bucketName) return /*#__PURE__*/ jsx("div", {
119
- children: "No bucket selected"
120
- });
129
+ const navigate = useDataBrowserNavigate();
121
130
  const contextValue = useMemo(()=>({
122
- bucketName,
131
+ bucketName: bucketName || '',
123
132
  navigate
124
133
  }), [
125
134
  bucketName,
126
135
  navigate
127
136
  ]);
137
+ if (!bucketName) return /*#__PURE__*/ jsx("div", {
138
+ children: "No bucket selected"
139
+ });
128
140
  return /*#__PURE__*/ jsx(BucketDetailsContext.Provider, {
129
141
  value: contextValue,
130
142
  children: children || /*#__PURE__*/ jsx(DefaultTabs, {})
131
143
  });
132
144
  };
133
- BucketDetailsRoot.displayName = "BucketDetails";
145
+ BucketDetailsRoot.displayName = 'BucketDetails';
134
146
  const DefaultTabs = ()=>{
135
147
  const { extraBucketTabs } = useDataBrowserUICustomization();
136
148
  const defaultTabsMap = useMemo(()=>({
137
149
  overview: {
138
- id: "overview",
139
- label: "Overview",
140
- path: "",
150
+ id: 'overview',
151
+ label: 'Overview',
152
+ path: '',
141
153
  withoutPadding: false,
142
154
  query: {
143
- tab: ""
155
+ tab: ''
144
156
  },
145
- type: "default",
157
+ type: 'default',
146
158
  Component: OverviewTab
147
159
  },
148
160
  lifecycle: {
149
- id: "lifecycle",
150
- label: "Lifecycle",
151
- path: "",
161
+ id: 'lifecycle',
162
+ label: 'Lifecycle',
163
+ path: '',
152
164
  withoutPadding: true,
153
165
  query: {
154
- tab: "lifecycle"
166
+ tab: 'lifecycle'
155
167
  },
156
- type: "default",
168
+ type: 'default',
157
169
  Component: LifecycleTab
158
170
  },
159
171
  replication: {
160
- id: "replication",
161
- label: "Replication",
162
- path: "",
172
+ id: 'replication',
173
+ label: 'Replication',
174
+ path: '',
163
175
  withoutPadding: true,
164
176
  query: {
165
- tab: "replication"
177
+ tab: 'replication'
166
178
  },
167
- type: "default",
179
+ type: 'default',
168
180
  Component: ReplicationTab
169
181
  }
170
182
  }), []);
@@ -172,12 +184,12 @@ const DefaultTabs = ()=>{
172
184
  const customTabConfigs = extraBucketTabs ? extraBucketTabs.map((tabConfig)=>({
173
185
  id: tabConfig.id,
174
186
  label: tabConfig.title,
175
- path: tabConfig.path || "",
187
+ path: tabConfig.path || '',
176
188
  query: {
177
189
  tab: tabConfig.id
178
190
  },
179
191
  withoutPadding: tabConfig.withoutPadding || false,
180
- type: "custom",
192
+ type: 'custom',
181
193
  config: tabConfig
182
194
  })) : [];
183
195
  const overrideIds = new Set(customTabConfigs.filter((t)=>t.id in defaultTabsMap).map((t)=>t.id));
@@ -196,13 +208,13 @@ const DefaultTabs = ()=>{
196
208
  path: tab.path,
197
209
  query: tab.query,
198
210
  withoutPadding: tab.withoutPadding,
199
- children: "default" === tab.type ? /*#__PURE__*/ jsx(tab.Component, {}) : /*#__PURE__*/ jsx(CustomTab, {
211
+ children: 'default' === tab.type ? /*#__PURE__*/ jsx(tab.Component, {}) : /*#__PURE__*/ jsx(CustomTab, {
200
212
  config: tab.config
201
213
  })
202
214
  }, tab.id))
203
215
  });
204
216
  };
205
- DefaultTabs.displayName = "BucketDetails.DefaultTabs";
217
+ DefaultTabs.displayName = 'BucketDetails.DefaultTabs';
206
218
  function BucketDetails() {
207
219
  return /*#__PURE__*/ jsx(BucketDetailsRoot, {});
208
220
  }