Bucket objects listing menu redesign (#1467)
Signed-off-by: Benjamin Perez <benjamin@bexsoft.net> Co-authored-by: Benjamin Perez <benjamin@bexsoft.net>
This commit is contained in:
@@ -25,22 +25,18 @@ const DeleteIcon = (props: SVGProps<SVGSVGElement>) => (
|
||||
viewBox="0 0 256 256"
|
||||
{...props}
|
||||
>
|
||||
<defs>
|
||||
<clipPath id="prefix__a">
|
||||
<path d="M0 0h256v256H0z" />
|
||||
</clipPath>
|
||||
</defs>
|
||||
<g clipPath="url(#prefix__a)">
|
||||
<path fill="none" d="M0 0h256v256H0z" />
|
||||
<g data-name="Grupo 1557">
|
||||
<path data-name="Rect\xE1ngulo 826" fill="none" d="M0 0h256v256H0z" />
|
||||
<path
|
||||
data-name="Uni\xF3n 10"
|
||||
d="M71.113 256a37.94 37.94 0 0 1-37.889-37.9V60.906a15.426 15.426 0 0 1-14.227-15.353V29.621a15.423 15.423 0 0 1 15.4-15.4h41.541A15.378 15.378 0 0 1 91.258.003h72.871a15.393 15.393 0 0 1 15.334 14.218h41.531a15.423 15.423 0 0 1 15.4 15.4v15.932a15.426 15.426 0 0 1-14.227 15.353V218.1a37.942 37.942 0 0 1-37.9 37.9Zm-19.605-37.9a19.634 19.634 0 0 0 19.605 19.614h113.164A19.637 19.637 0 0 0 203.89 218.1V60.951H51.507ZM218.117 38.6v-6.1h-56.893V18.278H94.177V32.5H37.286v6.1Z"
|
||||
/>
|
||||
</g>
|
||||
<g id="trash-icn" transform="translate(0 0)">
|
||||
<path
|
||||
fill={"currentcolor"}
|
||||
d="M219.6,16.2h-49.7V8.4c0-3.4-2.7-6.1-6.1-6.1H92.2c-3.4,0-6.1,2.7-6.1,6.1v7.8H36.3
|
||||
c-3.4,0-6.1,2.8-6.1,6.2V38c0,3.4,2.7,6.1,6.1,6.1h183.3c3.4,0,6.1-2.7,6.1-6.1V22.4C225.8,19,223.1,16.2,219.6,16.2
|
||||
C219.7,16.2,219.6,16.2,219.6,16.2z"
|
||||
/>
|
||||
<path
|
||||
fill={"currentcolor"}
|
||||
d="M44.2,225.5c0,15.6,12.7,28.2,28.2,28.2h111.2c15.6-0.1,28.2-12.7,28.2-28.2V58.1H44.2V225.5z"
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
);
|
||||
|
||||
export default DeleteIcon;
|
||||
|
||||
@@ -25,22 +25,20 @@ const HistoryIcon = (props: SVGProps<SVGSVGElement>) => (
|
||||
viewBox="0 0 256 256"
|
||||
{...props}
|
||||
>
|
||||
<defs>
|
||||
<clipPath id="prefix__a">
|
||||
<path d="M0 0h256v256H0z" />
|
||||
</clipPath>
|
||||
</defs>
|
||||
<g clipPath="url(#prefix__a)">
|
||||
<path fill="none" d="M0 0h256v256H0z" />
|
||||
<path data-name="Rect\xE1ngulo 872" fill="none" d="M0 0h256v256H0z" />
|
||||
<g>
|
||||
<path
|
||||
data-name="Trazado 453"
|
||||
d="m81.488 242.942-22.543-48.346a13.317 13.317 0 0 1 6.49-17.833l48.346-22.538c15.859-7.4 27.115 16.725 11.252 24.122l-18.053 8.418a80.439 80.439 0 0 0 102.75-48.094 80.444 80.444 0 0 0-48.021-102.986A80.441 80.441 0 0 0 58.723 83.71a14.88 14.88 0 0 1-19.068 8.89 14.882 14.882 0 0 1-8.9-19.072 110.238 110.238 0 0 1 141.131-65.81 110.23 110.23 0 0 1 65.809 141.131 110.193 110.193 0 0 1-139.842 66.2l7.762 16.637c4.881 10.461-3.945 18.912-12.646 18.913-4.497.005-8.96-2.252-11.481-7.657Zm75.682-93.834a3.229 3.229 0 0 1-1.561-1.045q-13.8-13.794-27.611-27.593v-.646c.063-12.9.033-25.8.039-38.708a3.459 3.459 0 0 1 .8-2.727 3.477 3.477 0 0 1 2.256-.563c1.682-.02 3.363-.044 5.055-.063a4.066 4.066 0 0 1 3.014.773 4.046 4.046 0 0 1 .811 2.911q.2 13.947-.086 27.9a14.025 14.025 0 0 0 .713 5.9 13.918 13.918 0 0 0 3.219 4.131q10.119 10.053 20.238 20.117a3.339 3.339 0 0 1 1.084 1.623 3.122 3.122 0 0 1-.855 2.3 24.648 24.648 0 0 1-4.822 4.832 3.49 3.49 0 0 1-1.975.881 1.689 1.689 0 0 1-.319-.023Z"
|
||||
fill={"currentcolor"}
|
||||
d="M145.4,20C86.3,20.1,38.3,67.6,37.5,126.6L24.8,114c-5.2-5-13.4-4.9-18.5,0.2
|
||||
c-4.9,5.1-4.9,13.2,0,18.2l37,37c5.1,5.1,13.3,5.2,18.5,0.1c0,0,0.1-0.1,0.1-0.1l37-37c4.9-5.3,4.6-13.5-0.7-18.5
|
||||
c-5-4.7-12.8-4.7-17.8,0l-13.8,13.8c0.2-43.4,35.4-78.5,78.8-78.5c43.5,0,78.8,35.3,78.8,78.8c0,43.5-35.3,78.8-78.8,78.8
|
||||
c-8.1,0-14.6,6.5-14.6,14.6s6.5,14.6,14.6,14.6c59.6-0.1,107.8-48.4,107.9-107.9C253.4,68.5,205.1,20.1,145.4,20z"
|
||||
/>
|
||||
<path
|
||||
data-name="Uni\xF3n 13 - Contorno"
|
||||
d="M92.968 251.103a12.73 12.73 0 0 1-6.744-1.879 13.836 13.836 0 0 1-5.189-6.07l-22.543-48.346a14.085 14.085 0 0 1-1.307-5.259 13.856 13.856 0 0 1 .744-5.241 13.776 13.776 0 0 1 7.295-8l48.346-22.538a14.467 14.467 0 0 1 6.129-1.44 12.56 12.56 0 0 1 8.6 3.438 15.406 15.406 0 0 1 4.545 7.953 13.39 13.39 0 0 1-.756 8.441 12.4 12.4 0 0 1-2.592 3.727 14.978 14.978 0 0 1-4.252 2.91l-16.941 7.9a79.364 79.364 0 0 0 25.85 4.331 79.721 79.721 0 0 0 23.842-3.653 80.4 80.4 0 0 0 21.525-10.468 79.546 79.546 0 0 0 17.619-16.539 79.522 79.522 0 0 0 12.121-21.871 79.941 79.941 0 0 0-47.723-102.346 79.383 79.383 0 0 0-27.23-4.821 79.7 79.7 0 0 0-23.844 3.656 80.393 80.393 0 0 0-21.527 10.471 79.581 79.581 0 0 0-17.621 16.544 79.559 79.559 0 0 0-12.121 21.876 15.272 15.272 0 0 1-5.725 7.4 15.345 15.345 0 0 1-8.729 2.719 15.342 15.342 0 0 1-5.258-.931 15.29 15.29 0 0 1-8.682-7.954 15.289 15.289 0 0 1-.516-11.759 110.23 110.23 0 0 1 16.793-30.3 110.251 110.251 0 0 1 24.412-22.917 111.367 111.367 0 0 1 29.82-14.5A110.409 110.409 0 0 1 134.336.574a110 110 0 0 1 37.721 6.677 110.98 110.98 0 0 1 20.15 9.731A109.94 109.94 0 0 1 209.5 30.145a110.736 110.736 0 0 1 14.162 16.02 111.715 111.715 0 0 1 10.766 18.3 111.8 111.8 0 0 1 7.1 20.011 110.787 110.787 0 0 1 3.168 21.146 109.933 109.933 0 0 1-1.031 21.707 111.107 111.107 0 0 1-5.5 21.691 110.2 110.2 0 0 1-16.783 30.288 110.134 110.134 0 0 1-24.4 22.9 111.325 111.325 0 0 1-29.807 14.487 110.443 110.443 0 0 1-33.014 5.056 110.035 110.035 0 0 1-35.361-5.84l7.264 15.569a12.959 12.959 0 0 1-.525 12.821 15.194 15.194 0 0 1-12.571 6.802Zm26.73-97.771a13.491 13.491 0 0 0-5.707 1.346l-48.346 22.538a12.787 12.787 0 0 0-6.771 7.418 12.867 12.867 0 0 0-.691 4.864 13.1 13.1 0 0 0 1.215 4.887l22.543 48.346a12.851 12.851 0 0 0 4.811 5.644 11.731 11.731 0 0 0 6.217 1.729 14.154 14.154 0 0 0 6.668-1.717 13.6 13.6 0 0 0 5.063-4.624 11.334 11.334 0 0 0 1.787-5.406 13.174 13.174 0 0 0-1.324-6.455l-8.264-17.713 1.121.393a109.092 109.092 0 0 0 36.146 6.168 109.439 109.439 0 0 0 32.715-5.01 110.312 110.312 0 0 0 29.539-14.357 109.081 109.081 0 0 0 24.174-22.69 109.052 109.052 0 0 0 16.631-30.013 109.874 109.874 0 0 0 5.451-21.5 108.833 108.833 0 0 0 1.023-21.509 109.579 109.579 0 0 0-3.141-20.955 110.678 110.678 0 0 0-7.035-19.832 110.7 110.7 0 0 0-10.67-18.138 109.785 109.785 0 0 0-14.033-15.875 108.977 108.977 0 0 0-17.135-13.043 110 110 0 0 0-19.971-9.643 108.984 108.984 0 0 0-37.377-6.616 109.405 109.405 0 0 0-32.729 5.018A110.407 110.407 0 0 0 72.053 20.96a109.231 109.231 0 0 0-24.187 22.709 109.145 109.145 0 0 0-16.641 30.027 14.281 14.281 0 0 0 .48 10.995 14.3 14.3 0 0 0 8.119 7.437 14.322 14.322 0 0 0 4.914.871 14.349 14.349 0 0 0 8.162-2.542 14.256 14.256 0 0 0 5.35-6.919 80.6 80.6 0 0 1 12.275-22.15 80.562 80.562 0 0 1 17.842-16.752 81.393 81.393 0 0 1 21.795-10.6 80.7 80.7 0 0 1 24.143-3.7 80.4 80.4 0 0 1 27.574 4.881 80.946 80.946 0 0 1 48.32 103.627 80.516 80.516 0 0 1-12.275 22.145 80.54 80.54 0 0 1-17.84 16.747 81.4 81.4 0 0 1-21.793 10.6 80.725 80.725 0 0 1-24.141 3.7 80.414 80.414 0 0 1-27.342-4.8l-1.141-.411 1.1-.512 18.053-8.418a13.988 13.988 0 0 0 3.969-2.713 11.409 11.409 0 0 0 2.385-3.426 12.405 12.405 0 0 0 .693-7.815 14.4 14.4 0 0 0-4.248-7.433 11.568 11.568 0 0 0-7.92-3.176Zm37.789-3.694a2.222 2.222 0 0 1-.412-.039 3.621 3.621 0 0 1-1.822-1.184l-11.055-11.048-16.555-16.543-.146-.146v-.853c.045-9.332.043-18.821.039-28V81.114a3.867 3.867 0 0 1 .977-3.107 3.924 3.924 0 0 1 2.57-.683l2.494-.031q1.28-.017 2.564-.032h.344a4.118 4.118 0 0 1 3.029.923 4.436 4.436 0 0 1 .957 3.258 800.73 800.73 0 0 1-.086 27.921 13.773 13.773 0 0 0 .672 5.692 13.532 13.532 0 0 0 3.113 3.975c6.664 6.621 13.439 13.358 19.992 19.874l.244.243a3.8 3.8 0 0 1 1.223 1.882v.006a3.536 3.536 0 0 1-.949 2.694 25.081 25.081 0 0 1-4.92 4.929 3.911 3.911 0 0 1-2.272.98Zm-28.99-29.375 16.406 16.4 11.059 11.05a2.806 2.806 0 0 0 1.3.908 1.17 1.17 0 0 0 .223.021 3.078 3.078 0 0 0 1.672-.779 24.124 24.124 0 0 0 4.725-4.734 2.72 2.72 0 0 0 .766-1.909 2.945 2.945 0 0 0-.945-1.362l-.246-.244c-6.553-6.516-13.328-13.253-19.992-19.874a14.293 14.293 0 0 1-3.326-4.288 14.5 14.5 0 0 1-.754-6.109 798.65 798.65 0 0 0 .086-27.885 3.61 3.61 0 0 0-.662-2.562 3.688 3.688 0 0 0-2.652-.629l-2.566.032-2.492.031a3.051 3.051 0 0 0-1.936.442 3.053 3.053 0 0 0-.627 2.348v10.71c0 9.178.006 18.668-.039 28Z"
|
||||
fill="rgba(0,0,0,0)"
|
||||
fill={"currentcolor"}
|
||||
d="M150.7,81.1c0.2-1.5-0.3-3-1.2-4.2c-1.3-0.9-2.9-1.3-4.4-1.1h-7.4c-1.2-0.1-2.3,0.2-3.3,0.8
|
||||
c-0.9,1.1-1.4,2.5-1.2,4c0,18.9,0,37.8,0,56.6v0.9l40.4,40.4c0.6,0.7,1.4,1.3,2.3,1.5c1.2,0.1,2.5-0.4,3.4-1.2c2.7-2,5-4.4,7-7.1
|
||||
c0.9-0.9,1.3-2.1,1.2-3.4c-0.3-0.9-0.8-1.8-1.6-2.4l-29.6-29.4c-1.9-1.7-3.5-3.7-4.7-6c-1-2.8-1.3-5.7-1-8.6
|
||||
C150.9,108.3,150.9,94.7,150.7,81.1z"
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
@@ -19,28 +19,30 @@ import { SVGProps } from "react";
|
||||
|
||||
const PreviewIcon = (props: SVGProps<SVGSVGElement>) => (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
version="1.1"
|
||||
id="Layer_1"
|
||||
className={`min-icon`}
|
||||
fill={"currentcolor"}
|
||||
viewBox="0 0 256 256"
|
||||
{...props}
|
||||
>
|
||||
<defs>
|
||||
<clipPath id="prefix__a">
|
||||
<path d="M0 0h256v256H0z" />
|
||||
</clipPath>
|
||||
</defs>
|
||||
<g clipPath="url(#prefix__a)">
|
||||
<path fill="none" d="M0 0h256v256H0z" />
|
||||
<path
|
||||
data-name="Trazado 408"
|
||||
d="M251.052 112.324A147.3 147.3 0 0 0 128 46.272 147.3 147.3 0 0 0 4.949 112.324a29.583 29.583 0 0 0 0 32.76A147.3 147.3 0 0 0 128 211.136a147.305 147.305 0 0 0 123.052-66.052 29.585 29.585 0 0 0 0-32.76Zm-17.68 21.08A126.144 126.144 0 0 1 128 189.974a126.144 126.144 0 0 1-105.371-56.57 8.487 8.487 0 0 1 0-9.4A126.144 126.144 0 0 1 128 67.434a126.145 126.145 0 0 1 105.372 56.569 8.488 8.488 0 0 1 0 9.401Z"
|
||||
/>
|
||||
<path
|
||||
data-name="Trazado 409"
|
||||
d="M128 74.274a54.492 54.492 0 0 0-54.431 54.43A54.492 54.492 0 0 0 128 183.135a54.493 54.493 0 0 0 54.431-54.431A54.493 54.493 0 0 0 128 74.274Zm0 87.7a33.305 33.305 0 0 1-33.268-33.268A33.305 33.305 0 0 1 128 95.439a33.305 33.305 0 0 1 33.263 33.265A33.305 33.305 0 0 1 128 161.972Z"
|
||||
/>
|
||||
<path data-name="Rect\xE1ngulo 859" fill="none" d="M0 0h256v256H0z" />
|
||||
<g>
|
||||
<defs>
|
||||
<rect id="SVGID_1_" x="2.6" y="47.4" width="250.4" height="161.2" />
|
||||
</defs>
|
||||
<g>
|
||||
<path
|
||||
d="M127.8,95.5c-18,0-32.5,14.6-32.5,32.5c0,18,14.6,32.5,32.5,32.5l0,0
|
||||
c18,0,32.5-14.6,32.5-32.5C160.3,110,145.8,95.5,127.8,95.5"
|
||||
fill={"currentcolor"}
|
||||
/>
|
||||
<path
|
||||
d="M248.2,112C204.1,45.5,114.5,27.4,48,71.4C31.9,82.1,18.1,95.9,7.5,112
|
||||
c-6.5,9.7-6.5,22.3,0,32c44.1,66.5,133.7,84.6,200.1,40.5c16.1-10.7,29.9-24.5,40.5-40.5C254.6,134.3,254.6,121.7,248.2,112
|
||||
M127.8,181.2c-29.4,0-53.2-23.8-53.2-53.2s23.8-53.2,53.2-53.2S181,98.6,181,128l0,0C181,157.4,157.2,181.2,127.8,181.2"
|
||||
fill={"currentcolor"}
|
||||
/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
);
|
||||
|
||||
@@ -89,8 +89,7 @@ import SearchBox from "../../../../Common/SearchBox";
|
||||
|
||||
import withSuspense from "../../../../Common/Components/withSuspense";
|
||||
import { displayName } from "./utils";
|
||||
import { DownloadIcon } from "../../../../../../icons";
|
||||
import RBIconButton from "../../../BucketDetails/SummaryItems/RBIconButton";
|
||||
import { DownloadIcon, PreviewIcon, ShareIcon } from "../../../../../../icons";
|
||||
import UploadFilesButton from "../../UploadFilesButton";
|
||||
|
||||
const AddFolderIcon = React.lazy(
|
||||
@@ -119,7 +118,6 @@ const ShareFile = withSuspense(
|
||||
React.lazy(() => import("../ObjectDetails/ShareFile"))
|
||||
);
|
||||
const RewindEnable = withSuspense(React.lazy(() => import("./RewindEnable")));
|
||||
const DeleteObject = withSuspense(React.lazy(() => import("./DeleteObject")));
|
||||
const PreviewFileModal = withSuspense(
|
||||
React.lazy(() => import("../Preview/PreviewFileModal"))
|
||||
);
|
||||
@@ -140,8 +138,11 @@ const styles = (theme: Theme) =>
|
||||
|
||||
badgeOverlap: {
|
||||
"& .MuiBadge-badge": {
|
||||
top: 35,
|
||||
right: 10,
|
||||
top: 10,
|
||||
right: 1,
|
||||
width: 5,
|
||||
height: 5,
|
||||
minWidth: 5
|
||||
},
|
||||
},
|
||||
screenTitle: {
|
||||
@@ -233,7 +234,6 @@ const ListObjects = ({
|
||||
classes,
|
||||
match,
|
||||
history,
|
||||
downloadingFiles,
|
||||
rewindEnabled,
|
||||
rewindDate,
|
||||
bucketToRewind,
|
||||
@@ -254,10 +254,8 @@ const ListObjects = ({
|
||||
const [loading, setLoading] = useState<boolean>(true);
|
||||
const [rewind, setRewind] = useState<RewindObject[]>([]);
|
||||
const [loadingRewind, setLoadingRewind] = useState<boolean>(false);
|
||||
const [deleteOpen, setDeleteOpen] = useState<boolean>(false);
|
||||
const [deleteMultipleOpen, setDeleteMultipleOpen] = useState<boolean>(false);
|
||||
const [createFolderOpen, setCreateFolderOpen] = useState<boolean>(false);
|
||||
const [selectedObject, setSelectedObject] = useState<string>("");
|
||||
const [filterObjects, setFilterObjects] = useState<string>("");
|
||||
const [loadingStartTime, setLoadingStartTime] = useState<number>(0);
|
||||
const [loadingMessage, setLoadingMessage] =
|
||||
@@ -276,6 +274,8 @@ const ListObjects = ({
|
||||
>("ASC");
|
||||
const [currentSortField, setCurrentSortField] = useState<string>("name");
|
||||
const [iniLoad, setIniLoad] = useState<boolean>(false);
|
||||
const [canShareFile, setCanShareFile] = useState<boolean>(false);
|
||||
const [canPreviewFile, setCanPreviewFile] = useState<boolean>(false);
|
||||
|
||||
const internalPaths = get(match.params, "subpaths", "");
|
||||
const bucketName = match.params["bucketName"];
|
||||
@@ -290,6 +290,27 @@ const ListObjects = ({
|
||||
}
|
||||
}, [folderUpload]);
|
||||
|
||||
useEffect(() => {
|
||||
if (selectedObjects.length === 1) {
|
||||
const objectName = selectedObjects[0];
|
||||
|
||||
if (extensionPreview(objectName) !== "none") {
|
||||
setCanPreviewFile(true);
|
||||
} else {
|
||||
setCanPreviewFile(false);
|
||||
}
|
||||
|
||||
if (objectName.endsWith("/")) {
|
||||
setCanShareFile(false);
|
||||
} else {
|
||||
setCanShareFile(true);
|
||||
}
|
||||
} else {
|
||||
setCanShareFile(false);
|
||||
setCanPreviewFile(false);
|
||||
}
|
||||
}, [selectedObjects]);
|
||||
|
||||
const displayDeleteObject = hasPermission(bucketName, [
|
||||
IAM_SCOPES.S3_DELETE_OBJECT,
|
||||
]);
|
||||
@@ -575,15 +596,6 @@ const ListObjects = ({
|
||||
setErrorSnackMessage,
|
||||
]);
|
||||
|
||||
const closeDeleteModalAndRefresh = (refresh: boolean) => {
|
||||
setDeleteOpen(false);
|
||||
|
||||
if (refresh) {
|
||||
setSnackBarMessage(`Object '${selectedObject}' deleted successfully.`);
|
||||
setLoading(true);
|
||||
}
|
||||
};
|
||||
|
||||
const closeDeleteMultipleModalAndRefresh = (refresh: boolean) => {
|
||||
setDeleteMultipleOpen(false);
|
||||
|
||||
@@ -630,11 +642,6 @@ const ListObjects = ({
|
||||
return niceBytes(String(object.size));
|
||||
};
|
||||
|
||||
const confirmDeleteObject = (object: BucketObject) => {
|
||||
setDeleteOpen(true);
|
||||
setSelectedObject(object.name);
|
||||
};
|
||||
|
||||
const displayDeleteFlag = (state: boolean) => {
|
||||
return state ? "Yes" : "No";
|
||||
};
|
||||
@@ -856,14 +863,36 @@ const ListObjects = ({
|
||||
[isDragActive, isDragAccept]
|
||||
);
|
||||
|
||||
const openPreview = (fileObject: BucketObject) => {
|
||||
setSelectedPreview(fileObject);
|
||||
setPreviewOpen(true);
|
||||
const openPreview = () => {
|
||||
if (selectedObjects.length === 1) {
|
||||
let fileObject: BucketObject | undefined;
|
||||
|
||||
const findFunction = (currValue: BucketObject | RewindObject) =>
|
||||
selectedObjects.includes(currValue.name);
|
||||
|
||||
fileObject = filteredRecords.find(findFunction);
|
||||
|
||||
if (fileObject) {
|
||||
setSelectedPreview(fileObject);
|
||||
setPreviewOpen(true);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const openShare = (fileObject: BucketObject) => {
|
||||
setSelectedPreview(fileObject);
|
||||
setShareFileModalOpen(true);
|
||||
const openShare = () => {
|
||||
if (selectedObjects.length === 1) {
|
||||
let fileObject: BucketObject | undefined;
|
||||
|
||||
const findFunction = (currValue: BucketObject | RewindObject) =>
|
||||
selectedObjects.includes(currValue.name);
|
||||
|
||||
fileObject = filteredRecords.find(findFunction);
|
||||
|
||||
if (fileObject) {
|
||||
setSelectedPreview(fileObject);
|
||||
setShareFileModalOpen(true);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const closeShareModal = () => {
|
||||
@@ -878,50 +907,8 @@ const ListObjects = ({
|
||||
onClick: openPath,
|
||||
sendOnlyId: true,
|
||||
},
|
||||
{
|
||||
type: "preview",
|
||||
label: "Preview",
|
||||
onClick: openPreview,
|
||||
disableButtonFunction: (item: string) =>
|
||||
extensionPreview(item) === "none",
|
||||
},
|
||||
{
|
||||
type: "share",
|
||||
label: "Share",
|
||||
onClick: openShare,
|
||||
disableButtonFunction: (item: string) => item.endsWith("/"),
|
||||
},
|
||||
{
|
||||
type: "download",
|
||||
label: "Download",
|
||||
onClick: downloadObject,
|
||||
showLoaderFunction: (item: string) =>
|
||||
downloadingFiles.includes(`${match.params["bucket"]}/${item}`),
|
||||
disableButtonFunction: (item: string) => {
|
||||
if (rewindEnabled) {
|
||||
const element = rewind.find((elm) => elm.name === item);
|
||||
|
||||
if (element && element.delete_flag) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
},
|
||||
sendOnlyId: false,
|
||||
},
|
||||
];
|
||||
|
||||
if (displayDeleteObject) {
|
||||
tableActions.push({
|
||||
type: "delete",
|
||||
label: "Delete",
|
||||
onClick: confirmDeleteObject,
|
||||
disableButtonFunction: () => {
|
||||
return rewindEnabled;
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
const filteredRecords = records.filter((b: BucketObject) => {
|
||||
if (filterObjects === "") {
|
||||
return true;
|
||||
@@ -1089,15 +1076,6 @@ const ListObjects = ({
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
{deleteOpen && (
|
||||
<DeleteObject
|
||||
deleteOpen={deleteOpen}
|
||||
selectedBucket={bucketName}
|
||||
selectedObject={encodeFileName(selectedObject)}
|
||||
closeDeleteModalAndRefresh={closeDeleteModalAndRefresh}
|
||||
versioning={isVersioned}
|
||||
/>
|
||||
)}
|
||||
{deleteMultipleOpen && (
|
||||
<DeleteMultipleObjects
|
||||
deleteOpen={deleteMultipleOpen}
|
||||
@@ -1173,7 +1151,6 @@ const ListObjects = ({
|
||||
closeMenu();
|
||||
}}
|
||||
/>
|
||||
|
||||
<input
|
||||
type="file"
|
||||
multiple
|
||||
@@ -1206,97 +1183,6 @@ const ListObjects = ({
|
||||
overrideClass={classes.searchField}
|
||||
/>
|
||||
</SecureComponent>
|
||||
<div>
|
||||
<SecureComponent
|
||||
scopes={[IAM_SCOPES.S3_DELETE_OBJECT]}
|
||||
resource={bucketName}
|
||||
errorProps={{ disabled: true }}
|
||||
>
|
||||
<RBIconButton
|
||||
tooltip={"Delete Selected"}
|
||||
onClick={() => {
|
||||
setDeleteMultipleOpen(true);
|
||||
}}
|
||||
text={"Delete Selected"}
|
||||
icon={<DeleteIcon />}
|
||||
color="secondary"
|
||||
disabled={selectedObjects.length === 0}
|
||||
variant={"outlined"}
|
||||
/>
|
||||
</SecureComponent>
|
||||
<RBIconButton
|
||||
tooltip={"Download Selected"}
|
||||
onClick={downloadSelected}
|
||||
text={"Download Selected"}
|
||||
icon={<DownloadIcon />}
|
||||
color="primary"
|
||||
disabled={selectedObjects.length === 0}
|
||||
variant={"contained"}
|
||||
/>
|
||||
</div>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<Fragment>
|
||||
<SecureComponent
|
||||
resource={bucketName}
|
||||
scopes={[IAM_SCOPES.S3_PUT_OBJECT]}
|
||||
errorProps={{ disabled: true }}
|
||||
>
|
||||
<RBIconButton
|
||||
tooltip={"Choose or create a new path"}
|
||||
onClick={() => {
|
||||
setCreateFolderOpen(true);
|
||||
}}
|
||||
text={""}
|
||||
icon={<AddFolderIcon />}
|
||||
color="primary"
|
||||
disabled={rewindEnabled}
|
||||
variant={"outlined"}
|
||||
/>
|
||||
</SecureComponent>
|
||||
<SecureComponent
|
||||
resource={bucketName}
|
||||
scopes={[IAM_SCOPES.S3_PUT_OBJECT]}
|
||||
errorProps={{ disabled: true }}
|
||||
>
|
||||
<Badge
|
||||
badgeContent=" "
|
||||
color="secondary"
|
||||
variant="dot"
|
||||
invisible={!rewindEnabled}
|
||||
className={classes.badgeOverlap}
|
||||
>
|
||||
<RBIconButton
|
||||
tooltip={"Rewind"}
|
||||
onClick={() => {
|
||||
setRewindSelect(true);
|
||||
}}
|
||||
text={""}
|
||||
icon={<HistoryIcon />}
|
||||
color="primary"
|
||||
disabled={!isVersioned}
|
||||
variant={"outlined"}
|
||||
/>
|
||||
</Badge>
|
||||
</SecureComponent>
|
||||
<SecureComponent
|
||||
scopes={[IAM_SCOPES.S3_LIST_BUCKET]}
|
||||
resource={bucketName}
|
||||
errorProps={{ disabled: true }}
|
||||
>
|
||||
<RBIconButton
|
||||
tooltip={"Refresh list"}
|
||||
onClick={() => {
|
||||
setLoading(true);
|
||||
}}
|
||||
text={""}
|
||||
icon={<RefreshIcon />}
|
||||
color="primary"
|
||||
disabled={rewindEnabled}
|
||||
variant={"contained"}
|
||||
/>
|
||||
</SecureComponent>
|
||||
</Fragment>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<br />
|
||||
@@ -1332,6 +1218,88 @@ const ListObjects = ({
|
||||
triggerSort: sortChange,
|
||||
}}
|
||||
onSelectAll={selectAllItems}
|
||||
actionButtons={[
|
||||
{
|
||||
action: downloadSelected,
|
||||
label: "Download",
|
||||
disabled: selectedObjects.length === 0,
|
||||
icon: <DownloadIcon />,
|
||||
tooltip: "Download Selected",
|
||||
},
|
||||
{
|
||||
action: openShare,
|
||||
label: "Share",
|
||||
disabled: selectedObjects.length !== 1 || !canShareFile,
|
||||
icon: <ShareIcon />,
|
||||
tooltip: "Share Selected File",
|
||||
},
|
||||
{
|
||||
action: openPreview,
|
||||
label: "Preview",
|
||||
disabled: selectedObjects.length !== 1 || !canPreviewFile,
|
||||
icon: <PreviewIcon />,
|
||||
tooltip: "Preview Selected File",
|
||||
},
|
||||
{
|
||||
action: () => {
|
||||
setDeleteMultipleOpen(true);
|
||||
},
|
||||
label: "Delete",
|
||||
icon: <DeleteIcon />,
|
||||
disabled:
|
||||
!hasPermission(bucketName, [
|
||||
IAM_SCOPES.S3_DELETE_OBJECT,
|
||||
]) ||
|
||||
selectedObjects.length === 0 ||
|
||||
!displayDeleteObject,
|
||||
tooltip: "Delete Selected Files",
|
||||
},
|
||||
{
|
||||
action: () => {
|
||||
setRewindSelect(true);
|
||||
},
|
||||
label: "Rewind",
|
||||
disabled:
|
||||
!isVersioned ||
|
||||
!hasPermission(bucketName, [IAM_SCOPES.S3_PUT_OBJECT]),
|
||||
icon: (
|
||||
<Badge
|
||||
badgeContent=" "
|
||||
color="secondary"
|
||||
variant="dot"
|
||||
invisible={!rewindEnabled}
|
||||
className={classes.badgeOverlap}
|
||||
>
|
||||
<HistoryIcon />
|
||||
</Badge>
|
||||
),
|
||||
tooltip: "Rewind Bucket",
|
||||
},
|
||||
{
|
||||
action: () => {
|
||||
setCreateFolderOpen(true);
|
||||
},
|
||||
label: "New Path",
|
||||
icon: <AddFolderIcon />,
|
||||
disabled:
|
||||
rewindEnabled ||
|
||||
!hasPermission(bucketName, [IAM_SCOPES.S3_PUT_OBJECT]),
|
||||
tooltip: "Choose or create a new path",
|
||||
},
|
||||
]}
|
||||
globalActions={[
|
||||
{
|
||||
action: () => {
|
||||
setLoading(true);
|
||||
},
|
||||
label: "Reload",
|
||||
icon: <RefreshIcon />,
|
||||
disabled:
|
||||
!hasPermission(bucketName, [IAM_SCOPES.S3_LIST_BUCKET]) ||
|
||||
rewindEnabled,
|
||||
tooltip: "Reload List",
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</SecureComponent>
|
||||
</Grid>
|
||||
|
||||
@@ -34,6 +34,7 @@ interface IUploadFilesButton {
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
listUploadIcons: {
|
||||
height: 20,
|
||||
"& .min-icon": {
|
||||
width: 18,
|
||||
fill: "rgba(0,0,0,0.87)",
|
||||
|
||||
@@ -34,6 +34,7 @@ import ArrowDropDownIcon from "@mui/icons-material/ArrowDropDown";
|
||||
import ArrowDropUpIcon from "@mui/icons-material/ArrowDropUp";
|
||||
import TableActionButton from "./TableActionButton";
|
||||
import CheckboxWrapper from "../FormComponents/CheckboxWrapper/CheckboxWrapper";
|
||||
import TopActionButton from "./TopActionButton";
|
||||
import history from "../../../../history";
|
||||
import {
|
||||
checkboxIcons,
|
||||
@@ -81,6 +82,14 @@ interface ISortConfig {
|
||||
currentDirection: "ASC" | "DESC" | undefined;
|
||||
}
|
||||
|
||||
interface IActionButton {
|
||||
label: string;
|
||||
icon?: React.ReactNode;
|
||||
action: () => void;
|
||||
disabled: boolean;
|
||||
tooltip?: string;
|
||||
}
|
||||
|
||||
interface TableWrapperProps {
|
||||
itemActions?: ItemActions[] | null;
|
||||
columns: IColumns[];
|
||||
@@ -110,6 +119,10 @@ interface TableWrapperProps {
|
||||
}: {
|
||||
index: number;
|
||||
}) => "deleted" | "" | React.CSSProperties;
|
||||
generalTableActions?: () => void;
|
||||
actionButtons?: IActionButton[];
|
||||
subActions?: React.ReactNode;
|
||||
globalActions?: IActionButton[];
|
||||
}
|
||||
|
||||
const borderColor = "#9c9c9c80";
|
||||
@@ -128,9 +141,19 @@ const styles = () =>
|
||||
overflowY: "scroll",
|
||||
position: "relative",
|
||||
"&::-webkit-scrollbar": {
|
||||
width: 3,
|
||||
width: 0,
|
||||
height: 3,
|
||||
},
|
||||
"&.actionsBar": {
|
||||
padding: "45px 16px 8px",
|
||||
},
|
||||
},
|
||||
topHelpers: {
|
||||
position: "absolute",
|
||||
top: 0,
|
||||
left: 0,
|
||||
backgroundColor: "#F8F8F8",
|
||||
borderBottom: "#EAEDEE 1px solid",
|
||||
},
|
||||
noBackground: {
|
||||
backgroundColor: "transparent",
|
||||
@@ -167,6 +190,59 @@ const styles = () =>
|
||||
checkAllWrapper: {
|
||||
marginTop: -16,
|
||||
},
|
||||
actionsScrollable: {
|
||||
display: "flex",
|
||||
overflowX: "auto",
|
||||
overflowY: "hidden",
|
||||
height: 36,
|
||||
alignItems: "center",
|
||||
"&::-webkit-scrollbar": {
|
||||
height: 2,
|
||||
minHeight: 2,
|
||||
borderRadius: 0,
|
||||
},
|
||||
"&::-webkit-scrollbar-track": {
|
||||
background: "#F0F0F0",
|
||||
borderRadius: 0,
|
||||
boxShadow: "inset 0px 0px 0px 0px transparent",
|
||||
height: 2,
|
||||
},
|
||||
"&::-webkit-scrollbar-thumb": {
|
||||
background: "#5E5E5E",
|
||||
borderRadius: 0,
|
||||
},
|
||||
"&::-webkit-scrollbar-thumb:hover": {
|
||||
background: "#4C4C4C",
|
||||
},
|
||||
},
|
||||
objectsSelected: {
|
||||
display: "flex",
|
||||
flexGrow: 0,
|
||||
whiteSpace: "nowrap",
|
||||
backgroundColor: "#F4F2F2",
|
||||
color: "#000",
|
||||
fontWeight: "bold",
|
||||
fontSize: 14,
|
||||
height: 37,
|
||||
maxHeight: 37,
|
||||
padding: "0 25px",
|
||||
alignItems: "center",
|
||||
position: "relative",
|
||||
"&::after": {
|
||||
content: "' '",
|
||||
borderRight: "#eaeaea 1px solid",
|
||||
width: 1,
|
||||
height: 22,
|
||||
display: "block",
|
||||
position: "absolute",
|
||||
right: 0,
|
||||
},
|
||||
},
|
||||
globalActions: {
|
||||
display: "flex",
|
||||
flexGrow: 0,
|
||||
justifyContent: "flex-end",
|
||||
},
|
||||
"@global": {
|
||||
".rowLine": {
|
||||
borderBottom: `1px solid ${borderColor}`,
|
||||
@@ -465,6 +541,9 @@ const TableWrapper = ({
|
||||
disabled = false,
|
||||
onSelectAll,
|
||||
rowStyle,
|
||||
actionButtons,
|
||||
subActions,
|
||||
globalActions,
|
||||
}: TableWrapperProps) => {
|
||||
const [columnSelectorOpen, setColumnSelectorOpen] = useState<boolean>(false);
|
||||
const [anchorEl, setAnchorEl] = React.useState<any>(null);
|
||||
@@ -563,6 +642,10 @@ const TableWrapper = ({
|
||||
customPaperHeight !== ""
|
||||
? customPaperHeight
|
||||
: classes.defaultPaperHeight
|
||||
} ${
|
||||
onSelect || actionButtons || subActions || globalActions
|
||||
? "actionsBar"
|
||||
: ""
|
||||
}`}
|
||||
>
|
||||
{isLoading && (
|
||||
@@ -575,6 +658,71 @@ const TableWrapper = ({
|
||||
</Grid>
|
||||
</Grid>
|
||||
)}
|
||||
{!isLoading && (
|
||||
<Fragment>
|
||||
<Grid
|
||||
container
|
||||
direction={"row"}
|
||||
alignItems={"center"}
|
||||
flexGrow={"1"}
|
||||
className={classes.topHelpers}
|
||||
>
|
||||
{onSelect && (
|
||||
<Grid item xs className={classes.objectsSelected}>
|
||||
{selectedItems?.length || 0} Objects selected
|
||||
</Grid>
|
||||
)}
|
||||
{actionButtons && (
|
||||
<Grid
|
||||
item
|
||||
xs
|
||||
className={classes.actionsScrollable}
|
||||
flexWrap={"nowrap"}
|
||||
>
|
||||
{actionButtons.map((button, index) => {
|
||||
return (
|
||||
<TopActionButton
|
||||
variant={"text"}
|
||||
onClick={button.action}
|
||||
disabled={button.disabled}
|
||||
id={`button-option-${button.label}`}
|
||||
key={`tableActon-${index.toString()}`}
|
||||
startIcon={button.icon}
|
||||
tooltip={button.tooltip}
|
||||
>
|
||||
{button.label}
|
||||
</TopActionButton>
|
||||
);
|
||||
})}
|
||||
</Grid>
|
||||
)}
|
||||
{subActions && (
|
||||
<Grid item xs>
|
||||
{subActions}
|
||||
</Grid>
|
||||
)}
|
||||
{globalActions && (
|
||||
<Grid item xs className={classes.globalActions}>
|
||||
{globalActions.map((button, index) => {
|
||||
return (
|
||||
<TopActionButton
|
||||
variant={"contained"}
|
||||
onClick={button.action}
|
||||
disabled={button.disabled}
|
||||
id={`button-option-${button.label}`}
|
||||
key={`tableActon-${index.toString()}`}
|
||||
endIcon={button.icon}
|
||||
tooltip={button.tooltip}
|
||||
>
|
||||
{button.label}
|
||||
</TopActionButton>
|
||||
);
|
||||
})}
|
||||
</Grid>
|
||||
)}
|
||||
</Grid>
|
||||
</Fragment>
|
||||
)}
|
||||
{columnsSelector && !isLoading && records.length > 0 && (
|
||||
<div className={classes.overlayColumnSelection}>
|
||||
{columnsSelection(columns)}
|
||||
|
||||
@@ -0,0 +1,132 @@
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2022 MinIO, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React from "react";
|
||||
import { Theme } from "@mui/material/styles";
|
||||
import createStyles from "@mui/styles/createStyles";
|
||||
import withStyles from "@mui/styles/withStyles";
|
||||
import { Button, ButtonProps, Tooltip } from "@mui/material";
|
||||
import clsx from "clsx";
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
root: {
|
||||
padding: "0 15px",
|
||||
height: 22,
|
||||
margin: 0,
|
||||
color: "#5E5E5E",
|
||||
fontWeight: "normal",
|
||||
fontSize: 14,
|
||||
borderRight: "#E5E5E5 1px solid",
|
||||
borderStyle: "solid",
|
||||
borderRadius: 0,
|
||||
"&:hover": {
|
||||
backgroundColor: "transparent",
|
||||
color: "#000",
|
||||
},
|
||||
"& .min-icon": {
|
||||
width: 11,
|
||||
},
|
||||
"&:disabled": {
|
||||
color: "#EBEBEB",
|
||||
borderColor: "#EBEBEB",
|
||||
},
|
||||
"&": {
|
||||
"@media (max-width: 1279px)": {
|
||||
padding: 0,
|
||||
display: "flex",
|
||||
justifyContent: "center",
|
||||
"& .min-icon": {
|
||||
width: 15,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
contained: {
|
||||
borderColor: "#5E5E5E",
|
||||
background: "#5E5E5E",
|
||||
color: "white",
|
||||
borderRadius: 0,
|
||||
height: 37,
|
||||
fontWeight: "bold",
|
||||
padding: "15px 25px",
|
||||
"& .MuiTouchRipple-root span": {
|
||||
backgroundColor: "#4c4c4c",
|
||||
borderRadius: 3,
|
||||
opacity: 0.3,
|
||||
},
|
||||
"&:hover": {
|
||||
backgroundColor: "#4c4c4c",
|
||||
color: "#FFF",
|
||||
},
|
||||
"& .min-icon": {
|
||||
width: 12,
|
||||
marginTop: -3,
|
||||
},
|
||||
"&": {
|
||||
"@media (max-width: 1279px)": {
|
||||
padding: 0,
|
||||
display: "flex",
|
||||
justifyContent: "center",
|
||||
"& .min-icon": {
|
||||
width: 15,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
interface ITopActionButton extends ButtonProps {
|
||||
classes: any;
|
||||
children: any;
|
||||
variant?: "text" | "contained";
|
||||
tooltip?: string;
|
||||
}
|
||||
|
||||
const TopActionButton = ({
|
||||
classes,
|
||||
children,
|
||||
variant = "text",
|
||||
tooltip,
|
||||
...rest
|
||||
}: ITopActionButton) => {
|
||||
return (
|
||||
<Tooltip title={tooltip || ""}>
|
||||
<Button
|
||||
{...rest}
|
||||
className={clsx(classes.root, {
|
||||
[classes.contained]: variant === "contained",
|
||||
})}
|
||||
sx={{
|
||||
"& span.buttonItem": {
|
||||
"@media (max-width: 1279px)": {
|
||||
display: "none",
|
||||
},
|
||||
},
|
||||
"& span": {
|
||||
"@media (max-width: 1279px)": {
|
||||
margin: 0,
|
||||
},
|
||||
},
|
||||
}}
|
||||
>
|
||||
<span className={"buttonItem"}>{children}</span>
|
||||
</Button>
|
||||
</Tooltip>
|
||||
);
|
||||
};
|
||||
|
||||
export default withStyles(styles)(TopActionButton);
|
||||
Reference in New Issue
Block a user