@scality/data-browser-library 1.0.4 → 1.0.6

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 (60) hide show
  1. package/dist/components/DataBrowserUI.js +18 -8
  2. package/dist/components/__tests__/BucketCreate.test.js +60 -20
  3. package/dist/components/__tests__/BucketList.test.js +91 -6
  4. package/dist/components/__tests__/BucketNotificationFormPage.test.js +54 -19
  5. package/dist/components/__tests__/BucketReplicationFormPage.test.js +183 -61
  6. package/dist/components/__tests__/MetadataSearch.test.js +18 -12
  7. package/dist/components/__tests__/ObjectList.test.js +94 -2
  8. package/dist/components/buckets/BucketCreate.d.ts +1 -0
  9. package/dist/components/buckets/BucketCreate.js +57 -7
  10. package/dist/components/buckets/BucketDetails.js +0 -1
  11. package/dist/components/buckets/BucketLifecycleFormPage.js +209 -213
  12. package/dist/components/buckets/BucketList.js +25 -4
  13. package/dist/components/buckets/BucketReplicationFormPage.js +9 -3
  14. package/dist/components/buckets/DeleteBucketConfigRuleButton.js +1 -1
  15. package/dist/components/buckets/notifications/BucketNotificationList.js +1 -1
  16. package/dist/components/objects/DeleteObjectButton.d.ts +1 -0
  17. package/dist/components/objects/DeleteObjectButton.js +11 -5
  18. package/dist/components/objects/ObjectDetails/FormComponents.d.ts +9 -0
  19. package/dist/components/objects/ObjectDetails/FormComponents.js +37 -0
  20. package/dist/components/objects/ObjectDetails/ObjectMetadata.js +182 -204
  21. package/dist/components/objects/ObjectDetails/ObjectSummary.js +22 -5
  22. package/dist/components/objects/ObjectDetails/ObjectTags.js +109 -154
  23. package/dist/components/objects/ObjectDetails/__tests__/ObjectDetails.test.js +3 -3
  24. package/dist/components/objects/ObjectDetails/__tests__/ObjectMetadata.test.d.ts +1 -0
  25. package/dist/components/objects/ObjectDetails/__tests__/ObjectMetadata.test.js +230 -0
  26. package/dist/components/objects/ObjectDetails/__tests__/ObjectTags.test.d.ts +1 -0
  27. package/dist/components/objects/ObjectDetails/__tests__/ObjectTags.test.js +342 -0
  28. package/dist/components/objects/ObjectDetails/__tests__/formUtils.test.d.ts +1 -0
  29. package/dist/components/objects/ObjectDetails/__tests__/formUtils.test.js +202 -0
  30. package/dist/components/objects/ObjectDetails/index.d.ts +2 -1
  31. package/dist/components/objects/ObjectDetails/index.js +12 -16
  32. package/dist/components/objects/ObjectList.d.ts +3 -2
  33. package/dist/components/objects/ObjectList.js +204 -104
  34. package/dist/components/objects/ObjectLock/__tests__/ObjectLockSettings.test.js +78 -26
  35. package/dist/components/objects/ObjectPage.js +22 -5
  36. package/dist/components/ui/ArrayFieldActions.js +0 -2
  37. package/dist/components/ui/FilterFormSection.js +17 -36
  38. package/dist/components/ui/FormGrid.d.ts +7 -0
  39. package/dist/components/ui/FormGrid.js +37 -0
  40. package/dist/components/ui/Table.elements.js +1 -0
  41. package/dist/config/__tests__/factory.test.js +29 -1
  42. package/dist/config/factory.d.ts +2 -0
  43. package/dist/config/factory.js +3 -1
  44. package/dist/config/types.d.ts +45 -2
  45. package/dist/hooks/__tests__/usePresigningS3Client.test.d.ts +1 -0
  46. package/dist/hooks/__tests__/usePresigningS3Client.test.js +104 -0
  47. package/dist/hooks/factories/index.d.ts +1 -1
  48. package/dist/hooks/factories/index.js +2 -2
  49. package/dist/hooks/factories/useCreateS3MutationHook.d.ts +2 -1
  50. package/dist/hooks/factories/useCreateS3MutationHook.js +10 -3
  51. package/dist/hooks/factories/useCreateS3QueryHook.d.ts +1 -0
  52. package/dist/hooks/factories/useCreateS3QueryHook.js +9 -6
  53. package/dist/hooks/index.d.ts +1 -0
  54. package/dist/hooks/index.js +2 -1
  55. package/dist/hooks/presignedOperations.js +4 -4
  56. package/dist/hooks/useBucketLocations.d.ts +6 -0
  57. package/dist/hooks/useBucketLocations.js +45 -0
  58. package/dist/hooks/usePresigningS3Client.d.ts +13 -0
  59. package/dist/hooks/usePresigningS3Client.js +21 -0
  60. package/package.json +4 -3
