Permission Error handling and Tooltips for upload file, object action buttons (#2338)
 <img width="706" alt="Screen Shot 2022-09-23 at 11 38 59 AM" src="https://user-images.githubusercontent.com/65002498/192035299-093f814e-4821-4610-8fc5-c20565ea7c38.png"> <img width="642" alt="Screen Shot 2022-09-23 at 11 47 15 AM" src="https://user-images.githubusercontent.com/65002498/192036512-f8891625-e050-42fd-9c43-173dd61c4df3.png">
This commit is contained in:
@@ -435,13 +435,13 @@ export const CONSOLE_UI_RESOURCE = "console-ui";
|
||||
|
||||
export const permissionTooltipHelper = (scopes: string[], name: string) => {
|
||||
return (
|
||||
"You require additional permissions in order to enable " +
|
||||
"You require additional permissions in order to " +
|
||||
name +
|
||||
". Please ask your MinIO administrator to grant you " +
|
||||
scopes +
|
||||
" permission" +
|
||||
(scopes.length > 1 ? "s" : "") +
|
||||
" in order to enable " +
|
||||
" in order to " +
|
||||
name +
|
||||
"."
|
||||
);
|
||||
|
||||
@@ -19,6 +19,7 @@ import ObjectActionButton from "./ObjectActionButton";
|
||||
import { withStyles } from "@mui/styles";
|
||||
import createStyles from "@mui/styles/createStyles";
|
||||
import { detailsPanel } from "../../../../Common/FormComponents/common/styleLibrary";
|
||||
import TooltipWrapper from "../../../../Common/TooltipWrapper/TooltipWrapper";
|
||||
|
||||
const styles = () =>
|
||||
createStyles({
|
||||
@@ -52,12 +53,14 @@ const ActionsListSection = ({
|
||||
{items.map((actionItem, index) => {
|
||||
return (
|
||||
<li key={`action-element-${index.toString()}`}>
|
||||
<ObjectActionButton
|
||||
label={actionItem.label}
|
||||
icon={actionItem.icon}
|
||||
onClick={actionItem.action}
|
||||
disabled={actionItem.disabled}
|
||||
/>
|
||||
<TooltipWrapper tooltip={actionItem.tooltip || ""}>
|
||||
<ObjectActionButton
|
||||
label={actionItem.label}
|
||||
icon={actionItem.icon}
|
||||
onClick={actionItem.action}
|
||||
disabled={actionItem.disabled}
|
||||
/>
|
||||
</TooltipWrapper>
|
||||
</li>
|
||||
);
|
||||
})}
|
||||
|
||||
@@ -71,7 +71,10 @@ import ScreenTitle from "../../../../Common/ScreenTitle/ScreenTitle";
|
||||
import { AppState, useAppDispatch } from "../../../../../../store";
|
||||
import PageLayout from "../../../../Common/Layout/PageLayout";
|
||||
|
||||
import { IAM_SCOPES } from "../../../../../../common/SecureComponent/permissions";
|
||||
import {
|
||||
IAM_SCOPES,
|
||||
permissionTooltipHelper,
|
||||
} from "../../../../../../common/SecureComponent/permissions";
|
||||
import {
|
||||
hasPermission,
|
||||
SecureComponent,
|
||||
@@ -1055,11 +1058,23 @@ const ListObjects = () => {
|
||||
|
||||
const onDrop = useCallback(
|
||||
(acceptedFiles: any[]) => {
|
||||
if (acceptedFiles && acceptedFiles.length > 0) {
|
||||
if (acceptedFiles && acceptedFiles.length > 0 && canUpload) {
|
||||
let newFolderPath: string = acceptedFiles[0].path;
|
||||
uploadObject(acceptedFiles, newFolderPath);
|
||||
}
|
||||
if (!canUpload) {
|
||||
dispatch(
|
||||
setErrorSnackMessage({
|
||||
errorMessage: "Upload not allowed",
|
||||
detailedError: permissionTooltipHelper(
|
||||
[IAM_SCOPES.S3_PUT_OBJECT],
|
||||
"upload objects to this location"
|
||||
),
|
||||
})
|
||||
);
|
||||
}
|
||||
},
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
[uploadObject]
|
||||
);
|
||||
|
||||
@@ -1221,6 +1236,10 @@ const ListObjects = () => {
|
||||
uploadPath = uploadPath.concat(currentPath);
|
||||
}
|
||||
|
||||
const canDownload = hasPermission(bucketName, [IAM_SCOPES.S3_GET_OBJECT]);
|
||||
const canDelete = hasPermission(bucketName, [IAM_SCOPES.S3_DELETE_OBJECT]);
|
||||
const canUpload = hasPermission(uploadPath, [IAM_SCOPES.S3_PUT_OBJECT]);
|
||||
|
||||
const onClosePanel = (forceRefresh: boolean) => {
|
||||
dispatch(setSelectedObjectView(null));
|
||||
dispatch(setVersionsModeEnabled({ status: false }));
|
||||
@@ -1272,23 +1291,28 @@ const ListObjects = () => {
|
||||
{
|
||||
action: downloadSelected,
|
||||
label: "Download",
|
||||
disabled: selectedObjects.length === 0,
|
||||
disabled: !canDownload || selectedObjects.length === 0,
|
||||
icon: <DownloadIcon />,
|
||||
tooltip: "Download Selected",
|
||||
tooltip: canDownload
|
||||
? "Download Selected"
|
||||
: permissionTooltipHelper(
|
||||
[IAM_SCOPES.S3_GET_OBJECT],
|
||||
"download objects from this bucket"
|
||||
),
|
||||
},
|
||||
{
|
||||
action: openShare,
|
||||
label: "Share",
|
||||
disabled: selectedObjects.length !== 1 || !canShareFile,
|
||||
icon: <ShareIcon />,
|
||||
tooltip: "Share Selected File",
|
||||
tooltip: canShareFile ? "Share Selected File" : "Sharing unavailable",
|
||||
},
|
||||
{
|
||||
action: openPreview,
|
||||
label: "Preview",
|
||||
disabled: selectedObjects.length !== 1 || !canPreviewFile,
|
||||
icon: <PreviewIcon />,
|
||||
tooltip: "Preview Selected File",
|
||||
tooltip: canPreviewFile ? "Preview Selected File" : "Preview unavailable",
|
||||
},
|
||||
{
|
||||
action: () => {
|
||||
@@ -1297,10 +1321,13 @@ const ListObjects = () => {
|
||||
label: "Delete",
|
||||
icon: <DeleteIcon />,
|
||||
disabled:
|
||||
!hasPermission(bucketName, [IAM_SCOPES.S3_DELETE_OBJECT]) ||
|
||||
selectedObjects.length === 0 ||
|
||||
!displayDeleteObject,
|
||||
tooltip: "Delete Selected Files",
|
||||
!canDelete || selectedObjects.length === 0 || !displayDeleteObject,
|
||||
tooltip: canDelete
|
||||
? "Delete Selected Files"
|
||||
: permissionTooltipHelper(
|
||||
[IAM_SCOPES.S3_DELETE_OBJECT],
|
||||
"delete objects in this bucket"
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
|
||||
@@ -41,7 +41,10 @@ import {
|
||||
niceBytesInt,
|
||||
niceDaysInt,
|
||||
} from "../../../../../../common/utils";
|
||||
import { IAM_SCOPES } from "../../../../../../common/SecureComponent/permissions";
|
||||
import {
|
||||
IAM_SCOPES,
|
||||
permissionTooltipHelper,
|
||||
} from "../../../../../../common/SecureComponent/permissions";
|
||||
|
||||
import { AppState, useAppDispatch } from "../../../../../../store";
|
||||
import {
|
||||
@@ -90,6 +93,7 @@ import {
|
||||
updateProgress,
|
||||
} from "../../../../ObjectBrowser/objectBrowserSlice";
|
||||
import RenameLongFileName from "../../../../ObjectBrowser/RenameLongFilename";
|
||||
import TooltipWrapper from "../../../../Common/TooltipWrapper/TooltipWrapper";
|
||||
|
||||
const styles = () =>
|
||||
createStyles({
|
||||
@@ -405,6 +409,33 @@ const ObjectDetailPanel = ({
|
||||
currentItem,
|
||||
[bucketName, actualInfo.name].join("/"),
|
||||
];
|
||||
const canSetLegalHold = hasPermission(bucketName, [
|
||||
IAM_SCOPES.S3_PUT_OBJECT_LEGAL_HOLD,
|
||||
]);
|
||||
const canSetTags = hasPermission(objectResources, [
|
||||
IAM_SCOPES.S3_PUT_OBJECT_TAGGING,
|
||||
]);
|
||||
|
||||
const canChangeRetention = hasPermission(
|
||||
objectResources,
|
||||
[IAM_SCOPES.S3_GET_OBJECT_RETENTION, IAM_SCOPES.S3_PUT_OBJECT_RETENTION],
|
||||
true
|
||||
);
|
||||
const canInspect = hasPermission(objectResources, [
|
||||
IAM_SCOPES.ADMIN_INSPECT_DATA,
|
||||
]);
|
||||
const canChangeVersioning = hasPermission(objectResources, [
|
||||
IAM_SCOPES.S3_GET_BUCKET_VERSIONING,
|
||||
IAM_SCOPES.S3_PUT_BUCKET_VERSIONING,
|
||||
IAM_SCOPES.S3_GET_OBJECT_VERSION,
|
||||
]);
|
||||
const canGetObject = hasPermission(objectResources, [
|
||||
IAM_SCOPES.S3_GET_OBJECT,
|
||||
]);
|
||||
const canDelete = hasPermission(
|
||||
[bucketName, currentItem, [bucketName, actualInfo.name].join("/")],
|
||||
[IAM_SCOPES.S3_DELETE_OBJECT]
|
||||
);
|
||||
|
||||
const multiActionButtons = [
|
||||
{
|
||||
@@ -412,22 +443,28 @@ const ObjectDetailPanel = ({
|
||||
downloadObject(actualInfo);
|
||||
},
|
||||
label: "Download",
|
||||
disabled:
|
||||
!!actualInfo.is_delete_marker ||
|
||||
!hasPermission(objectResources, [IAM_SCOPES.S3_GET_OBJECT]),
|
||||
disabled: !!actualInfo.is_delete_marker || !canGetObject,
|
||||
icon: <DownloadIcon />,
|
||||
tooltip: "Download this Object",
|
||||
tooltip: canGetObject
|
||||
? "Download this Object"
|
||||
: permissionTooltipHelper(
|
||||
[IAM_SCOPES.S3_GET_OBJECT],
|
||||
"download this object"
|
||||
),
|
||||
},
|
||||
{
|
||||
action: () => {
|
||||
shareObject();
|
||||
},
|
||||
label: "Share",
|
||||
disabled:
|
||||
!!actualInfo.is_delete_marker ||
|
||||
!hasPermission(objectResources, [IAM_SCOPES.S3_GET_OBJECT]),
|
||||
disabled: !!actualInfo.is_delete_marker || !canGetObject,
|
||||
icon: <ShareIcon />,
|
||||
tooltip: "Share this File",
|
||||
tooltip: canGetObject
|
||||
? "Share this File"
|
||||
: permissionTooltipHelper(
|
||||
[IAM_SCOPES.S3_GET_OBJECT],
|
||||
"share this object"
|
||||
),
|
||||
},
|
||||
{
|
||||
action: () => {
|
||||
@@ -437,9 +474,14 @@ const ObjectDetailPanel = ({
|
||||
disabled:
|
||||
!!actualInfo.is_delete_marker ||
|
||||
extensionPreview(currentItem) === "none" ||
|
||||
!hasPermission(objectResources, [IAM_SCOPES.S3_GET_OBJECT]),
|
||||
!canGetObject,
|
||||
icon: <PreviewIcon />,
|
||||
tooltip: "Preview this File",
|
||||
tooltip: canGetObject
|
||||
? "Preview this File"
|
||||
: permissionTooltipHelper(
|
||||
[IAM_SCOPES.S3_GET_OBJECT],
|
||||
"preview this object"
|
||||
),
|
||||
},
|
||||
{
|
||||
action: () => {
|
||||
@@ -450,10 +492,17 @@ const ObjectDetailPanel = ({
|
||||
!locking ||
|
||||
!distributedSetup ||
|
||||
!!actualInfo.is_delete_marker ||
|
||||
!hasPermission(bucketName, [IAM_SCOPES.S3_PUT_OBJECT_LEGAL_HOLD]) ||
|
||||
!canSetLegalHold ||
|
||||
selectedVersion !== "",
|
||||
icon: <LegalHoldIcon />,
|
||||
tooltip: "Change Legal Hold rules for this File",
|
||||
tooltip: canSetLegalHold
|
||||
? locking
|
||||
? "Change Legal Hold rules for this File"
|
||||
: "Object Locking must be enabled on this bucket in order to set Legal Hold"
|
||||
: permissionTooltipHelper(
|
||||
[IAM_SCOPES.S3_PUT_OBJECT_LEGAL_HOLD],
|
||||
"change legal hold settings for this object"
|
||||
),
|
||||
},
|
||||
{
|
||||
action: openRetentionModal,
|
||||
@@ -461,10 +510,21 @@ const ObjectDetailPanel = ({
|
||||
disabled:
|
||||
!distributedSetup ||
|
||||
!!actualInfo.is_delete_marker ||
|
||||
!hasPermission(objectResources, [IAM_SCOPES.S3_GET_OBJECT_RETENTION]) ||
|
||||
selectedVersion !== "",
|
||||
!canChangeRetention ||
|
||||
selectedVersion !== "" ||
|
||||
!locking,
|
||||
icon: <RetentionIcon />,
|
||||
tooltip: "Change Retention rules for this File",
|
||||
tooltip: canChangeRetention
|
||||
? locking
|
||||
? "Change Retention rules for this File"
|
||||
: "Object Locking must be enabled on this bucket in order to set Retention Rules"
|
||||
: permissionTooltipHelper(
|
||||
[
|
||||
IAM_SCOPES.S3_GET_OBJECT_RETENTION,
|
||||
IAM_SCOPES.S3_PUT_OBJECT_RETENTION,
|
||||
],
|
||||
"change Retention Rules for this object"
|
||||
),
|
||||
},
|
||||
{
|
||||
action: () => {
|
||||
@@ -472,11 +532,17 @@ const ObjectDetailPanel = ({
|
||||
},
|
||||
label: "Tags",
|
||||
disabled:
|
||||
!!actualInfo.is_delete_marker ||
|
||||
selectedVersion !== "" ||
|
||||
!hasPermission(objectResources, [IAM_SCOPES.S3_PUT_OBJECT_TAGGING]),
|
||||
!!actualInfo.is_delete_marker || selectedVersion !== "" || !canSetTags,
|
||||
icon: <TagsIcon />,
|
||||
tooltip: "Change Tags for this File",
|
||||
tooltip: canSetTags
|
||||
? "Change Tags for this File"
|
||||
: permissionTooltipHelper(
|
||||
[
|
||||
IAM_SCOPES.S3_PUT_OBJECT_TAGGING,
|
||||
IAM_SCOPES.S3_GET_OBJECT_TAGGING,
|
||||
],
|
||||
"set Tags on this object"
|
||||
),
|
||||
},
|
||||
{
|
||||
action: () => {
|
||||
@@ -487,9 +553,14 @@ const ObjectDetailPanel = ({
|
||||
!distributedSetup ||
|
||||
!!actualInfo.is_delete_marker ||
|
||||
selectedVersion !== "" ||
|
||||
!hasPermission(objectResources, [IAM_SCOPES.ADMIN_INSPECT_DATA]),
|
||||
!canInspect,
|
||||
icon: <InspectMenuIcon />,
|
||||
tooltip: "Inspect this file",
|
||||
tooltip: canInspect
|
||||
? "Inspect this file"
|
||||
: permissionTooltipHelper(
|
||||
[IAM_SCOPES.ADMIN_INSPECT_DATA],
|
||||
"inspect this file"
|
||||
),
|
||||
},
|
||||
{
|
||||
action: () => {
|
||||
@@ -505,12 +576,19 @@ const ObjectDetailPanel = ({
|
||||
disabled:
|
||||
!distributedSetup ||
|
||||
!(actualInfo.version_id && actualInfo.version_id !== "null") ||
|
||||
!hasPermission(objectResources, [
|
||||
IAM_SCOPES.S3_GET_BUCKET_VERSIONING,
|
||||
IAM_SCOPES.S3_PUT_BUCKET_VERSIONING,
|
||||
IAM_SCOPES.S3_GET_OBJECT_VERSION,
|
||||
]),
|
||||
tooltip: "Display Versions for this file",
|
||||
!canChangeVersioning,
|
||||
tooltip: canChangeVersioning
|
||||
? actualInfo.version_id && actualInfo.version_id !== "null"
|
||||
? "Display Versions for this file"
|
||||
: ""
|
||||
: permissionTooltipHelper(
|
||||
[
|
||||
IAM_SCOPES.S3_GET_BUCKET_VERSIONING,
|
||||
IAM_SCOPES.S3_PUT_BUCKET_VERSIONING,
|
||||
IAM_SCOPES.S3_GET_OBJECT_VERSION,
|
||||
],
|
||||
"display all versions of this object"
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
@@ -621,35 +699,51 @@ const ObjectDetailPanel = ({
|
||||
}
|
||||
items={multiActionButtons}
|
||||
/>
|
||||
|
||||
<Grid item xs={12} sx={{ justifyContent: "center", display: "flex" }}>
|
||||
<SecureComponent
|
||||
resource={[
|
||||
bucketName,
|
||||
currentItem,
|
||||
[bucketName, actualInfo.name].join("/"),
|
||||
]}
|
||||
scopes={[IAM_SCOPES.S3_DELETE_OBJECT]}
|
||||
errorProps={{ disabled: true }}
|
||||
<TooltipWrapper
|
||||
tooltip={
|
||||
canDelete
|
||||
? ""
|
||||
: permissionTooltipHelper(
|
||||
[IAM_SCOPES.S3_DELETE_OBJECT],
|
||||
"delete this object"
|
||||
)
|
||||
}
|
||||
>
|
||||
<Grid
|
||||
item
|
||||
xs={12}
|
||||
sx={{ justifyContent: "center", display: "flex" }}
|
||||
>
|
||||
<Button
|
||||
id={"delete-element-click"}
|
||||
icon={<DeleteIcon />}
|
||||
iconLocation={"start"}
|
||||
fullWidth
|
||||
variant={"secondary"}
|
||||
onClick={() => {
|
||||
setDeleteOpen(true);
|
||||
}}
|
||||
disabled={selectedVersion === "" && actualInfo.is_delete_marker}
|
||||
style={{
|
||||
width: "calc(100% - 44px)",
|
||||
margin: "8px 0",
|
||||
}}
|
||||
label={`Delete${selectedVersion !== "" ? " version" : ""}`}
|
||||
/>
|
||||
</SecureComponent>
|
||||
</Grid>
|
||||
<SecureComponent
|
||||
resource={[
|
||||
bucketName,
|
||||
currentItem,
|
||||
[bucketName, actualInfo.name].join("/"),
|
||||
]}
|
||||
scopes={[IAM_SCOPES.S3_DELETE_OBJECT]}
|
||||
errorProps={{ disabled: true }}
|
||||
>
|
||||
<Button
|
||||
id={"delete-element-click"}
|
||||
icon={<DeleteIcon />}
|
||||
iconLocation={"start"}
|
||||
fullWidth
|
||||
variant={"secondary"}
|
||||
onClick={() => {
|
||||
setDeleteOpen(true);
|
||||
}}
|
||||
disabled={
|
||||
selectedVersion === "" && actualInfo.is_delete_marker
|
||||
}
|
||||
style={{
|
||||
width: "calc(100% - 44px)",
|
||||
margin: "8px 0",
|
||||
}}
|
||||
label={`Delete${selectedVersion !== "" ? " version" : ""}`}
|
||||
/>
|
||||
</SecureComponent>
|
||||
</Grid>
|
||||
</TooltipWrapper>
|
||||
<Grid item xs={12} className={classes.headerForSection}>
|
||||
<span>Object Info</span>
|
||||
<ObjectInfoIcon />
|
||||
|
||||
@@ -22,7 +22,10 @@ import withStyles from "@mui/styles/withStyles";
|
||||
import ListItemText from "@mui/material/ListItemText";
|
||||
import ListItemIcon from "@mui/material/ListItemIcon";
|
||||
import { UploadFolderIcon, UploadIcon } from "../../../../icons";
|
||||
import { IAM_SCOPES } from "../../../../common/SecureComponent/permissions";
|
||||
import {
|
||||
IAM_SCOPES,
|
||||
permissionTooltipHelper,
|
||||
} from "../../../../common/SecureComponent/permissions";
|
||||
import { hasPermission } from "../../../../common/SecureComponent";
|
||||
import { Button } from "mds";
|
||||
import TooltipWrapper from "../../Common/TooltipWrapper/TooltipWrapper";
|
||||
@@ -78,7 +81,16 @@ const UploadFilesButton = ({
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<TooltipWrapper tooltip={"Upload Files"}>
|
||||
<TooltipWrapper
|
||||
tooltip={
|
||||
uploadEnabled
|
||||
? "Upload Files"
|
||||
: permissionTooltipHelper(
|
||||
[IAM_SCOPES.S3_PUT_OBJECT],
|
||||
"upload files to this bucket"
|
||||
)
|
||||
}
|
||||
>
|
||||
<Button
|
||||
id={"upload-main"}
|
||||
aria-controls={`upload-main-menu`}
|
||||
|
||||
@@ -22,18 +22,22 @@ import withStyles from "@mui/styles/withStyles";
|
||||
import createStyles from "@mui/styles/createStyles";
|
||||
import { Theme } from "@mui/material/styles";
|
||||
import { Link, useNavigate } from "react-router-dom";
|
||||
import { IconButton, Tooltip } from "@mui/material";
|
||||
import { IconButton } from "@mui/material";
|
||||
import { objectBrowserCommon } from "../Common/FormComponents/common/styleLibrary";
|
||||
import { encodeURLString } from "../../../common/utils";
|
||||
import { BackCaretIcon, CopyIcon, NewPathIcon } from "../../../icons";
|
||||
import { hasPermission } from "../../../common/SecureComponent";
|
||||
import { IAM_SCOPES } from "../../../common/SecureComponent/permissions";
|
||||
import {
|
||||
IAM_SCOPES,
|
||||
permissionTooltipHelper,
|
||||
} from "../../../common/SecureComponent/permissions";
|
||||
import { BucketObjectItem } from "../Buckets/ListBuckets/Objects/ListObjects/types";
|
||||
import withSuspense from "../Common/Components/withSuspense";
|
||||
import { setSnackBarMessage } from "../../../systemSlice";
|
||||
import { AppState, useAppDispatch } from "../../../store";
|
||||
import { setVersionsModeEnabled } from "./objectBrowserSlice";
|
||||
import { Button } from "mds";
|
||||
import TooltipWrapper from "../Common/TooltipWrapper/TooltipWrapper";
|
||||
|
||||
const CreatePathModal = withSuspense(
|
||||
React.lazy(
|
||||
@@ -81,6 +85,8 @@ const BrowserBreadcrumbs = ({
|
||||
|
||||
const [createFolderOpen, setCreateFolderOpen] = useState<boolean>(false);
|
||||
|
||||
const canCreatePath = hasPermission(bucketName, [IAM_SCOPES.S3_PUT_OBJECT]);
|
||||
|
||||
let paths = internalPaths;
|
||||
|
||||
if (internalPaths !== "") {
|
||||
@@ -220,16 +226,22 @@ const BrowserBreadcrumbs = ({
|
||||
<div className={classes.additionalOptions}>{additionalOptions}</div>
|
||||
</Grid>
|
||||
{!hidePathButton && (
|
||||
<Tooltip title={"Choose or create a new path"}>
|
||||
<TooltipWrapper
|
||||
tooltip={
|
||||
canCreatePath
|
||||
? "Choose or create a new path"
|
||||
: permissionTooltipHelper(
|
||||
[IAM_SCOPES.S3_PUT_OBJECT],
|
||||
"create a new path"
|
||||
)
|
||||
}
|
||||
>
|
||||
<Button
|
||||
id={"new-path"}
|
||||
onClick={() => {
|
||||
setCreateFolderOpen(true);
|
||||
}}
|
||||
disabled={
|
||||
rewindEnabled ||
|
||||
!hasPermission(bucketName, [IAM_SCOPES.S3_PUT_OBJECT])
|
||||
}
|
||||
disabled={rewindEnabled || !canCreatePath}
|
||||
icon={<NewPathIcon style={{ fill: "#969FA8" }} />}
|
||||
style={{
|
||||
whiteSpace: "nowrap",
|
||||
@@ -237,7 +249,7 @@ const BrowserBreadcrumbs = ({
|
||||
variant={"regular"}
|
||||
label={"Create new path"}
|
||||
/>
|
||||
</Tooltip>
|
||||
</TooltipWrapper>
|
||||
)}
|
||||
</div>
|
||||
<div className={classes.breadcrumbsSecond}>{additionalOptions}</div>
|
||||
|
||||
Reference in New Issue
Block a user