Changed breadcrumbs styles (#1610)
- Added onKey press support to input boxes - Added enter key support to create path modal - Replaced bucket icon Signed-off-by: Benjamin Perez <benjamin@bexsoft.net>
This commit is contained in:
37
portal-ui/src/icons/BackCaretIcon.tsx
Normal file
37
portal-ui/src/icons/BackCaretIcon.tsx
Normal file
@@ -0,0 +1,37 @@
|
||||
// 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 * as React from "react";
|
||||
import { SVGProps } from "react";
|
||||
|
||||
const BackCaretIcon = (props: SVGProps<SVGSVGElement>) => (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
className={`min-icon`}
|
||||
fill={"currentcolor"}
|
||||
viewBox="0 0 256 256"
|
||||
{...props}
|
||||
>
|
||||
<g id="noun_chevron_2320228" transform="translate(5.595 10) rotate(180)">
|
||||
<path id="Path_6842" d="M-178.01,7.8c-3.9-0.03-7.62-1.63-10.34-4.43c-5.81-5.68-5.92-15-0.25-20.81
|
||||
c0.08-0.08,0.16-0.16,0.25-0.25l100.13-100.13l-100.13-100.48c-5.81-5.68-5.92-15-0.25-20.81c0.08-0.08,0.16-0.16,0.25-0.25
|
||||
c5.68-5.81,15-5.92,20.81-0.25c0.08,0.08,0.16,0.16,0.25,0.25l110.82,110.82c2.8,2.72,4.39,6.44,4.43,10.34
|
||||
c0.11,3.93-1.51,7.71-4.43,10.34L-167.29,2.99C-170.07,5.97-173.93,7.71-178.01,7.8z"/>
|
||||
</g>
|
||||
</svg>
|
||||
);
|
||||
|
||||
export default BackCaretIcon;
|
||||
@@ -25,19 +25,12 @@ const BucketsIcon = (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 884" fill="none" d="M0 0h256v256H0z" />
|
||||
<g>
|
||||
<path
|
||||
data-name="buckets-icn"
|
||||
d="m244.998 90.474.049-.243 10.563-61.472a25.8 25.8 0 0 0-4.748-19.986A21.518 21.518 0 0 0 233.739 0H22.255A21.507 21.507 0 0 0 5.138 8.773 25.862 25.862 0 0 0 .384 28.759c5.223 30.384 16.209 94.421 25 145.533l.014.1c4.457 26 8.338 48.644 10.617 61.787 1.965 11.487 11.148 19.819 21.854 19.819h140.264c10.713 0 19.875-8.332 21.861-19.819l10.592-61.711.076-.375Zm-203.928 72.5c-3.6-20.981-7.479-43.648-11.148-65.015H226.09l-11.168 65.015Zm197.482-137.7-9.2 53.735h-202.7c-3.7-21.626-7-40.758-9.221-53.735a5.736 5.736 0 0 1 1.041-4.394 4.738 4.738 0 0 1 3.764-1.934h211.5a4.732 4.732 0 0 1 3.775 1.939 5.691 5.691 0 0 1 1.042 4.387Zm-26.893 156.649-8.709 50.763a5.048 5.048 0 0 1-4.824 4.37H57.862a5.047 5.047 0 0 1-4.816-4.361c-1.93-11.25-5.066-29.464-8.717-50.771Z"
|
||||
stroke="#000"
|
||||
strokeWidth={0.2}
|
||||
d="M244.1,8.4c-3.9-5.3-10.1-8.5-16.7-8.5H21.6C15,0,8.8,3.1,4.9,8.4C0.8,14-0.9,21,0.3,27.9
|
||||
c5.1,29.6,15.8,91.9,24.3,141.7v0.1C29,195,32.8,217.1,35,229.9c1.4,10.8,10.4,18.9,21.3,19.3h136.5
|
||||
c10.9-0.4,19.9-8.5,21.3-19.3l10.3-60.1l0.1-0.4L238.4,88v-0.2l10.3-59.9C249.9,21,248.3,14,244.1,8.4 M206.1,177h-163
|
||||
l-3.2-18.6h169.3L206.1,177z M220,95.3H28.9l-3.2-18.6h197.4L220,95.3z"
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2021 MinIO, Inc.
|
||||
// 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
|
||||
@@ -25,17 +25,11 @@ const FolderIcon = (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="folder-icn{">
|
||||
<path d="M101.729 42.952c6.612 0 13.7 18.758 20.78 18.758h88.049a9.441 9.441 0 0 1 9.444 9.379v4.689H40.349V52.33h-.236a9.441 9.441 0 0 1 9.448-9.378h52.168m124.4 44.255a9.778 9.778 0 0 1 9.774 9.725L225.885 204.09a9.788 9.788 0 0 1-9.794 9.716H39.679a9.781 9.781 0 0 1-9.786-9.716l-9.79-107.158a9.781 9.781 0 0 1 9.79-9.725h196.236M101.729 23H49.561a29.469 29.469 0 0 0-29.544 29.33 20.109 20.109 0 0 0 .236 3.063v13.438A29.758 29.758 0 0 0 0 96.931c0 .6.031 1.2.09 1.8l9.723 106.5a29.827 29.827 0 0 0 29.862 28.532h176.412a29.833 29.833 0 0 0 29.862-28.5l9.959-106.484a17.091 17.091 0 0 0 .091-1.847 29.673 29.673 0 0 0-15.911-26.229 29.477 29.477 0 0 0-29.532-28.949h-81.5c-.4-.529-.787-1.05-1.117-1.5-5.1-6.87-12.815-17.248-26.208-17.248Z" />
|
||||
<path data-name="Rect\xE1ngulo 874" fill="none" d="M0 0h256v256H0z" />
|
||||
</g>
|
||||
<g>
|
||||
<path d="M235.3,72.5c-0.2-15.5-12.8-27.9-28.3-27.9h-78l-1.1-1.5c-5.1-9.3-14.5-15.5-25.1-16.6h-50c-15.6,0-28.3,12.6-28.3,28.3
|
||||
c0,1,0.1,2,0.2,3v12.9c-11.6,3.9-19.4,14.8-19.4,27c0,0.6,0,1.2,0.1,1.7L14.8,202c0.6,15.4,13.2,27.5,28.6,27.5h168.9
|
||||
c15.4,0,28-12.1,28.6-27.5l9.5-102.5c0-0.6,0.1-1.2,0.1-1.8C250.6,87.1,244.7,77.4,235.3,72.5z M32.5,88.4c11.7-3.3,12-11,12-11
|
||||
h172c0.2,4.6,2.9,8.8,6.9,11H32.5z"/>
|
||||
</g>
|
||||
</svg>
|
||||
);
|
||||
|
||||
@@ -166,3 +166,4 @@ export { default as ConsoleIcon } from "./ConsoleIcon";
|
||||
export { default as FileVideoIcon } from "./FileVideoIcon";
|
||||
export { default as ChangePasswordIcon } from "./ChangePasswordIcon";
|
||||
export { default as LockIcon } from "./LockIcon";
|
||||
export { default as BackCaretIcon } from "./BackCaretIcon";
|
||||
|
||||
@@ -102,6 +102,16 @@ const CreateFolderModal = ({
|
||||
setIsFormValid(valid);
|
||||
}, [pathUrl]);
|
||||
|
||||
const inputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setPathUrl(e.target.value);
|
||||
};
|
||||
|
||||
const keyPressed = (e: any) => {
|
||||
if(e.code === "Enter" && pathUrl !== "") {
|
||||
createProcess();
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
<ModalWrapper
|
||||
@@ -121,9 +131,8 @@ const CreateFolderModal = ({
|
||||
id={"folderPath"}
|
||||
name={"folderPath"}
|
||||
placeholder={"Enter the new Folder Path"}
|
||||
onChange={(e) => {
|
||||
setPathUrl(e.target.value);
|
||||
}}
|
||||
onChange={inputChange}
|
||||
onKeyPress={keyPressed}
|
||||
required
|
||||
/>
|
||||
</Grid>
|
||||
|
||||
@@ -102,9 +102,6 @@ import ObjectDetailPanel from "./ObjectDetailPanel";
|
||||
import RBIconButton from "../../../BucketDetails/SummaryItems/RBIconButton";
|
||||
import MultiSelectionPanel from "./MultiSelectionPanel";
|
||||
|
||||
const AddFolderIcon = React.lazy(
|
||||
() => import("../../../../../../icons/AddFolderIcon")
|
||||
);
|
||||
const HistoryIcon = React.lazy(
|
||||
() => import("../../../../../../icons/HistoryIcon")
|
||||
);
|
||||
@@ -115,9 +112,7 @@ const RefreshIcon = React.lazy(
|
||||
const DeleteIcon = React.lazy(
|
||||
() => import("../../../../../../icons/DeleteIcon")
|
||||
);
|
||||
const CreateFolderModal = withSuspense(
|
||||
React.lazy(() => import("./CreateFolderModal"))
|
||||
);
|
||||
|
||||
const DeleteMultipleObjects = withSuspense(
|
||||
React.lazy(() => import("./DeleteMultipleObjects"))
|
||||
);
|
||||
@@ -169,6 +164,22 @@ const styles = (theme: Theme) =>
|
||||
...searchField.searchField,
|
||||
maxWidth: 380,
|
||||
},
|
||||
screenTitleContainer: {
|
||||
border: "#EAEDEE 1px solid",
|
||||
borderBottom: 0,
|
||||
padding: "0.8rem 15px 0",
|
||||
},
|
||||
titleSpacer: {
|
||||
marginLeft: 10,
|
||||
},
|
||||
listIcon: {
|
||||
display: "block",
|
||||
marginTop: "-10px",
|
||||
"& .min-icon": {
|
||||
width: 20,
|
||||
height: 20,
|
||||
}
|
||||
},
|
||||
...objectBrowserCommon,
|
||||
...containerForHeader(theme.spacing(4)),
|
||||
});
|
||||
@@ -269,7 +280,6 @@ const ListObjects = ({
|
||||
const [rewind, setRewind] = useState<RewindObject[]>([]);
|
||||
const [loadingRewind, setLoadingRewind] = useState<boolean>(false);
|
||||
const [deleteMultipleOpen, setDeleteMultipleOpen] = useState<boolean>(false);
|
||||
const [createFolderOpen, setCreateFolderOpen] = useState<boolean>(false);
|
||||
const [loadingStartTime, setLoadingStartTime] = useState<number>(0);
|
||||
const [loadingMessage, setLoadingMessage] =
|
||||
useState<React.ReactNode>(defLoading);
|
||||
@@ -372,12 +382,12 @@ const ListObjects = ({
|
||||
|
||||
if (timeDelta / 1000 >= 6) {
|
||||
setLoadingMessage(
|
||||
<React.Fragment>
|
||||
<Fragment>
|
||||
<Typography component="h3">
|
||||
This operation is taking longer than expected... (
|
||||
{Math.ceil(timeDelta / 1000)}s)
|
||||
</Typography>
|
||||
</React.Fragment>
|
||||
</Fragment>
|
||||
);
|
||||
} else if (timeDelta / 1000 >= 3) {
|
||||
setLoadingMessage(
|
||||
@@ -656,9 +666,7 @@ const ListObjects = ({
|
||||
}
|
||||
};
|
||||
|
||||
const closeAddFolderModal = () => {
|
||||
setCreateFolderOpen(false);
|
||||
};
|
||||
|
||||
|
||||
const handleUploadButton = (e: any) => {
|
||||
if (
|
||||
@@ -1167,7 +1175,7 @@ const ListObjects = ({
|
||||
];
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
<Fragment>
|
||||
{shareFileModalOpen && selectedPreview && (
|
||||
<ShareFile
|
||||
open={shareFileModalOpen}
|
||||
@@ -1189,15 +1197,6 @@ const ListObjects = ({
|
||||
versioning={isVersioned}
|
||||
/>
|
||||
)}
|
||||
{createFolderOpen && (
|
||||
<CreateFolderModal
|
||||
modalOpen={createFolderOpen}
|
||||
bucketName={bucketName}
|
||||
folderName={internalPaths}
|
||||
onClose={closeAddFolderModal}
|
||||
existingFiles={records}
|
||||
/>
|
||||
)}
|
||||
{rewindSelect && (
|
||||
<RewindEnable
|
||||
open={rewindSelect}
|
||||
@@ -1214,21 +1213,15 @@ const ListObjects = ({
|
||||
/>
|
||||
)}
|
||||
<PageLayout>
|
||||
<Grid item xs={12}>
|
||||
<Grid item xs={12} className={classes.screenTitleContainer}>
|
||||
<ScreenTitle
|
||||
className={classes.screenTitle}
|
||||
icon={
|
||||
<Fragment>
|
||||
<BucketsIcon width={40} />
|
||||
</Fragment>
|
||||
}
|
||||
title={
|
||||
<BrowserBreadcrumbs
|
||||
bucketName={bucketName}
|
||||
internalPaths={pageTitle}
|
||||
fullSizeBreadcrumbs
|
||||
/>
|
||||
<span className={classes.listIcon}>
|
||||
<BucketsIcon />
|
||||
</span>
|
||||
}
|
||||
title={<span className={classes.titleSpacer}>{bucketName}</span>}
|
||||
subTitle={
|
||||
<Fragment>
|
||||
<Grid item xs={12} className={classes.bucketDetails}>
|
||||
@@ -1266,21 +1259,6 @@ const ListObjects = ({
|
||||
}
|
||||
actions={
|
||||
<Fragment>
|
||||
<RBIconButton
|
||||
id={"new-path"}
|
||||
tooltip={"Choose or create a new path"}
|
||||
text={"New Path"}
|
||||
icon={<AddFolderIcon />}
|
||||
color="primary"
|
||||
variant={"outlined"}
|
||||
onClick={() => {
|
||||
setCreateFolderOpen(true);
|
||||
}}
|
||||
disabled={
|
||||
rewindEnabled ||
|
||||
!hasPermission(bucketName, [IAM_SCOPES.S3_PUT_OBJECT])
|
||||
}
|
||||
/>
|
||||
<RBIconButton
|
||||
id={"rewind-objects-list"}
|
||||
tooltip={"Rewind Bucket"}
|
||||
@@ -1292,6 +1270,7 @@ const ListObjects = ({
|
||||
variant="dot"
|
||||
invisible={!rewindEnabled}
|
||||
className={classes.badgeOverlap}
|
||||
sx={{height: 12}}
|
||||
>
|
||||
<HistoryIcon />
|
||||
</Badge>
|
||||
@@ -1355,6 +1334,13 @@ const ListObjects = ({
|
||||
}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<BrowserBreadcrumbs
|
||||
bucketName={bucketName}
|
||||
internalPaths={pageTitle}
|
||||
existingFiles={records || []}
|
||||
/>
|
||||
</Grid>
|
||||
<div
|
||||
id="object-list-wrapper"
|
||||
{...getRootProps({ style: { ...dndStyles } })}
|
||||
@@ -1414,7 +1400,7 @@ const ListObjects = ({
|
||||
</Grid>
|
||||
</div>
|
||||
</PageLayout>
|
||||
</React.Fragment>
|
||||
</Fragment>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -48,7 +48,6 @@ import {
|
||||
import { decodeFileName, encodeFileName } from "../../../../../../common/utils";
|
||||
import { IAM_SCOPES } from "../../../../../../common/SecureComponent/permissions";
|
||||
import SetRetention from "./SetRetention";
|
||||
import BrowserBreadcrumbs from "../../../../ObjectBrowser/BrowserBreadcrumbs";
|
||||
import DeleteObject from "../ListObjects/DeleteObject";
|
||||
import AddTagModal from "./AddTagModal";
|
||||
import DeleteTagModal from "./DeleteTagModal";
|
||||
@@ -518,14 +517,6 @@ const ObjectDetails = ({
|
||||
? objectNameArray[objectNameArray.length - 1]
|
||||
: actualInfo.name
|
||||
}
|
||||
subTitle={
|
||||
<Fragment>
|
||||
<BrowserBreadcrumbs
|
||||
bucketName={bucketName}
|
||||
internalPaths={actualInfo.name}
|
||||
/>
|
||||
</Fragment>
|
||||
}
|
||||
actions={
|
||||
<Fragment>
|
||||
<SecureComponent
|
||||
|
||||
@@ -40,6 +40,7 @@ interface InputBoxProps {
|
||||
label: string;
|
||||
classes: any;
|
||||
onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
|
||||
onKeyPress?: (e: any) => void;
|
||||
value: string | boolean;
|
||||
id: string;
|
||||
name: string;
|
||||
@@ -133,6 +134,7 @@ const InputBoxWrapper = ({
|
||||
autoFocus = false,
|
||||
classes,
|
||||
className = "",
|
||||
onKeyPress,
|
||||
}: InputBoxProps) => {
|
||||
let inputProps: any = { "data-index": index, ...extraInputProps };
|
||||
|
||||
@@ -197,6 +199,7 @@ const InputBoxWrapper = ({
|
||||
helperText={error}
|
||||
placeholder={placeholder}
|
||||
className={classes.inputRebase}
|
||||
onKeyPress={onKeyPress}
|
||||
/>
|
||||
{overlayIcon && (
|
||||
<div
|
||||
|
||||
@@ -361,20 +361,27 @@ export const objectBrowserCommon = {
|
||||
lineHeight: "40px",
|
||||
},
|
||||
breadcrumbs: {
|
||||
fontSize: 10,
|
||||
color: "#000",
|
||||
fontSize: 12,
|
||||
color: "#969FA8",
|
||||
fontWeight: "bold",
|
||||
marginTop: 2,
|
||||
border: "#EAEDEE 1px solid",
|
||||
borderBottom: 0,
|
||||
height: 38,
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
backgroundColor: "#FCFCFD",
|
||||
"& a": {
|
||||
textDecoration: "none",
|
||||
color: "#000",
|
||||
color: "#969FA8",
|
||||
"&:hover": {
|
||||
textDecoration: "underline",
|
||||
},
|
||||
},
|
||||
"&.fullSize": {
|
||||
fontSize: 18,
|
||||
marginLeft: 10,
|
||||
},
|
||||
"& .min-icon": {
|
||||
width: 14,
|
||||
minWidth: 14,
|
||||
}
|
||||
},
|
||||
smallLabel: {
|
||||
color: "#9C9C9C",
|
||||
@@ -388,6 +395,17 @@ export const objectBrowserCommon = {
|
||||
detailsSpacer: {
|
||||
marginRight: 18,
|
||||
},
|
||||
breadcrumbsList: {
|
||||
textOverflow: "ellipsis" as const,
|
||||
overflow: "hidden" as const,
|
||||
whiteSpace: "nowrap" as const,
|
||||
display: "inline-block" as const,
|
||||
flexGrow: 1,
|
||||
textAlign: "left" as const,
|
||||
marginLeft: 15,
|
||||
marginRight: 10,
|
||||
lineHeight: 35,
|
||||
},
|
||||
};
|
||||
|
||||
export const selectorsCommon = {
|
||||
|
||||
@@ -14,10 +14,9 @@
|
||||
// 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 React, { Fragment, useState } from "react";
|
||||
import get from "lodash/get";
|
||||
import Grid from "@mui/material/Grid";
|
||||
import Moment from "react-moment";
|
||||
import { connect } from "react-redux";
|
||||
import withStyles from "@mui/styles/withStyles";
|
||||
import { Theme } from "@mui/material/styles";
|
||||
@@ -26,6 +25,19 @@ import { ObjectBrowserState } from "./reducers";
|
||||
import { objectBrowserCommon } from "../Common/FormComponents/common/styleLibrary";
|
||||
import { Link } from "react-router-dom";
|
||||
import { encodeFileName } from "../../../common/utils";
|
||||
import { BackCaretIcon, FolderIcon } from "../../../icons";
|
||||
import { IconButton, Tooltip } from "@mui/material";
|
||||
import history from "../../../history";
|
||||
import { hasPermission } from "../../../common/SecureComponent";
|
||||
import { IAM_SCOPES } from "../../../common/SecureComponent/permissions";
|
||||
import withSuspense from "../Common/Components/withSuspense";
|
||||
import { BucketObject } from "../Buckets/ListBuckets/Objects/ListObjects/types";
|
||||
|
||||
const CreateFolderModal = withSuspense(
|
||||
React.lazy(
|
||||
() => import("../Buckets/ListBuckets/Objects/ListObjects/CreateFolderModal")
|
||||
)
|
||||
);
|
||||
|
||||
interface ObjectBrowserReducer {
|
||||
objectBrowser: ObjectBrowserState;
|
||||
@@ -37,7 +49,7 @@ interface IObjectBrowser {
|
||||
internalPaths: string;
|
||||
rewindEnabled?: boolean;
|
||||
rewindDate?: any;
|
||||
fullSizeBreadcrumbs?: boolean;
|
||||
existingFiles: BucketObject[];
|
||||
}
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
@@ -51,8 +63,10 @@ const BrowserBreadcrumbs = ({
|
||||
internalPaths,
|
||||
rewindEnabled,
|
||||
rewindDate,
|
||||
fullSizeBreadcrumbs,
|
||||
existingFiles,
|
||||
}: IObjectBrowser) => {
|
||||
const [createFolderOpen, setCreateFolderOpen] = useState<boolean>(false);
|
||||
|
||||
let paths = internalPaths;
|
||||
|
||||
if (internalPaths !== "") {
|
||||
@@ -60,52 +74,83 @@ const BrowserBreadcrumbs = ({
|
||||
}
|
||||
|
||||
const splitPaths = paths.split("/").filter((path) => path !== "");
|
||||
const listBreadcrumbs = splitPaths.map(
|
||||
(objectItem: string, index: number) => {
|
||||
const subSplit = splitPaths.slice(0, index + 1).join("/");
|
||||
const route = `/buckets/${bucketName}/browse/${
|
||||
subSplit ? `${encodeFileName(subSplit)}` : ``
|
||||
}`;
|
||||
return (
|
||||
<React.Fragment key={`breadcrumbs-${index.toString()}`}>
|
||||
<Link to={route}>{objectItem}</Link>
|
||||
{index < splitPaths.length - 1 && <span> / </span>}
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
);
|
||||
let breadcrumbsMap = splitPaths.map((objectItem: string, index: number) => {
|
||||
const subSplit = splitPaths.slice(0, index + 1).join("/");
|
||||
const route = `/buckets/${bucketName}/browse/${
|
||||
subSplit ? `${encodeFileName(subSplit)}` : ``
|
||||
}`;
|
||||
return (
|
||||
<Fragment key={`breadcrumbs-${index.toString()}`}>
|
||||
<span> / </span>
|
||||
<Link to={route}>{objectItem}</Link>
|
||||
</Fragment>
|
||||
);
|
||||
});
|
||||
|
||||
const listBreadcrumbs: any[] = [
|
||||
<Fragment key={`breadcrumbs-root-path`}>
|
||||
<Link to={`/buckets/${bucketName}/browse`}>{bucketName}</Link>
|
||||
</Fragment>,
|
||||
...breadcrumbsMap,
|
||||
];
|
||||
|
||||
const closeAddFolderModal = () => {
|
||||
setCreateFolderOpen(false);
|
||||
};
|
||||
|
||||
const title = false;
|
||||
return (
|
||||
<React.Fragment>
|
||||
{title && (
|
||||
<Grid item xs={12}>
|
||||
<div className={classes.sectionTitle}>
|
||||
{splitPaths && splitPaths.length > 0
|
||||
? splitPaths[splitPaths.length - 1]
|
||||
: ""}
|
||||
{rewindEnabled && splitPaths.length > 1 && (
|
||||
<small className={classes.smallLabel}>
|
||||
(Rewind:{" "}
|
||||
<Moment date={rewindDate} format="MMMM Do YYYY, h:mm a" /> )
|
||||
</small>
|
||||
)}
|
||||
</div>
|
||||
</Grid>
|
||||
{createFolderOpen && (
|
||||
<CreateFolderModal
|
||||
modalOpen={createFolderOpen}
|
||||
bucketName={bucketName}
|
||||
folderName={internalPaths}
|
||||
onClose={closeAddFolderModal}
|
||||
existingFiles={existingFiles}
|
||||
/>
|
||||
)}
|
||||
|
||||
<Grid
|
||||
item
|
||||
xs={12}
|
||||
className={`${classes.breadcrumbs} ${
|
||||
fullSizeBreadcrumbs ? "fullSize" : ""
|
||||
}`}
|
||||
>
|
||||
<React.Fragment>
|
||||
<Link to={`/buckets/${bucketName}/browse`}>{bucketName}</Link>
|
||||
{listBreadcrumbs.length > 0 && <span> / </span>}
|
||||
</React.Fragment>
|
||||
{listBreadcrumbs}
|
||||
<Grid item xs={12} className={`${classes.breadcrumbs}`}>
|
||||
<IconButton
|
||||
onClick={() => {
|
||||
history.goBack();
|
||||
}}
|
||||
sx={{
|
||||
border: "#EAEDEE 1px solid",
|
||||
backgroundColor: "#fff",
|
||||
borderLeft: 0,
|
||||
borderBottom: 0,
|
||||
borderRadius: 0,
|
||||
width: 39,
|
||||
height: 39,
|
||||
marginRight: "10px",
|
||||
}}
|
||||
>
|
||||
<BackCaretIcon />
|
||||
</IconButton>
|
||||
<Tooltip title={"Choose or create a new path"}>
|
||||
<IconButton
|
||||
id={"new-path"}
|
||||
onClick={() => {
|
||||
setCreateFolderOpen(true);
|
||||
}}
|
||||
disabled={
|
||||
rewindEnabled ||
|
||||
!hasPermission(bucketName, [IAM_SCOPES.S3_PUT_OBJECT])
|
||||
}
|
||||
disableTouchRipple
|
||||
disableRipple
|
||||
focusRipple={false}
|
||||
sx={{
|
||||
padding: 0,
|
||||
paddingLeft: "6px",
|
||||
}}
|
||||
>
|
||||
<FolderIcon />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
<div className={classes.breadcrumbsList} dir="rtl">
|
||||
{listBreadcrumbs}
|
||||
</div>
|
||||
</Grid>
|
||||
</React.Fragment>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user