@@ -3,6 +3,7 @@ import { ConstrainedText, FormattedDateTime, Icon, Link, Wrap, spacing } from "@
3
3
  import { Box, Button, Table } from "@scality/core-ui/dist/next";
4
4
  import { Fragment, useCallback, useMemo } from "react";
5
5
  import { useDataBrowserUICustomization } from "../../contexts/DataBrowserUICustomizationContext.js";
6
+ import { useBucketLocations } from "../../hooks/index.js";
6
7
  import { BucketLocation } from "./BucketLocation.js";
7
8
  const SEARCH_QUERY_PARAM = 'search';
8
9
  const LOCATION_COLUMN_FLEX = '1.2';
@@ -30,7 +31,7 @@ const createBucketNameColumn = (onNavigateToBucket)=>({
30
31
  width: 'unset'
31
32
  }
32
33
  });
33
- const createLocationColumn = ()=>({
34
+ const createLocationColumn = (locationMap)=>({
34
35
  Header: 'Storage Location',
35
36
  accessor: 'Name',
36
37
  id: 'location',
@@ -42,6 +43,13 @@ const createLocationColumn = ()=>({
42
43
  bucketName: value
43
44
  });
44
45
  },
46
+ sortType: (rowA, rowB)=>{
47
+ const locA = locationMap.get(rowA.original.Name || '') || '';
48
+ const locB = locationMap.get(rowB.original.Name || '') || '';
49
+ return locA.localeCompare(locB, 'en', {
50
+ sensitivity: 'base'
51
+ });
52
+ },
45
53
  cellStyle: {
46
54
  width: 'unset',
47
55
  flex: LOCATION_COLUMN_FLEX
@@ -51,6 +59,14 @@ const createDateColumn = ()=>({
51
59
  Header: 'Created on',
52
60
  accessor: 'CreationDate',
53
61
  id: 'date',
62
+ sortType: (rowA, rowB)=>{
63
+ const a = rowA.original.CreationDate;
64
+ const b = rowB.original.CreationDate;
65
+ if (!a && !b) return 0;
66
+ if (!a) return -1;
67
+ if (!b) return 1;
68
+ return a.getTime() - b.getTime();
69
+ },
54
70
  cellStyle: {
55
71
  flex: '1',
56
72
  textAlign: 'right',
@@ -90,10 +106,14 @@ function createOverrideMap(customItems) {
90
106
  }
91
107
  function BucketList({ buckets, bucketStatus, selectedBucketName, onBucketSelect, onCreateBucket, onNavigateToBucket }) {
92
108
  const { extraBucketListColumns, extraBucketListActions } = useDataBrowserUICustomization();
109
+ const bucketNames = useMemo(()=>buckets.filter((b)=>b.Name).map((b)=>b.Name), [
110
+ buckets
111
+ ]);
112
+ const locationMap = useBucketLocations(bucketNames);
93
113
  const columns = useMemo(()=>{
94
114
  const defaultColumnsMap = {
95
115
  name: createBucketNameColumn(onNavigateToBucket),
96
- location: createLocationColumn(),
116
+ location: createLocationColumn(locationMap),
97
117
  date: createDateColumn()
98
118
  };
99
119
  const customColumns = (extraBucketListColumns || []).map((config)=>buildCustomColumn(config));
@@ -108,7 +128,8 @@ function BucketList({ buckets, bucketStatus, selectedBucketName, onBucketSelect,
108
128
  ];
109
129
  }, [
110
130
  onNavigateToBucket,
111
- extraBucketListColumns
131
+ extraBucketListColumns,
132
+ locationMap
112
133
  ]);
113
134
  const selectedId = useMemo(()=>{
114
135
  if (!buckets || !selectedBucketName) return;
@@ -159,7 +180,7 @@ function BucketList({ buckets, bucketStatus, selectedBucketName, onBucketSelect,
159
180
  columns: columns,
160
181
  data: buckets,
161
182
  status: bucketStatus,
162
- defaultSortingKey: "CreationDate",
183
+ defaultSortingKey: "date",
163
184
  entityName: {
164
185
  en: {
165
186
  singular: 'bucket',
@@ -7,6 +7,7 @@ import joi from "joi";
7
7
  import { useCallback, useEffect, useMemo, useRef } from "react";
8
8
  import { Controller, FormProvider, useFieldArray, useForm } from "react-hook-form";
9
9
  import { useParams } from "react-router";
10
+ import { useDataBrowserUICustomization } from "../../contexts/DataBrowserUICustomizationContext.js";
10
11
  import { useGetBucketReplication, useSetBucketReplication } from "../../hooks/bucketConfiguration.js";
11
12
  import { useBuckets } from "../../hooks/bucketOperations.js";
12
13
  import { useDataBrowserNavigate } from "../../hooks/useDataBrowserNavigate.js";
@@ -246,6 +247,7 @@ const buildReplicationRule = (data)=>{
246
247
  return rule;
247
248
  };
248
249
  function BucketReplicationFormPage() {
250
+ const { storageClassSelector: StorageClassSelector, storageClassLabel } = useDataBrowserUICustomization();
249
251
  const { bucketName, ruleId } = useParams();
250
252
  const navigate = useDataBrowserNavigate();
251
253
  const { showToast } = useToast();
@@ -664,16 +666,20 @@ function BucketReplicationFormPage() {
664
666
  })
665
667
  }),
666
668
  /*#__PURE__*/ jsx(FormGroup, {
667
- label: "Storage Class",
669
+ label: storageClassLabel || 'Storage Class',
668
670
  id: "storageClass",
669
671
  direction: "horizontal",
670
672
  error: errors?.storageClass?.message,
671
673
  helpErrorPosition: "bottom",
672
- labelHelpTooltip: "Storage class for replicated objects in destination bucket",
674
+ labelHelpTooltip: StorageClassSelector ? void 0 : 'Storage class for replicated objects in destination bucket',
673
675
  content: /*#__PURE__*/ jsx(Controller, {
674
676
  name: "storageClass",
675
677
  control: control,
676
- render: ({ field })=>/*#__PURE__*/ jsx(Select, {
678
+ render: ({ field })=>StorageClassSelector ? /*#__PURE__*/ jsx(StorageClassSelector, {
679
+ value: field.value,
680
+ onChange: field.onChange,
681
+ context: "replication"
682
+ }) : /*#__PURE__*/ jsx(Select, {
677
683
  id: "storageClass",
678
684
  value: field.value,
679
685
  onChange: field.onChange,
@@ -28,7 +28,7 @@ function DeleteBucketConfigRuleButton({ bucketName, ruleId, rules, ruleType, upd
28
28
  icon: /*#__PURE__*/ jsx(Icon, {
29
29
  name: "Delete"
30
30
  }),
31
- variant: "secondary",
31
+ variant: "danger",
32
32
  type: "button",
33
33
  onClick: (e)=>{
34
34
  e.stopPropagation();
@@ -243,7 +243,7 @@ function BucketNotificationList({ bucketName, notificationRules, notificationSta
243
243
  })
244
244
  }),
245
245
  /*#__PURE__*/ jsx(Table.SingleSelectableContent, {
246
- rowHeight: "h64",
246
+ rowHeight: "h48",
247
247
  separationLineVariant: "backgroundLevel1",
248
248
  selectedId: selectedId?.toString(),
249
249
  onRowSelected: onRowSelected
@@ -3,6 +3,7 @@ export type Objects = TableItem[];
3
3
  interface DeleteObjectButtonProps {
4
4
  objects: Objects;
5
5
  bucketName: string;
6
+ onDeleteSuccess?: () => void;
6
7
  }
7
8
  export declare const DeleteObjectButton: React.FC<DeleteObjectButtonProps>;
8
9
  export default DeleteObjectButton;
@@ -40,7 +40,7 @@ const Title = ({ objects, isCurrentSelectionPermanentlyDeleted })=>{
40
40
  ]
41
41
  });
42
42
  };
43
- const DeleteObjectButton = ({ objects, bucketName })=>{
43
+ const DeleteObjectButton = ({ objects, bucketName, onDeleteSuccess })=>{
44
44
  const [isModalOpen, setIsModalOpen] = useState(false);
45
45
  const [selectedObjects, setSelectedObjects] = useState(objects);
46
46
  const { data: versioningData } = useGetBucketVersioning({
@@ -60,7 +60,10 @@ const DeleteObjectButton = ({ objects, bucketName })=>{
60
60
  }, []);
61
61
  const cancel = useCallback(()=>{
62
62
  setIsModalOpen(false);
63
- }, []);
63
+ setSelectedObjects(objects);
64
+ }, [
65
+ objects
66
+ ]);
64
67
  const deleteSelectedFiles = useCallback(()=>{
65
68
  const objectsToDelete = selectedObjects.filter((object)=>'object' === object.type && object.Key).map((object)=>{
66
69
  const deleteItem = {
@@ -88,6 +91,7 @@ const DeleteObjectButton = ({ objects, bucketName })=>{
88
91
  status: 'success'
89
92
  });
90
93
  setIsModalOpen(false);
94
+ onDeleteSuccess?.();
91
95
  },
92
96
  onError: (error)=>{
93
97
  showToast({
@@ -102,13 +106,15 @@ const DeleteObjectButton = ({ objects, bucketName })=>{
102
106
  bucketName,
103
107
  selectedObjects,
104
108
  deleteObjects,
105
- showToast
109
+ showToast,
110
+ onDeleteSuccess
106
111
  ]);
107
112
  const totalSize = selectedObjects.reduce((acc, object)=>object.Size ? acc + object.Size : acc, 0);
108
113
  useEffect(()=>{
109
- setSelectedObjects(objects);
114
+ if (!isModalOpen) setSelectedObjects(objects);
110
115
  }, [
111
- objects
116
+ objects,
117
+ isModalOpen
112
118
  ]);
113
119
  return /*#__PURE__*/ jsxs(Fragment, {
114
120
  children: [
@@ -0,0 +1,9 @@
1
+ export { FormCell, FormColumnHeaders, FormRow } from '../../ui/FormGrid';
2
+ export declare const FormLoading: () => import("react/jsx-runtime").JSX.Element;
3
+ export declare const FormError: ({ message }: {
4
+ message: string;
5
+ }) => import("react/jsx-runtime").JSX.Element;
6
+ export declare const FormHeader: ({ disabled, isSubmitting }: {
7
+ disabled: boolean;
8
+ isSubmitting: boolean;
9
+ }) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,37 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { Icon, Loader, Text, spacing } from "@scality/core-ui";
3
+ import { Box, Button } from "@scality/core-ui/dist/next";
4
+ import { TableContainer } from "../../ui/Table.elements.js";
5
+ import { FormCell, FormColumnHeaders, FormRow } from "../../ui/FormGrid.js";
6
+ const FormLoading = ()=>/*#__PURE__*/ jsx(TableContainer, {
7
+ children: /*#__PURE__*/ jsx(Box, {
8
+ display: "flex",
9
+ justifyContent: "center",
10
+ padding: spacing.r32,
11
+ children: /*#__PURE__*/ jsx(Loader, {})
12
+ })
13
+ });
14
+ const FormError = ({ message })=>/*#__PURE__*/ jsx(TableContainer, {
15
+ children: /*#__PURE__*/ jsx(Box, {
16
+ padding: spacing.r16,
17
+ children: /*#__PURE__*/ jsx(Text, {
18
+ color: "statusCritical",
19
+ children: message
20
+ })
21
+ })
22
+ });
23
+ const FormHeader = ({ disabled, isSubmitting })=>/*#__PURE__*/ jsx(Box, {
24
+ display: "flex",
25
+ justifyContent: "flex-end",
26
+ alignItems: "center",
27
+ children: /*#__PURE__*/ jsx(Button, {
28
+ variant: "primary",
29
+ label: "Save",
30
+ disabled: disabled || isSubmitting,
31
+ type: "submit",
32
+ icon: /*#__PURE__*/ jsx(Icon, {
33
+ name: "Save"
34
+ })
35
+ })
36
+ });
37
+ export { FormCell, FormColumnHeaders, FormError, FormHeader, FormLoading, FormRow };