Use PageLayout from mds (#2789)

This commit is contained in:
Javier Adriel
2023-04-29 21:16:09 -06:00
committed by GitHub
parent fb5193d896
commit 90c8ea7f09
50 changed files with 1264 additions and 1269 deletions

View File

@@ -21,6 +21,7 @@ import {
Button,
DeleteIcon,
HelpBox,
PageLayout,
PasswordKeyIcon,
} from "mds";
import { useSelector } from "react-redux";
@@ -40,7 +41,6 @@ import {
import { ErrorResponseHandler } from "../../../common/types";
import ChangePasswordModal from "./ChangePasswordModal";
import PageLayout from "../Common/Layout/PageLayout";
import SearchBox from "../Common/SearchBox";
import withSuspense from "../Common/Components/withSuspense";
import {
@@ -205,102 +205,104 @@ const Account = () => {
/>
<PageHeaderWrapper label="Access Keys" />
<PageLayout>
<Grid item={true} xs={12} className={classes.actionsTray}>
<SearchBox
placeholder={"Search Access Keys"}
onChange={setFilter}
overrideClass={classes.searchField}
value={filter}
/>
<Box
sx={{
display: "flex",
}}
>
{" "}
<TooltipWrapper tooltip={"Delete Selected"}>
<Button
id={"delete-selected-accounts"}
onClick={() => {
setDeleteMultipleOpen(true);
}}
label={"Delete Selected"}
icon={<DeleteIcon />}
disabled={selectedSAs.length === 0}
variant={"secondary"}
/>
</TooltipWrapper>
<SecureComponent
scopes={[IAM_SCOPES.ADMIN_CREATE_USER]}
resource={CONSOLE_UI_RESOURCE}
matchAll
errorProps={{ disabled: true }}
>
<Button
id={"change-password"}
onClick={() => setChangePasswordModalOpen(true)}
label={`Change Password`}
icon={<PasswordKeyIcon />}
variant={"regular"}
disabled={userIDP}
/>
</SecureComponent>
<Button
id={"create-service-account"}
onClick={() => {
navigate(`${IAM_PAGES.ACCOUNT_ADD}`);
}}
label={`Create access key`}
icon={<AddIcon />}
variant={"callAction"}
<Grid container spacing={1}>
<Grid item={true} xs={12} className={classes.actionsTray}>
<SearchBox
placeholder={"Search Access Keys"}
onChange={setFilter}
overrideClass={classes.searchField}
value={filter}
/>
</Box>
</Grid>
<Grid item xs={12} className={classes.tableBlock}>
<TableWrapper
isLoading={loading}
records={filteredRecords}
entityName={"Access Keys"}
idField={""}
columns={[{ label: "Access Key", elementKey: "" }]}
itemActions={tableActions}
selectedItems={selectedSAs}
onSelect={(e) => selectSAs(e, setSelectedSAs, selectedSAs)}
onSelectAll={selectAllItems}
/>
</Grid>
<Grid item xs={12} marginTop={"15px"}>
<HelpBox
title={"Learn more about ACCESS KEYS"}
iconComponent={<AccountIcon />}
help={
<Fragment>
MinIO access keys are child identities of an authenticated MinIO
user, including externally managed identities. Each access key
inherits its privileges based on the policies attached to its
parent user or those groups in which the parent user has
membership. Access Keys also support an optional inline policy
which further restricts access to a subset of actions and
resources available to the parent user.
<br />
<br />
You can learn more at our{" "}
{
// TODO: Change this link once it is called access keys
}
<a
href="https://min.io/docs/minio/linux/administration/identity-access-management/minio-user-management.html?ref=con#service-accounts"
target="_blank"
rel="noopener"
>
documentation
</a>
.
</Fragment>
}
/>
<Box
sx={{
display: "flex",
}}
>
{" "}
<TooltipWrapper tooltip={"Delete Selected"}>
<Button
id={"delete-selected-accounts"}
onClick={() => {
setDeleteMultipleOpen(true);
}}
label={"Delete Selected"}
icon={<DeleteIcon />}
disabled={selectedSAs.length === 0}
variant={"secondary"}
/>
</TooltipWrapper>
<SecureComponent
scopes={[IAM_SCOPES.ADMIN_CREATE_USER]}
resource={CONSOLE_UI_RESOURCE}
matchAll
errorProps={{ disabled: true }}
>
<Button
id={"change-password"}
onClick={() => setChangePasswordModalOpen(true)}
label={`Change Password`}
icon={<PasswordKeyIcon />}
variant={"regular"}
disabled={userIDP}
/>
</SecureComponent>
<Button
id={"create-service-account"}
onClick={() => {
navigate(`${IAM_PAGES.ACCOUNT_ADD}`);
}}
label={`Create access key`}
icon={<AddIcon />}
variant={"callAction"}
/>
</Box>
</Grid>
<Grid item xs={12} className={classes.tableBlock}>
<TableWrapper
isLoading={loading}
records={filteredRecords}
entityName={"Access Keys"}
idField={""}
columns={[{ label: "Access Key", elementKey: "" }]}
itemActions={tableActions}
selectedItems={selectedSAs}
onSelect={(e) => selectSAs(e, setSelectedSAs, selectedSAs)}
onSelectAll={selectAllItems}
/>
</Grid>
<Grid item xs={12} marginTop={"15px"}>
<HelpBox
title={"Learn more about ACCESS KEYS"}
iconComponent={<AccountIcon />}
help={
<Fragment>
MinIO access keys are child identities of an authenticated
MinIO user, including externally managed identities. Each
access key inherits its privileges based on the policies
attached to its parent user or those groups in which the
parent user has membership. Access Keys also support an
optional inline policy which further restricts access to a
subset of actions and resources available to the parent user.
<br />
<br />
You can learn more at our{" "}
{
// TODO: Change this link once it is called access keys
}
<a
href="https://min.io/docs/minio/linux/administration/identity-access-management/minio-user-management.html?ref=con#service-accounts"
target="_blank"
rel="noopener"
>
documentation
</a>
.
</Fragment>
}
/>
</Grid>
</Grid>
</PageLayout>
</React.Fragment>

View File

@@ -21,6 +21,7 @@ import {
BackLink,
Button,
IAMPoliciesIcon,
PageLayout,
PasswordKeyIcon,
ServiceAccountCredentialsIcon,
} from "mds";
@@ -33,7 +34,6 @@ import {
import Grid from "@mui/material/Grid";
import { Box } from "@mui/material";
import CodeMirrorWrapper from "../Common/FormComponents/CodeMirrorWrapper/CodeMirrorWrapper";
import PageLayout from "../Common/Layout/PageLayout";
import InputBoxWrapper from "../Common/FormComponents/InputBoxWrapper/InputBoxWrapper";
import FormSwitchWrapper from "../Common/FormComponents/FormSwitchWrapper/FormSwitchWrapper";
import AddServiceAccountHelpBox from "./AddServiceAccountHelpBox";

View File

@@ -28,6 +28,7 @@ import {
BucketsIcon,
Button,
FolderIcon,
PageLayout,
RefreshIcon,
TrashIcon,
} from "mds";
@@ -54,7 +55,6 @@ import {
IAM_SCOPES,
permissionTooltipHelper,
} from "../../../../common/SecureComponent/permissions";
import PageLayout from "../../Common/Layout/PageLayout";
import VerticalTabs from "../../Common/VerticalTabs/VerticalTabs";
import {

View File

@@ -26,6 +26,7 @@ import {
FormLayout,
HelpBox,
InfoIcon,
PageLayout,
} from "mds";
import {
containerForHeader,
@@ -42,7 +43,6 @@ import {
selSiteRep,
setErrorSnackMessage,
} from "../../../../../systemSlice";
import PageLayout from "../../../Common/Layout/PageLayout";
import InputUnitMenu from "../../../Common/FormComponents/InputUnitMenu/InputUnitMenu";
import TooltipWrapper from "../../../Common/TooltipWrapper/TooltipWrapper";
import SectionTitle from "../../../Common/SectionTitle";

View File

@@ -25,6 +25,7 @@ import {
HelpBox,
LifecycleConfigIcon,
MultipleBucketsIcon,
PageLayout,
RefreshIcon,
SelectAllIcon,
SelectMultipleIcon,
@@ -48,7 +49,6 @@ import {
IAM_SCOPES,
permissionTooltipHelper,
} from "../../../../common/SecureComponent/permissions";
import PageLayout from "../../Common/Layout/PageLayout";
import SearchBox from "../../Common/SearchBox";
import VirtualizedList from "../../Common/VirtualizedList/VirtualizedList";
import BulkLifecycleModal from "./BulkLifecycleModal";

View File

@@ -34,6 +34,7 @@ import {
DeleteIcon,
DownloadIcon,
HistoryIcon,
PageLayout,
PreviewIcon,
RefreshIcon,
ShareIcon,
@@ -69,7 +70,6 @@ import {
import ScreenTitle from "../../../../Common/ScreenTitle/ScreenTitle";
import { AppState, useAppDispatch } from "../../../../../../store";
import PageLayout from "../../../../Common/Layout/PageLayout";
import {
IAM_SCOPES,
permissionTooltipHelper,
@@ -968,261 +968,277 @@ const ListObjects = () => {
)}
<PageLayout variant={"full"}>
{anonymousMode && (
<div style={{ paddingBottom: 16 }}>
<FilterObjectsSB />
</div>
)}
<Grid item xs={12} className={classes.screenTitleContainer}>
<ScreenTitle
icon={
<span>
<BucketsIcon style={{ width: 30 }} />
</span>
}
title={<span className={classes.titleSpacer}>{bucketName}</span>}
subTitle={
!anonymousMode ? (
<Fragment>
<Grid item xs={12} className={classes.bucketDetails}>
<span className={classes.detailsSpacer}>
Created on:&nbsp;&nbsp;
<strong>
{bucketInfo?.creation_date
? createdTime.toFormat(
"ccc, LLL dd yyyy HH:mm:ss (ZZZZ)"
)
: ""}
</strong>
</span>
<span className={classes.detailsSpacer}>
Access:&nbsp;&nbsp;&nbsp;
<strong>{bucketInfo?.access || ""}</strong>
</span>
{bucketInfo && (
<Fragment>
<span className={classes.detailsSpacer}>
{bucketInfo.size && (
<Fragment>{niceBytesInt(bucketInfo.size)}</Fragment>
)}
{bucketInfo.size && quota && (
<Fragment> / {niceBytesInt(quota.quota)}</Fragment>
)}
{bucketInfo.size && bucketInfo.objects ? " - " : ""}
{bucketInfo.objects && (
<Fragment>
{bucketInfo.objects}&nbsp;Object
{bucketInfo.objects && bucketInfo.objects !== 1
? "s"
: ""}
</Fragment>
)}
</span>
</Fragment>
)}
</Grid>
</Fragment>
) : null
}
actions={
<div className={classes.actionsSection}>
{!anonymousMode && (
<TooltipWrapper tooltip={"Rewind Bucket"}>
<Grid container spacing={1}>
{anonymousMode && (
<div style={{ paddingBottom: 16 }}>
<FilterObjectsSB />
</div>
)}
<Grid item xs={12} className={classes.screenTitleContainer}>
<ScreenTitle
icon={
<span>
<BucketsIcon style={{ width: 30 }} />
</span>
}
title={<span className={classes.titleSpacer}>{bucketName}</span>}
subTitle={
!anonymousMode ? (
<Fragment>
<Grid item xs={12} className={classes.bucketDetails}>
<span className={classes.detailsSpacer}>
Created on:&nbsp;&nbsp;
<strong>
{bucketInfo?.creation_date
? createdTime.toFormat(
"ccc, LLL dd yyyy HH:mm:ss (ZZZZ)"
)
: ""}
</strong>
</span>
<span className={classes.detailsSpacer}>
Access:&nbsp;&nbsp;&nbsp;
<strong>{bucketInfo?.access || ""}</strong>
</span>
{bucketInfo && (
<Fragment>
<span className={classes.detailsSpacer}>
{bucketInfo.size && (
<Fragment>
{niceBytesInt(bucketInfo.size)}
</Fragment>
)}
{bucketInfo.size && quota && (
<Fragment>
{" "}
/ {niceBytesInt(quota.quota)}
</Fragment>
)}
{bucketInfo.size && bucketInfo.objects ? " - " : ""}
{bucketInfo.objects && (
<Fragment>
{bucketInfo.objects}&nbsp;Object
{bucketInfo.objects && bucketInfo.objects !== 1
? "s"
: ""}
</Fragment>
)}
</span>
</Fragment>
)}
</Grid>
</Fragment>
) : null
}
actions={
<div className={classes.actionsSection}>
{!anonymousMode && (
<TooltipWrapper tooltip={"Rewind Bucket"}>
<Button
id={"rewind-objects-list"}
label={"Rewind"}
icon={
<Badge
badgeContent=" "
color="secondary"
variant="dot"
invisible={!rewindEnabled}
className={classes.badgeOverlap}
sx={{ height: 16 }}
>
<HistoryIcon
style={{
minWidth: 16,
minHeight: 16,
width: 16,
height: 16,
marginTop: -3,
}}
/>
</Badge>
}
variant={"regular"}
onClick={() => {
setRewindSelect(true);
}}
disabled={
!isVersioned ||
!hasPermission(bucketName, [
IAM_SCOPES.S3_GET_OBJECT,
IAM_SCOPES.S3_GET_ACTIONS,
])
}
sx={regularButtonOverride}
/>
</TooltipWrapper>
)}
<TooltipWrapper tooltip={"Reload List"}>
<Button
id={"rewind-objects-list"}
label={"Rewind"}
icon={
<Badge
badgeContent=" "
color="secondary"
variant="dot"
invisible={!rewindEnabled}
className={classes.badgeOverlap}
sx={{ height: 16 }}
>
<HistoryIcon
style={{
minWidth: 16,
minHeight: 16,
width: 16,
height: 16,
marginTop: -3,
}}
/>
</Badge>
}
id={"refresh-objects-list"}
label={"Refresh"}
icon={<RefreshIcon />}
variant={"regular"}
onClick={() => {
setRewindSelect(true);
if (versionsMode) {
dispatch(setLoadingVersions(true));
} else {
dispatch(resetMessages());
dispatch(setLoadingRecords(true));
dispatch(setLoadingObjects(true));
}
}}
disabled={
!isVersioned ||
!hasPermission(bucketName, [
IAM_SCOPES.S3_GET_OBJECT,
IAM_SCOPES.S3_GET_ACTIONS,
])
anonymousMode
? false
: !hasPermission(bucketName, [
IAM_SCOPES.S3_LIST_BUCKET,
IAM_SCOPES.S3_ALL_LIST_BUCKET,
]) || rewindEnabled
}
sx={regularButtonOverride}
/>
</TooltipWrapper>
)}
<TooltipWrapper tooltip={"Reload List"}>
<Button
id={"refresh-objects-list"}
label={"Refresh"}
icon={<RefreshIcon />}
variant={"regular"}
onClick={() => {
if (versionsMode) {
dispatch(setLoadingVersions(true));
} else {
dispatch(resetMessages());
dispatch(setLoadingRecords(true));
dispatch(setLoadingObjects(true));
}
}}
disabled={
anonymousMode
? false
: !hasPermission(bucketName, [
IAM_SCOPES.S3_LIST_BUCKET,
IAM_SCOPES.S3_ALL_LIST_BUCKET,
]) || rewindEnabled
}
sx={regularButtonOverride}
<input
type="file"
multiple
onChange={handleUploadButton}
style={{ display: "none" }}
ref={fileUpload}
/>
</TooltipWrapper>
<input
type="file"
multiple
onChange={handleUploadButton}
style={{ display: "none" }}
ref={fileUpload}
/>
<input
type="file"
multiple
onChange={handleUploadButton}
style={{ display: "none" }}
ref={folderUpload}
/>
<UploadFilesButton
bucketName={bucketName}
uploadPath={uploadPath.join("/")}
uploadFileFunction={(closeMenu) => {
if (fileUpload && fileUpload.current) {
fileUpload.current.click();
}
closeMenu();
}}
uploadFolderFunction={(closeMenu) => {
if (folderUpload && folderUpload.current) {
folderUpload.current.click();
}
closeMenu();
}}
overrideStyles={callActionButtonOverride}
/>
</div>
}
/>
</Grid>
<div
id="object-list-wrapper"
{...getRootProps({ style: { ...dndStyles } })}
>
<input {...getInputProps()} />
<Grid
item
xs={12}
className={classes.tableBlock}
sx={{ border: "#EAEDEE 1px solid", borderTop: 0 }}
>
{versionsMode ? (
<Fragment>
{selectedInternalPaths !== null && (
<VersionsNavigator
internalPaths={selectedInternalPaths}
<input
type="file"
multiple
onChange={handleUploadButton}
style={{ display: "none" }}
ref={folderUpload}
/>
<UploadFilesButton
bucketName={bucketName}
uploadPath={uploadPath.join("/")}
uploadFileFunction={(closeMenu) => {
if (fileUpload && fileUpload.current) {
fileUpload.current.click();
}
closeMenu();
}}
uploadFolderFunction={(closeMenu) => {
if (folderUpload && folderUpload.current) {
folderUpload.current.click();
}
closeMenu();
}}
overrideStyles={callActionButtonOverride}
/>
)}
</Fragment>
) : (
<SecureComponent
scopes={[
IAM_SCOPES.S3_LIST_BUCKET,
IAM_SCOPES.S3_ALL_LIST_BUCKET,
]}
resource={bucketName}
errorProps={{ disabled: true }}
>
<Grid item xs={12} className={classes.fullContainer}>
{!anonymousMode && (
<Grid item xs={12} className={classes.breadcrumbsContainer}>
<BrowserBreadcrumbs
bucketName={bucketName}
internalPaths={pageTitle}
additionalOptions={
!isVersioned || rewindEnabled ? null : (
<div>
<CheckboxWrapper
name={"deleted_objects"}
id={"showDeletedObjects"}
value={"deleted_on"}
label={"Show deleted objects"}
onChange={setDeletedAction}
checked={showDeleted}
overrideLabelClasses={classes.labelStyle}
className={classes.overrideShowDeleted}
noTopMargin
/>
</div>
)
}
hidePathButton={false}
/>
</Grid>
)}
<ListObjectsTable internalPaths={selectedInternalPaths} />
</Grid>
</SecureComponent>
)}
{!anonymousMode && (
<SecureComponent
scopes={[
IAM_SCOPES.S3_LIST_BUCKET,
IAM_SCOPES.S3_ALL_LIST_BUCKET,
]}
resource={bucketName}
errorProps={{ disabled: true }}
>
<DetailsListPanel
open={detailsOpen}
closePanel={() => {
onClosePanel(false);
}}
className={`${versionsMode ? classes.hideListOnSmall : ""}`}
>
{selectedObjects.length > 0 && (
<ActionsListSection
items={multiActionButtons}
title={"Selected Objects:"}
/>
)}
{selectedInternalPaths !== null && (
<ObjectDetailPanel
internalPaths={selectedInternalPaths}
bucketName={bucketName}
onClosePanel={onClosePanel}
versioningInfo={isVersioned}
locking={lockingEnabled}
/>
)}
</DetailsListPanel>
</SecureComponent>
)}
</div>
}
/>
</Grid>
</div>
<Grid item xs={12}>
<div
id="object-list-wrapper"
{...getRootProps({ style: { ...dndStyles } })}
>
<input {...getInputProps()} />
<Grid
item
xs={12}
className={classes.tableBlock}
sx={{ border: "#EAEDEE 1px solid", borderTop: 0 }}
>
{versionsMode ? (
<Fragment>
{selectedInternalPaths !== null && (
<VersionsNavigator
internalPaths={selectedInternalPaths}
bucketName={bucketName}
/>
)}
</Fragment>
) : (
<SecureComponent
scopes={[
IAM_SCOPES.S3_LIST_BUCKET,
IAM_SCOPES.S3_ALL_LIST_BUCKET,
]}
resource={bucketName}
errorProps={{ disabled: true }}
>
<Grid item xs={12} className={classes.fullContainer}>
{!anonymousMode && (
<Grid
item
xs={12}
className={classes.breadcrumbsContainer}
>
<BrowserBreadcrumbs
bucketName={bucketName}
internalPaths={pageTitle}
additionalOptions={
!isVersioned || rewindEnabled ? null : (
<div>
<CheckboxWrapper
name={"deleted_objects"}
id={"showDeletedObjects"}
value={"deleted_on"}
label={"Show deleted objects"}
onChange={setDeletedAction}
checked={showDeleted}
overrideLabelClasses={classes.labelStyle}
className={classes.overrideShowDeleted}
noTopMargin
/>
</div>
)
}
hidePathButton={false}
/>
</Grid>
)}
<ListObjectsTable internalPaths={selectedInternalPaths} />
</Grid>
</SecureComponent>
)}
{!anonymousMode && (
<SecureComponent
scopes={[
IAM_SCOPES.S3_LIST_BUCKET,
IAM_SCOPES.S3_ALL_LIST_BUCKET,
]}
resource={bucketName}
errorProps={{ disabled: true }}
>
<DetailsListPanel
open={detailsOpen}
closePanel={() => {
onClosePanel(false);
}}
className={`${
versionsMode ? classes.hideListOnSmall : ""
}`}
>
{selectedObjects.length > 0 && (
<ActionsListSection
items={multiActionButtons}
title={"Selected Objects:"}
/>
)}
{selectedInternalPaths !== null && (
<ObjectDetailPanel
internalPaths={selectedInternalPaths}
bucketName={bucketName}
onClosePanel={onClosePanel}
versioningInfo={isVersioned}
locking={lockingEnabled}
/>
)}
</DetailsListPanel>
</SecureComponent>
)}
</Grid>
</div>
</Grid>
</Grid>
</PageLayout>
</Fragment>
);

View File

@@ -16,9 +16,8 @@
import React, { Fragment, useState } from "react";
import { DialogContentText, Grid } from "@mui/material";
import PageLayout from "./Layout/PageLayout";
import SectionTitle from "./SectionTitle";
import { Button, ConfirmDeleteIcon } from "mds";
import { Button, ConfirmDeleteIcon, PageLayout } from "mds";
import ConfirmDialog from "./ModalWrapper/ConfirmDialog";
import PageHeaderWrapper from "./PageHeaderWrapper/PageHeaderWrapper";

View File

@@ -1,33 +0,0 @@
import React from "react";
import { Grid } from "@mui/material";
type PageLayoutProps = {
className?: string;
variant?: "constrained" | "full";
children: any;
noPadding?: boolean;
};
const PageLayout = ({
className = "",
children,
variant = "constrained",
noPadding = false,
}: PageLayoutProps) => {
let style = variant === "constrained" ? { maxWidth: 1220 } : {};
return (
<div
style={{
padding: noPadding ? 0 : "2rem",
}}
>
<Grid container>
<Grid item xs={12} className={className} style={style}>
{children}
</Grid>
</Grid>
</div>
);
};
export default PageLayout;

View File

@@ -26,10 +26,9 @@ import {
containerForHeader,
searchField,
} from "../../Common/FormComponents/common/styleLibrary";
import { HelpBox, SettingsIcon } from "mds";
import { HelpBox, PageLayout, SettingsIcon } from "mds";
import { Link, Navigate, Route, Routes, useLocation } from "react-router-dom";
import VerticalTabs from "../../Common/VerticalTabs/VerticalTabs";
import PageLayout from "../../Common/Layout/PageLayout";
import ScreenTitle from "../../Common/ScreenTitle/ScreenTitle";
import ConfigurationForm from "./ConfigurationForm";
import { IAM_PAGES } from "../../../../common/SecureComponent/permissions";

View File

@@ -18,10 +18,9 @@ import React, { Fragment, useEffect, useState } from "react";
import Grid from "@mui/material/Grid";
import { Box, LinearProgress } from "@mui/material";
import { useNavigate } from "react-router-dom";
import { BackLink, Button, ClustersIcon, HelpBox } from "mds";
import { BackLink, Button, ClustersIcon, HelpBox, PageLayout } from "mds";
import useApi from "../../Common/Hooks/useApi";
import { IAM_PAGES } from "../../../../common/SecureComponent/permissions";
import PageLayout from "../../Common/Layout/PageLayout";
import SectionTitle from "../../Common/SectionTitle";
import {
setErrorSnackMessage,

View File

@@ -18,7 +18,6 @@ import React, { Fragment, useEffect, useState } from "react";
import { useNavigate } from "react-router-dom";
import { Box, DialogContentText, Grid } from "@mui/material";
import PageLayout from "../../Common/Layout/PageLayout";
import useApi from "../../Common/Hooks/useApi";
import ReplicationSites from "./ReplicationSites";
import {
@@ -28,6 +27,7 @@ import {
ConfirmDeleteIcon,
HelpBox,
Loader,
PageLayout,
RecoverIcon,
TrashIcon,
} from "mds";

View File

@@ -23,10 +23,10 @@ import {
GroupsIcon,
IAMPoliciesIcon,
Loader,
PageLayout,
RefreshIcon,
UsersIcon,
} from "mds";
import PageLayout from "../../Common/Layout/PageLayout";
import useApi from "../../Common/Hooks/useApi";
import { IAM_PAGES } from "../../../../common/SecureComponent/permissions";

View File

@@ -20,7 +20,7 @@ import { useNavigate, useParams } from "react-router-dom";
import get from "lodash/get";
import Grid from "@mui/material/Grid";
import { Theme } from "@mui/material/styles";
import { BackLink, Button } from "mds";
import { BackLink, Button, PageLayout } from "mds";
import createStyles from "@mui/styles/createStyles";
import withStyles from "@mui/styles/withStyles";
import { Box } from "@mui/material";
@@ -42,7 +42,6 @@ import {
tierTypes,
} from "./utils";
import PageLayout from "../../Common/Layout/PageLayout";
import { IAM_PAGES } from "../../../../common/SecureComponent/permissions";
import RegionSelectWrapper from "./RegionSelectWrapper";

View File

@@ -25,6 +25,7 @@ import {
AddIcon,
Button,
HelpBox,
PageLayout,
RefreshIcon,
TierOfflineIcon,
TierOnlineIcon,
@@ -46,7 +47,6 @@ import { ErrorResponseHandler } from "../../../../common/types";
import api from "../../../../common/api";
import TableWrapper from "../../Common/TableWrapper/TableWrapper";
import AButton from "../../Common/AButton/AButton";
import PageLayout from "../../Common/Layout/PageLayout";
import SearchBox from "../../Common/SearchBox";
import withSuspense from "../../Common/Components/withSuspense";

View File

@@ -19,9 +19,8 @@ import { useNavigate } from "react-router-dom";
import { Box } from "@mui/material";
import { tierTypes } from "./utils";
import { IAM_PAGES } from "../../../../common/SecureComponent/permissions";
import PageLayout from "../../Common/Layout/PageLayout";
import TierTypeCard from "./TierTypeCard";
import { BackLink, FormLayout, HelpBox, TiersIcon } from "mds";
import { BackLink, FormLayout, HelpBox, PageLayout, TiersIcon } from "mds";
import PageHeaderWrapper from "../../Common/PageHeaderWrapper/PageHeaderWrapper";
const TierTypeSelector = () => {

View File

@@ -41,10 +41,15 @@ import {
trafficPanelsLayout,
} from "./Widgets/LayoutUtil";
import MergedWidgetsRenderer from "./Widgets/MergedWidgetsRenderer";
import PageLayout from "../../Common/Layout/PageLayout";
import { Usage } from "../types";
import BasicDashboard from "../BasicDashboard/BasicDashboard";
import { Button, HelpBox, PrometheusErrorIcon, SyncIcon } from "mds";
import {
Button,
HelpBox,
PageLayout,
PrometheusErrorIcon,
SyncIcon,
} from "mds";
import { ITabOption } from "../../Common/TabSelector/types";
import { getUsageAsync } from "../dashboardThunks";
import { reloadWidgets } from "../dashboardSlice";
@@ -180,7 +185,11 @@ const PrDashboard = ({ apiPrefix = "admin", usage }: IPrDashboard) => {
}
return (
<PageLayout noPadding={hideMenu}>
<PageLayout
sx={{
padding: hideMenu ? 0 : "2rem",
}}
>
{zoomOpen && (
<ZoomWidget
modalOpen={zoomOpen}

View File

@@ -21,7 +21,7 @@ import Grid from "@mui/material/Grid";
import { Theme } from "@mui/material/styles";
import createStyles from "@mui/styles/createStyles";
import withStyles from "@mui/styles/withStyles";
import { BackLink, Button } from "mds";
import { BackLink, Button, PageLayout } from "mds";
import api from "../../../common/api";
import {
@@ -41,7 +41,6 @@ import { IElementValue } from "../Configurations/types";
import withSuspense from "../Common/Components/withSuspense";
import PageLayout from "../Common/Layout/PageLayout";
import { IAM_PAGES } from "../../../common/SecureComponent/permissions";
import {
setErrorSnackMessage,

View File

@@ -24,11 +24,10 @@ import {
settingsCommon,
typesSelection,
} from "../Common/FormComponents/common/styleLibrary";
import PageLayout from "../Common/Layout/PageLayout";
import { IAM_PAGES } from "../../../common/SecureComponent/permissions";
import { Box } from "@mui/material";
import NotificationEndpointTypeSelectorHelpBox from "../Account/NotificationEndpointTypeSelectorHelpBox";
import { BackLink } from "mds";
import { BackLink, PageLayout } from "mds";
import PageHeaderWrapper from "../Common/PageHeaderWrapper/PageHeaderWrapper";
interface INotificationTypeSelector {

View File

@@ -15,7 +15,14 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import React, { Fragment, useEffect, useState } from "react";
import { AddIcon, Button, HelpBox, LambdaIcon, RefreshIcon } from "mds";
import {
AddIcon,
Button,
HelpBox,
LambdaIcon,
PageLayout,
RefreshIcon,
} from "mds";
import { useNavigate } from "react-router-dom";
import { Theme } from "@mui/material/styles";
import createStyles from "@mui/styles/createStyles";
@@ -42,7 +49,6 @@ import {
import { ErrorResponseHandler } from "../../../common/types";
import api from "../../../common/api";
import AButton from "../Common/AButton/AButton";
import PageLayout from "../Common/Layout/PageLayout";
import SearchBox from "../Common/SearchBox";
import { IAM_PAGES } from "../../../common/SecureComponent/permissions";

View File

@@ -25,8 +25,7 @@ import {
} from "../Common/FormComponents/common/styleLibrary";
import Grid from "@mui/material/Grid";
import { LinearProgress } from "@mui/material";
import { BackLink, Button, CreateGroupIcon, FormLayout } from "mds";
import PageLayout from "../Common/Layout/PageLayout";
import { BackLink, Button, CreateGroupIcon, FormLayout, PageLayout } from "mds";
import InputBoxWrapper from "../Common/FormComponents/InputBoxWrapper/InputBoxWrapper";
import AddGroupHelpBox from "./AddGroupHelpBox";
import UsersSelectors from "./UsersSelectors";

View File

@@ -24,6 +24,7 @@ import {
GroupsIcon,
HelpBox,
IAMPoliciesIcon,
PageLayout,
UsersIcon,
} from "mds";
import createStyles from "@mui/styles/createStyles";
@@ -43,7 +44,6 @@ import { ErrorResponseHandler } from "../../../common/types";
import api from "../../../common/api";
import TableWrapper from "../Common/TableWrapper/TableWrapper";
import AButton from "../Common/AButton/AButton";
import PageLayout from "../Common/Layout/PageLayout";
import SearchBox from "../Common/SearchBox";
import {
applyPolicyPermissions,
@@ -225,119 +225,110 @@ const Groups = ({ classes }: IGroupsProps) => {
<PageHeaderWrapper label={"Groups"} />
<PageLayout>
<Grid item xs={12} className={classes.actionsTray}>
<SecureComponent
resource={CONSOLE_UI_RESOURCE}
scopes={displayGroupsPermissions}
errorProps={{ disabled: true }}
>
<SearchBox
placeholder={"Search Groups"}
onChange={setFilter}
overrideClass={classes.searchField}
value={filter}
/>
</SecureComponent>
<Box
sx={{
display: "flex",
}}
>
<Grid container spacing={1}>
<Grid item xs={12} className={classes.actionsTray}>
<SecureComponent
resource={CONSOLE_UI_RESOURCE}
scopes={applyPolicyPermissions}
matchAll
scopes={displayGroupsPermissions}
errorProps={{ disabled: true }}
>
<TooltipWrapper
tooltip={
checkedGroups.length < 1
? "Please select Groups on which you want to apply Policies"
: applyPolicy
? "Select Policy"
: permissionTooltipHelper(
applyPolicyPermissions,
"apply policies to Groups"
)
}
<SearchBox
placeholder={"Search Groups"}
onChange={setFilter}
overrideClass={classes.searchField}
value={filter}
/>
</SecureComponent>
<Box
sx={{
display: "flex",
}}
>
<SecureComponent
resource={CONSOLE_UI_RESOURCE}
scopes={applyPolicyPermissions}
matchAll
errorProps={{ disabled: true }}
>
<Button
id={"assign-policy"}
onClick={() => {
setPolicyOpen(true);
}}
label={"Assign Policy"}
icon={<IAMPoliciesIcon />}
disabled={checkedGroups.length < 1 || !applyPolicy}
variant={"regular"}
/>
</TooltipWrapper>
</SecureComponent>
<SecureComponent
resource={CONSOLE_UI_RESOURCE}
scopes={deleteGroupPermissions}
matchAll
errorProps={{ disabled: true }}
>
<TooltipWrapper
tooltip={
checkedGroups.length === 0
? "Select Groups to delete"
: getGroup
? "Delete Selected"
: permissionTooltipHelper(
getGroupPermissions,
"delete Groups"
)
}
>
<Button
id="delete-selected-groups"
onClick={() => {
setDeleteOpen(true);
}}
label={"Delete Selected"}
icon={<DeleteIcon />}
variant="secondary"
disabled={checkedGroups.length === 0 || !getGroup}
/>
</TooltipWrapper>
</SecureComponent>
<SecureComponent
resource={CONSOLE_UI_RESOURCE}
scopes={createGroupPermissions}
matchAll
errorProps={{ disabled: true }}
>
<TooltipWrapper tooltip={"Create Group"}>
<Button
id={"create-group"}
label={"Create Group"}
variant="callAction"
icon={<AddIcon />}
onClick={() => {
navigate(`${IAM_PAGES.GROUPS_ADD}`);
}}
/>
</TooltipWrapper>
</SecureComponent>
</Box>
</Grid>
{loading && <LinearProgress />}
{!loading && (
<Fragment>
{records.length > 0 && (
<Fragment>
<TooltipWrapper
tooltip={
getGroup
? ""
checkedGroups.length < 1
? "Please select Groups on which you want to apply Policies"
: applyPolicy
? "Select Policy"
: permissionTooltipHelper(
getGroupPermissions,
"view Group details"
applyPolicyPermissions,
"apply policies to Groups"
)
}
>
<Button
id={"assign-policy"}
onClick={() => {
setPolicyOpen(true);
}}
label={"Assign Policy"}
icon={<IAMPoliciesIcon />}
disabled={checkedGroups.length < 1 || !applyPolicy}
variant={"regular"}
/>
</TooltipWrapper>
</SecureComponent>
<SecureComponent
resource={CONSOLE_UI_RESOURCE}
scopes={deleteGroupPermissions}
matchAll
errorProps={{ disabled: true }}
>
<TooltipWrapper
tooltip={
checkedGroups.length === 0
? "Select Groups to delete"
: getGroup
? "Delete Selected"
: permissionTooltipHelper(
getGroupPermissions,
"delete Groups"
)
}
>
<Button
id="delete-selected-groups"
onClick={() => {
setDeleteOpen(true);
}}
label={"Delete Selected"}
icon={<DeleteIcon />}
variant="secondary"
disabled={checkedGroups.length === 0 || !getGroup}
/>
</TooltipWrapper>
</SecureComponent>
<SecureComponent
resource={CONSOLE_UI_RESOURCE}
scopes={createGroupPermissions}
matchAll
errorProps={{ disabled: true }}
>
<TooltipWrapper tooltip={"Create Group"}>
<Button
id={"create-group"}
label={"Create Group"}
variant="callAction"
icon={<AddIcon />}
onClick={() => {
navigate(`${IAM_PAGES.GROUPS_ADD}`);
}}
/>
</TooltipWrapper>
</SecureComponent>
</Box>
</Grid>
{loading && <LinearProgress />}
{!loading && (
<Fragment>
{records.length > 0 && (
<Fragment>
<Grid item xs={12} className={classes.tableBlock}>
<SecureComponent
resource={CONSOLE_UI_RESOURCE}
@@ -358,76 +349,76 @@ const Groups = ({ classes }: IGroupsProps) => {
/>
</SecureComponent>
</Grid>
</TooltipWrapper>
<Grid item xs={12} marginTop={"25px"}>
<HelpBox
title={"Groups"}
iconComponent={<GroupsIcon />}
help={
<Fragment>
A group can have one attached IAM policy, where all
users with membership in that group inherit that policy.
Groups support more simplified management of user
permissions on the MinIO Tenant.
<br />
<br />
You can learn more at our{" "}
<a
href="https://min.io/docs/minio/linux/administration/identity-access-management/minio-group-management.html?ref=con"
target="_blank"
rel="noopener"
>
documentation
</a>
.
</Fragment>
}
/>
</Grid>
</Fragment>
)}
{records.length === 0 && (
<Grid
container
justifyContent={"center"}
alignContent={"center"}
alignItems={"center"}
>
<Grid item xs={8}>
<HelpBox
title={"Groups"}
iconComponent={<UsersIcon />}
help={
<Fragment>
A group can have one attached IAM policy, where all
users with membership in that group inherit that policy.
Groups support more simplified management of user
permissions on the MinIO Tenant.
<SecureComponent
resource={CONSOLE_UI_RESOURCE}
scopes={createGroupPermissions}
matchAll
>
<Grid item xs={12} marginTop={"25px"}>
<HelpBox
title={"Groups"}
iconComponent={<GroupsIcon />}
help={
<Fragment>
A group can have one attached IAM policy, where all
users with membership in that group inherit that
policy. Groups support more simplified management of
user permissions on the MinIO Tenant.
<br />
<br />
To get started,{" "}
<AButton
onClick={() => {
navigate(`${IAM_PAGES.GROUPS_ADD}`);
}}
You can learn more at our{" "}
<a
href="https://min.io/docs/minio/linux/administration/identity-access-management/minio-group-management.html?ref=con"
target="_blank"
rel="noopener"
>
Create a Group
</AButton>
documentation
</a>
.
</SecureComponent>
</Fragment>
}
/>
</Fragment>
}
/>
</Grid>
</Fragment>
)}
{records.length === 0 && (
<Grid
container
justifyContent={"center"}
alignContent={"center"}
alignItems={"center"}
>
<Grid item xs={8}>
<HelpBox
title={"Groups"}
iconComponent={<UsersIcon />}
help={
<Fragment>
A group can have one attached IAM policy, where all
users with membership in that group inherit that
policy. Groups support more simplified management of
user permissions on the MinIO Tenant.
<SecureComponent
resource={CONSOLE_UI_RESOURCE}
scopes={createGroupPermissions}
matchAll
>
<br />
<br />
To get started,{" "}
<AButton
onClick={() => {
navigate(`${IAM_PAGES.GROUPS_ADD}`);
}}
>
Create a Group
</AButton>
.
</SecureComponent>
</Fragment>
}
/>
</Grid>
</Grid>
</Grid>
)}
</Fragment>
)}
)}
</Fragment>
)}
</Grid>
</PageLayout>
</Fragment>
);

View File

@@ -1,7 +1,14 @@
import React, { Fragment, useEffect, useState } from "react";
import { Theme } from "@mui/material/styles";
import { useNavigate, useParams } from "react-router-dom";
import { AddIcon, Button, GroupsIcon, IAMPoliciesIcon, TrashIcon } from "mds";
import {
AddIcon,
Button,
GroupsIcon,
IAMPoliciesIcon,
PageLayout,
TrashIcon,
} from "mds";
import createStyles from "@mui/styles/createStyles";
import {
actionsTray,
@@ -22,7 +29,6 @@ import { ErrorResponseHandler } from "../../../common/types";
import DeleteGroup from "./DeleteGroup";
import VerticalTabs from "../Common/VerticalTabs/VerticalTabs";
import FormSwitchWrapper from "../Common/FormComponents/FormSwitchWrapper/FormSwitchWrapper";
import PageLayout from "../Common/Layout/PageLayout";
import PanelTitle from "../Common/PanelTitle/PanelTitle";
import SearchBox from "../Common/SearchBox";
import {
@@ -243,7 +249,7 @@ const GroupsDetails = ({ classes }: IGroupDetailsProps) => {
</SecureComponent>
</div>
<div className={classes.tableBlock}>
<Grid item xs={12}>
<SecureComponent
resource={CONSOLE_UI_RESOURCE}
scopes={listUsersPermissions}
@@ -275,7 +281,7 @@ const GroupsDetails = ({ classes }: IGroupDetailsProps) => {
}
/>
</SecureComponent>
</div>
</Grid>
</React.Fragment>
);
@@ -305,7 +311,7 @@ const GroupsDetails = ({ classes }: IGroupDetailsProps) => {
/>
</TooltipWrapper>
</div>
<div className={classes.tableBlock}>
<Grid item xs={12}>
<TableWrapper
itemActions={[
{
@@ -330,7 +336,7 @@ const GroupsDetails = ({ classes }: IGroupDetailsProps) => {
)
}
/>
</div>
</Grid>
</React.Fragment>
);
return (

View File

@@ -26,7 +26,7 @@ import {
} from "@mui/material";
import { IMessageEvent, w3cwebsocket as W3CWebSocket } from "websocket";
import { Theme } from "@mui/material/styles";
import { Button, HealIcon } from "mds";
import { Button, HealIcon, PageLayout } from "mds";
import createStyles from "@mui/styles/createStyles";
import withStyles from "@mui/styles/withStyles";
import { wsProtocol } from "../../../utils/wsUtils";
@@ -46,7 +46,6 @@ import {
import { ErrorResponseHandler } from "../../../common/types";
import CheckboxWrapper from "../Common/FormComponents/CheckboxWrapper/CheckboxWrapper";
import api from "../../../common/api";
import PageLayout from "../Common/Layout/PageLayout";
import { SecureComponent } from "../../../common/SecureComponent";
import DistributedOnly from "../Common/DistributedOnly/DistributedOnly";
import { selDistSet } from "../../../systemSlice";

View File

@@ -23,7 +23,7 @@ import {
import { AppState, useAppDispatch } from "../../../store";
import { useSelector } from "react-redux";
import { useNavigate } from "react-router-dom";
import { Box, Button, Grid, HelpBox, InfoIcon, Loader } from "mds";
import { Box, Button, Grid, HelpBox, InfoIcon, Loader, PageLayout } from "mds";
import {
DiagStatError,
DiagStatInProgress,
@@ -46,7 +46,6 @@ import {
} from "../Common/FormComponents/common/styleLibrary";
import TestWrapper from "../Common/TestWrapper/TestWrapper";
import PageLayout from "../Common/Layout/PageLayout";
import { setServerDiagStat } from "../../../systemSlice";
import {
healthInfoMessageReceived,

View File

@@ -25,7 +25,7 @@ import {
modalBasic,
} from "../Common/FormComponents/common/styleLibrary";
import InputBoxWrapper from "../Common/FormComponents/InputBoxWrapper/InputBoxWrapper";
import { BackLink, Button } from "mds";
import { BackLink, Button, PageLayout } from "mds";
import { useNavigate } from "react-router-dom";
import { ErrorResponseHandler } from "../../../common/types";
import { useAppDispatch } from "../../../store";
@@ -34,7 +34,6 @@ import {
setServerNeedsRestart,
} from "../../../systemSlice";
import useApi from "../Common/Hooks/useApi";
import PageLayout from "../Common/Layout/PageLayout";
import SectionTitle from "../Common/SectionTitle";
import FormSwitchWrapper from "../Common/FormComponents/FormSwitchWrapper/FormSwitchWrapper";
import PageHeaderWrapper from "../Common/PageHeaderWrapper/PageHeaderWrapper";

View File

@@ -26,7 +26,14 @@ import {
modalBasic,
searchField,
} from "../Common/FormComponents/common/styleLibrary";
import { BackLink, Button, EditIcon, RefreshIcon, TrashIcon } from "mds";
import {
BackLink,
Button,
EditIcon,
PageLayout,
RefreshIcon,
TrashIcon,
} from "mds";
import InputBoxWrapper from "../Common/FormComponents/InputBoxWrapper/InputBoxWrapper";
import { useNavigate, useParams } from "react-router-dom";
import { ErrorResponseHandler } from "../../../common/types";
@@ -37,7 +44,6 @@ import {
} from "../../../systemSlice";
import useApi from "../Common/Hooks/useApi";
import api from "../../../common/api";
import PageLayout from "../Common/Layout/PageLayout";
import ScreenTitle from "../Common/ScreenTitle/ScreenTitle";
import DeleteIDPConfigurationModal from "./DeleteIDPConfigurationModal";
import FormSwitchWrapper from "../Common/FormComponents/FormSwitchWrapper/FormSwitchWrapper";

View File

@@ -32,11 +32,10 @@ import {
import api from "../../../common/api";
import { ErrorResponseHandler } from "../../../common/types";
import { setErrorSnackMessage } from "../../../systemSlice";
import PageLayout from "../Common/Layout/PageLayout";
import { containerForHeader } from "../Common/FormComponents/common/styleLibrary";
import { Grid } from "@mui/material";
import TooltipWrapper from "../Common/TooltipWrapper/TooltipWrapper";
import { AddIcon, Button, RefreshIcon } from "mds";
import { AddIcon, Button, PageLayout, RefreshIcon } from "mds";
import TableWrapper from "../Common/TableWrapper/TableWrapper";
import DeleteIDPConfigurationModal from "./DeleteIDPConfigurationModal";
import PageHeaderWrapper from "../Common/PageHeaderWrapper/PageHeaderWrapper";

View File

@@ -18,8 +18,7 @@ import React, { useState } from "react";
import { Box } from "@mui/material";
import Grid from "@mui/material/Grid";
import { AddAccessRuleIcon, Button, FormLayout } from "mds";
import PageLayout from "../Common/Layout/PageLayout";
import { AddAccessRuleIcon, Button, FormLayout, PageLayout } from "mds";
import InputBoxWrapper from "../Common/FormComponents/InputBoxWrapper/InputBoxWrapper";
import { ErrorResponseHandler } from "../../../common/types";
import useApi from "../Common/Hooks/useApi";

View File

@@ -18,8 +18,13 @@ import React, { Fragment, useState } from "react";
import { Box } from "@mui/material";
import Grid from "@mui/material/Grid";
import { AddAccessRuleIcon, BackLink, Button, FormLayout } from "mds";
import PageLayout from "../Common/Layout/PageLayout";
import {
AddAccessRuleIcon,
BackLink,
Button,
FormLayout,
PageLayout,
} from "mds";
import InputBoxWrapper from "../Common/FormComponents/InputBoxWrapper/InputBoxWrapper";
import { IAM_PAGES } from "../../../common/SecureComponent/permissions";
import { ErrorResponseHandler } from "../../../common/types";

View File

@@ -16,7 +16,7 @@
import { Grid, Theme } from "@mui/material";
import { createStyles, withStyles } from "@mui/styles";
import { AddIcon, Button, RefreshIcon, UploadIcon } from "mds";
import { AddIcon, Button, PageLayout, RefreshIcon, UploadIcon } from "mds";
import React, { useEffect, useState } from "react";
import { useNavigate } from "react-router-dom";
import api from "../../../common/api";
@@ -37,7 +37,6 @@ import {
containerForHeader,
searchField,
} from "../Common/FormComponents/common/styleLibrary";
import PageLayout from "../Common/Layout/PageLayout";
import SearchBox from "../Common/SearchBox";
import TableWrapper from "../Common/TableWrapper/TableWrapper";
import TooltipWrapper from "../Common/TooltipWrapper/TooltipWrapper";

View File

@@ -16,7 +16,6 @@
import React, { Fragment, useEffect, useState } from "react";
import { Box, Grid } from "@mui/material";
import PageLayout from "../Common/Layout/PageLayout";
import api from "../../../common/api";
import { ErrorResponseHandler } from "../../../common/types";
@@ -46,7 +45,7 @@ import {
XAxis,
YAxis,
} from "recharts";
import { DisabledIcon, EnabledIcon } from "mds";
import { DisabledIcon, EnabledIcon, PageLayout } from "mds";
import PageHeaderWrapper from "../Common/PageHeaderWrapper/PageHeaderWrapper";
const Status = () => {

View File

@@ -19,11 +19,10 @@ import { LinearProgress } from "@mui/material";
import Grid from "@mui/material/Grid";
import { SubnetInfo } from "./types";
import api from "../../../common/api";
import { ArrowIcon, Button } from "mds";
import { ArrowIcon, Button, PageLayout } from "mds";
import { IAM_PAGES } from "../../../common/SecureComponent/permissions";
import LicensePlans from "./LicensePlans";
import { useNavigate } from "react-router-dom";
import PageLayout from "../Common/Layout/PageLayout";
import RegistrationStatusBanner from "../Support/RegistrationStatusBanner";
import withSuspense from "../Common/Components/withSuspense";
import { getLicenseConsent } from "./utils";

View File

@@ -16,7 +16,7 @@
import React, { Fragment, useEffect, useState } from "react";
import { IMessageEvent, w3cwebsocket as W3CWebSocket } from "websocket";
import { Theme } from "@mui/material/styles";
import { Button } from "mds";
import { Button, PageLayout } from "mds";
import createStyles from "@mui/styles/createStyles";
import withStyles from "@mui/styles/withStyles";
import { useSelector } from "react-redux";
@@ -33,7 +33,6 @@ import {
inlineCheckboxes,
searchField,
} from "../../Common/FormComponents/common/styleLibrary";
import PageLayout from "../../Common/Layout/PageLayout";
import SearchBox from "../../Common/SearchBox";
import Paper from "@mui/material/Paper";
import Table from "@mui/material/Table";

View File

@@ -16,7 +16,7 @@
import React, { Fragment, useCallback, useEffect, useState } from "react";
import { useSelector } from "react-redux";
import { Button, SearchIcon } from "mds";
import { Button, PageLayout, SearchIcon } from "mds";
import { Theme } from "@mui/material/styles";
import { Grid } from "@mui/material";
import { DateTime } from "luxon";
@@ -37,7 +37,6 @@ import FilterInputWrapper from "../../Common/FormComponents/FilterInputWrapper/F
import LogSearchFullModal from "./LogSearchFullModal";
import { LogSearchColumnLabels } from "./utils";
import DateRangeSelector from "../../Common/FormComponents/DateRangeSelector/DateRangeSelector";
import PageLayout from "../../Common/Layout/PageLayout";
import ArrowForwardIosIcon from "@mui/icons-material/ArrowForwardIos";
import {
CONSOLE_UI_RESOURCE,

View File

@@ -18,7 +18,7 @@ import React, { Fragment, useEffect, useState } from "react";
import { useNavigate } from "react-router-dom";
import { Theme } from "@mui/material/styles";
import { BucketsIcon, Button, HelpBox, RefreshIcon } from "mds";
import { BucketsIcon, Button, HelpBox, PageLayout, RefreshIcon } from "mds";
import createStyles from "@mui/styles/createStyles";
import { LinearProgress } from "@mui/material";
import Grid from "@mui/material/Grid";
@@ -35,7 +35,6 @@ import {
IAM_SCOPES,
permissionTooltipHelper,
} from "../../../common/SecureComponent/permissions";
import PageLayout from "../Common/Layout/PageLayout";
import SearchBox from "../Common/SearchBox";
import hasPermission from "../../../common/SecureComponent/accessControl";
import { setErrorSnackMessage } from "../../../systemSlice";

View File

@@ -17,8 +17,13 @@
import React, { Fragment, useState } from "react";
import Grid from "@mui/material/Grid";
import { Box } from "@mui/material";
import { AddAccessRuleIcon, BackLink, Button, FormLayout } from "mds";
import PageLayout from "../Common/Layout/PageLayout";
import {
AddAccessRuleIcon,
BackLink,
Button,
FormLayout,
PageLayout,
} from "mds";
import InputBoxWrapper from "../Common/FormComponents/InputBoxWrapper/InputBoxWrapper";
import AddPolicyHelpBox from "./AddPolicyHelpBox";
import CodeMirrorWrapper from "../Common/FormComponents/CodeMirrorWrapper/CodeMirrorWrapper";

View File

@@ -15,7 +15,7 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import React, { Fragment, useEffect, useState } from "react";
import { AddIcon, Button, HelpBox, IAMPoliciesIcon } from "mds";
import { AddIcon, Button, HelpBox, IAMPoliciesIcon, PageLayout } from "mds";
import { useNavigate } from "react-router-dom";
import { Theme } from "@mui/material/styles";
import createStyles from "@mui/styles/createStyles";
@@ -30,7 +30,6 @@ import {
import { ErrorResponseHandler } from "../../../common/types";
import TableWrapper from "../Common/TableWrapper/TableWrapper";
import PageLayout from "../Common/Layout/PageLayout";
import {
CONSOLE_UI_RESOURCE,
createPolicyPermissions,

View File

@@ -24,6 +24,7 @@ import {
SearchIcon,
SectionTitle,
TrashIcon,
PageLayout,
Grid,
} from "mds";
import { Theme } from "@mui/material/styles";
@@ -36,7 +37,7 @@ import {
searchField,
} from "../Common/FormComponents/common/styleLibrary";
import Paper from "@mui/material/Paper";
import { LinearProgress } from "@mui/material";
import { Grid as MUIGrid, LinearProgress } from "@mui/material";
import TableWrapper from "../Common/TableWrapper/TableWrapper";
import { ErrorResponseHandler } from "../../../common/types";
@@ -44,7 +45,6 @@ import CodeMirrorWrapper from "../Common/FormComponents/CodeMirrorWrapper/CodeMi
import InputAdornment from "@mui/material/InputAdornment";
import TextField from "@mui/material/TextField";
import ScreenTitle from "../Common/ScreenTitle/ScreenTitle";
import PageLayout from "../Common/Layout/PageLayout";
import VerticalTabs from "../Common/VerticalTabs/VerticalTabs";
import {
@@ -368,240 +368,242 @@ const PolicyDetails = ({ classes }: IPolicyDetailsProps) => {
/>
<PageLayout className={classes.pageContainer}>
<Grid item xs={12}>
<ScreenTitle
icon={
<Fragment>
<IAMPoliciesIcon width={40} />
</Fragment>
}
title={policyName}
subTitle={<Fragment>IAM Policy</Fragment>}
actions={
<Fragment>
<SecureComponent
scopes={[IAM_SCOPES.ADMIN_DELETE_POLICY]}
resource={CONSOLE_UI_RESOURCE}
errorProps={{ disabled: true }}
>
<TooltipWrapper
tooltip={
canDeletePolicy
? ""
: permissionTooltipHelper(
deletePolicyPermissions,
"delete Policies"
)
}
<MUIGrid container spacing={1}>
<Grid item xs={12}>
<ScreenTitle
icon={
<Fragment>
<IAMPoliciesIcon width={40} />
</Fragment>
}
title={policyName}
subTitle={<Fragment>IAM Policy</Fragment>}
actions={
<Fragment>
<SecureComponent
scopes={[IAM_SCOPES.ADMIN_DELETE_POLICY]}
resource={CONSOLE_UI_RESOURCE}
errorProps={{ disabled: true }}
>
<TooltipWrapper
tooltip={
canDeletePolicy
? ""
: permissionTooltipHelper(
deletePolicyPermissions,
"delete Policies"
)
}
>
<Button
id={"delete-policy"}
label={"Delete Policy"}
variant="secondary"
icon={<TrashIcon />}
onClick={deletePolicy}
disabled={!canDeletePolicy}
/>
</TooltipWrapper>
</SecureComponent>
<TooltipWrapper tooltip={"Refresh"}>
<Button
id={"delete-policy"}
label={"Delete Policy"}
variant="secondary"
icon={<TrashIcon />}
onClick={deletePolicy}
disabled={!canDeletePolicy}
id={"refresh-policy"}
label={"Refresh"}
variant="regular"
icon={<RefreshIcon />}
onClick={() => {
refreshPolicyDetails();
}}
/>
</TooltipWrapper>
</SecureComponent>
</Fragment>
}
/>
</Grid>
<TooltipWrapper tooltip={"Refresh"}>
<Button
id={"refresh-policy"}
label={"Refresh"}
variant="regular"
icon={<RefreshIcon />}
onClick={() => {
refreshPolicyDetails();
}}
/>
</TooltipWrapper>
</Fragment>
}
/>
</Grid>
<VerticalTabs>
{{
tabConfig: { label: "Summary", disabled: !displayPolicy },
content: (
<Fragment>
<SectionTitle separator sx={{ marginBottom: 15 }}>
Policy Summary
</SectionTitle>
<Paper className={classes.paperContainer}>
<PolicyView policyStatements={policyStatements} />
</Paper>
</Fragment>
),
}}
{{
tabConfig: {
label: "Users",
disabled: !displayUsers || ldapIsEnabled,
},
content: (
<Fragment>
<SectionTitle separator sx={{ marginBottom: 15 }}>
Users
</SectionTitle>
<Grid container>
{userList.length > 0 && (
<Grid item xs={12} className={classes.actionsTray}>
<TextField
placeholder="Search Users"
className={classes.searchField}
id="search-resource"
label=""
onChange={(val) => {
setFilterUsers(val.target.value);
}}
InputProps={{
disableUnderline: true,
startAdornment: (
<InputAdornment position="start">
<SearchIcon />
</InputAdornment>
),
}}
variant="standard"
/>
</Grid>
)}
<TableWrapper
itemActions={userTableActions}
columns={[{ label: "Name", elementKey: "name" }]}
isLoading={loadingUsers}
records={filteredUsers}
entityName="Users with this Policy associated"
idField="name"
/>
</Grid>
</Fragment>
),
}}
{{
tabConfig: {
label: "Groups",
disabled: !displayGroups || ldapIsEnabled,
},
content: (
<Fragment>
<SectionTitle separator sx={{ marginBottom: 15 }}>
Groups
</SectionTitle>
<Grid container>
{groupList.length > 0 && (
<Grid item xs={12} className={classes.actionsTray}>
<TextField
placeholder="Search Groups"
className={classes.searchField}
id="search-resource"
label=""
onChange={(val) => {
setFilterGroups(val.target.value);
}}
InputProps={{
disableUnderline: true,
startAdornment: (
<InputAdornment position="start">
<SearchIcon />
</InputAdornment>
),
}}
variant="standard"
/>
</Grid>
)}
<TableWrapper
itemActions={groupTableActions}
columns={[{ label: "Name", elementKey: "name" }]}
isLoading={loadingGroups}
records={filteredGroups}
entityName="Groups with this Policy associated"
idField="name"
/>
</Grid>
</Fragment>
),
}}
{{
tabConfig: { label: "Raw Policy", disabled: !displayPolicy },
content: (
<Fragment>
<SectionTitle separator sx={{ marginBottom: 15 }}>
Raw Policy
</SectionTitle>
<form
noValidate
autoComplete="off"
onSubmit={(e: React.FormEvent<HTMLFormElement>) => {
saveRecord(e);
}}
>
<VerticalTabs>
{{
tabConfig: { label: "Summary", disabled: !displayPolicy },
content: (
<Fragment>
<SectionTitle separator sx={{ marginBottom: 15 }}>
Policy Summary
</SectionTitle>
<Paper className={classes.paperContainer}>
<PolicyView policyStatements={policyStatements} />
</Paper>
</Fragment>
),
}}
{{
tabConfig: {
label: "Users",
disabled: !displayUsers || ldapIsEnabled,
},
content: (
<Fragment>
<SectionTitle separator sx={{ marginBottom: 15 }}>
Users
</SectionTitle>
<Grid container>
<Grid item xs={12}>
<CodeMirrorWrapper
readOnly={!canEditPolicy}
value={policyDefinition}
onBeforeChange={(editor, data, value) => {
setPolicyDefinition(value);
}}
editorHeight={"350px"}
/>
</Grid>
<Grid item xs={12} className={classes.buttonContainer}>
{!policy && (
<button
type="button"
color="primary"
className={classes.clearButton}
onClick={() => {
resetForm();
{userList.length > 0 && (
<Grid item xs={12} className={classes.actionsTray}>
<TextField
placeholder="Search Users"
className={classes.searchField}
id="search-resource"
label=""
onChange={(val) => {
setFilterUsers(val.target.value);
}}
>
Clear
</button>
)}
<SecureComponent
scopes={[IAM_SCOPES.ADMIN_CREATE_POLICY]}
resource={CONSOLE_UI_RESOURCE}
errorProps={{ disabled: true }}
>
<TooltipWrapper
tooltip={
canEditPolicy
? ""
: permissionTooltipHelper(
createPolicyPermissions,
"edit a Policy"
)
}
>
<Button
id={"save"}
type="submit"
variant="callAction"
color="primary"
disabled={
addLoading || !validSave || !canEditPolicy
}
label={"Save"}
/>
</TooltipWrapper>
</SecureComponent>
</Grid>
{addLoading && (
<Grid item xs={12}>
<LinearProgress />
InputProps={{
disableUnderline: true,
startAdornment: (
<InputAdornment position="start">
<SearchIcon />
</InputAdornment>
),
}}
variant="standard"
/>
</Grid>
)}
<TableWrapper
itemActions={userTableActions}
columns={[{ label: "Name", elementKey: "name" }]}
isLoading={loadingUsers}
records={filteredUsers}
entityName="Users with this Policy associated"
idField="name"
/>
</Grid>
</form>
</Fragment>
),
}}
</VerticalTabs>
</Fragment>
),
}}
{{
tabConfig: {
label: "Groups",
disabled: !displayGroups || ldapIsEnabled,
},
content: (
<Fragment>
<SectionTitle separator sx={{ marginBottom: 15 }}>
Groups
</SectionTitle>
<Grid container>
{groupList.length > 0 && (
<Grid item xs={12} className={classes.actionsTray}>
<TextField
placeholder="Search Groups"
className={classes.searchField}
id="search-resource"
label=""
onChange={(val) => {
setFilterGroups(val.target.value);
}}
InputProps={{
disableUnderline: true,
startAdornment: (
<InputAdornment position="start">
<SearchIcon />
</InputAdornment>
),
}}
variant="standard"
/>
</Grid>
)}
<TableWrapper
itemActions={groupTableActions}
columns={[{ label: "Name", elementKey: "name" }]}
isLoading={loadingGroups}
records={filteredGroups}
entityName="Groups with this Policy associated"
idField="name"
/>
</Grid>
</Fragment>
),
}}
{{
tabConfig: { label: "Raw Policy", disabled: !displayPolicy },
content: (
<Fragment>
<SectionTitle separator sx={{ marginBottom: 15 }}>
Raw Policy
</SectionTitle>
<form
noValidate
autoComplete="off"
onSubmit={(e: React.FormEvent<HTMLFormElement>) => {
saveRecord(e);
}}
>
<Grid container>
<Grid item xs={12}>
<CodeMirrorWrapper
readOnly={!canEditPolicy}
value={policyDefinition}
onBeforeChange={(editor, data, value) => {
setPolicyDefinition(value);
}}
editorHeight={"350px"}
/>
</Grid>
<Grid item xs={12} className={classes.buttonContainer}>
{!policy && (
<button
type="button"
color="primary"
className={classes.clearButton}
onClick={() => {
resetForm();
}}
>
Clear
</button>
)}
<SecureComponent
scopes={[IAM_SCOPES.ADMIN_CREATE_POLICY]}
resource={CONSOLE_UI_RESOURCE}
errorProps={{ disabled: true }}
>
<TooltipWrapper
tooltip={
canEditPolicy
? ""
: permissionTooltipHelper(
createPolicyPermissions,
"edit a Policy"
)
}
>
<Button
id={"save"}
type="submit"
variant="callAction"
color="primary"
disabled={
addLoading || !validSave || !canEditPolicy
}
label={"Save"}
/>
</TooltipWrapper>
</SecureComponent>
</Grid>
{addLoading && (
<Grid item xs={12}>
<LinearProgress />
</Grid>
)}
</Grid>
</form>
</Fragment>
),
}}
</VerticalTabs>
</MUIGrid>
</PageLayout>
</Fragment>
);

View File

@@ -20,7 +20,14 @@ import { IMessageEvent, w3cwebsocket as W3CWebSocket } from "websocket";
import { Grid } from "@mui/material";
import { Theme } from "@mui/material/styles";
import { useNavigate } from "react-router-dom";
import { Button, HelpBox, Loader, SpeedtestIcon, WarnIcon } from "mds";
import {
Button,
HelpBox,
Loader,
PageLayout,
SpeedtestIcon,
WarnIcon,
} from "mds";
import { DateTime } from "luxon";
import createStyles from "@mui/styles/createStyles";
import {
@@ -40,7 +47,6 @@ import STResults from "./STResults";
import InputBoxWrapper from "../Common/FormComponents/InputBoxWrapper/InputBoxWrapper";
import ProgressBarWrapper from "../Common/ProgressBarWrapper/ProgressBarWrapper";
import InputUnitMenu from "../Common/FormComponents/InputUnitMenu/InputUnitMenu";
import PageLayout from "../Common/Layout/PageLayout";
import { SecureComponent } from "../../../common/SecureComponent";
import DistributedOnly from "../Common/DistributedOnly/DistributedOnly";
import { selDistSet } from "../../../systemSlice";

View File

@@ -16,9 +16,8 @@
import React, { Fragment, useEffect, useState } from "react";
import { Box } from "@mui/material";
import { Button, CallHomeMenuIcon, HelpBox, Loader } from "mds";
import { Button, CallHomeMenuIcon, HelpBox, Loader, PageLayout } from "mds";
import { Link, useNavigate } from "react-router-dom";
import PageLayout from "../Common/Layout/PageLayout";
import api from "../../../common/api";
import { ErrorResponseHandler } from "../../../common/types";
import { setErrorSnackMessage } from "../../../systemSlice";

View File

@@ -1,11 +1,10 @@
import React, { Fragment, useState } from "react";
import { IMessageEvent, w3cwebsocket as W3CWebSocket } from "websocket";
import { Theme } from "@mui/material/styles";
import { Button } from "mds";
import { Button, PageLayout } from "mds";
import createStyles from "@mui/styles/createStyles";
import withStyles from "@mui/styles/withStyles";
import { Grid } from "@mui/material";
import PageLayout from "../Common/Layout/PageLayout";
import CheckboxWrapper from "../Common/FormComponents/CheckboxWrapper/CheckboxWrapper";
import { wsProtocol } from "../../../utils/wsUtils";
import {

View File

@@ -20,7 +20,6 @@ import createStyles from "@mui/styles/createStyles";
import { spacingUtils } from "../Common/FormComponents/common/styleLibrary";
import withStyles from "@mui/styles/withStyles";
import { Box } from "@mui/material";
import PageLayout from "../Common/Layout/PageLayout";
import api from "../../../common/api";
import { SubnetRegTokenResponse } from "../License/types";
@@ -45,6 +44,7 @@ import SubnetMFAToken from "./SubnetMFAToken";
import ClusterRegistrationForm from "./ClusterRegistrationForm";
import OnlineRegistration from "./OnlineRegistration";
import PageHeaderWrapper from "../Common/PageHeaderWrapper/PageHeaderWrapper";
import { PageLayout } from "mds";
interface IRegister {
classes: any;

View File

@@ -16,9 +16,14 @@
import React, { Fragment, useEffect, useState } from "react";
import { Box, DialogContentText } from "@mui/material";
import { Button, HelpBox, InspectMenuIcon, PasswordKeyIcon } from "mds";
import {
Button,
HelpBox,
InspectMenuIcon,
PageLayout,
PasswordKeyIcon,
} from "mds";
import { useNavigate } from "react-router-dom";
import PageLayout from "../Common/Layout/PageLayout";
import InputBoxWrapper from "../Common/FormComponents/InputBoxWrapper/InputBoxWrapper";
import FormSwitchWrapper from "../Common/FormComponents/FormSwitchWrapper/FormSwitchWrapper";
import ModalWrapper from "../Common/ModalWrapper/ModalWrapper";

View File

@@ -18,7 +18,7 @@ import React, { Fragment, useState } from "react";
import { DateTime } from "luxon";
import { Box, Grid } from "@mui/material";
import { IMessageEvent, w3cwebsocket as W3CWebSocket } from "websocket";
import { Button, FilterIcon } from "mds";
import { Button, FilterIcon, PageLayout } from "mds";
import { AppState, useAppDispatch } from "../../../store";
import { useSelector } from "react-redux";
import { TraceMessage } from "./types";
@@ -34,7 +34,6 @@ import {
} from "../Common/FormComponents/common/styleLibrary";
import TableWrapper from "../Common/TableWrapper/TableWrapper";
import CheckboxWrapper from "../Common/FormComponents/CheckboxWrapper/CheckboxWrapper";
import PageLayout from "../Common/Layout/PageLayout";
import InputBoxWrapper from "../Common/FormComponents/InputBoxWrapper/InputBoxWrapper";
import {
@@ -170,7 +169,7 @@ const Trace = ({ classes }: ITrace) => {
<Fragment>
<PageHeaderWrapper label={"Trace"} />
<PageLayout>
<Grid className={classes.formBox}>
<Grid container spacing={1} className={classes.formBox}>
<Grid
item
xs={12}

View File

@@ -16,7 +16,7 @@
import React, { Fragment } from "react";
import { Theme } from "@mui/material/styles";
import { BackLink, Button, CreateUserIcon, FormLayout } from "mds";
import { BackLink, Button, CreateUserIcon, FormLayout, PageLayout } from "mds";
import createStyles from "@mui/styles/createStyles";
import withStyles from "@mui/styles/withStyles";
import UserSelector from "./UserSelector";
@@ -29,8 +29,6 @@ import {
import Grid from "@mui/material/Grid";
import { LinearProgress } from "@mui/material";
import PageLayout from "../Common/Layout/PageLayout";
import PolicySelectors from "../Policies/PolicySelectors";
import GroupsSelectors from "./GroupsSelectors";

View File

@@ -21,6 +21,7 @@ import {
BackLink,
Button,
IAMPoliciesIcon,
PageLayout,
PasswordKeyIcon,
ServiceAccountCredentialsIcon,
} from "mds";
@@ -33,7 +34,6 @@ import {
import Grid from "@mui/material/Grid";
import { Box } from "@mui/material";
import CodeMirrorWrapper from "../Common/FormComponents/CodeMirrorWrapper/CodeMirrorWrapper";
import PageLayout from "../Common/Layout/PageLayout";
import InputBoxWrapper from "../Common/FormComponents/InputBoxWrapper/InputBoxWrapper";
import FormSwitchWrapper from "../Common/FormComponents/FormSwitchWrapper/FormSwitchWrapper";

View File

@@ -24,6 +24,7 @@ import {
DeleteIcon,
GroupsIcon,
HelpBox,
PageLayout,
UsersIcon,
} from "mds";
import createStyles from "@mui/styles/createStyles";
@@ -43,7 +44,6 @@ import { ErrorResponseHandler } from "../../../common/types";
import TableWrapper from "../Common/TableWrapper/TableWrapper";
import { encodeURLString } from "../../../common/utils";
import AButton from "../Common/AButton/AButton";
import PageLayout from "../Common/Layout/PageLayout";
import SearchBox from "../Common/SearchBox";
import withSuspense from "../Common/Components/withSuspense";
import {
@@ -211,119 +211,89 @@ const ListUsers = ({ classes }: IUsersProps) => {
)}
<PageHeaderWrapper label={"Users"} />
<PageLayout>
<Grid item xs={12} className={classes.actionsTray}>
<SearchBox
placeholder={"Search Users"}
onChange={setFilter}
overrideClass={classes.searchField}
value={filter}
/>
<SecureComponent
resource={CONSOLE_UI_RESOURCE}
scopes={[IAM_SCOPES.ADMIN_DELETE_USER]}
matchAll
errorProps={{ disabled: true }}
>
<TooltipWrapper
tooltip={
hasPermission("console", [IAM_SCOPES.ADMIN_DELETE_USER])
? checkedUsers.length === 0
? "Select Users to delete"
: "Delete Selected"
: permissionTooltipHelper(
[IAM_SCOPES.ADMIN_DELETE_USER],
"delete users"
)
}
<Grid container spacing={1}>
<Grid item xs={12} className={classes.actionsTray}>
<SearchBox
placeholder={"Search Users"}
onChange={setFilter}
overrideClass={classes.searchField}
value={filter}
/>
<SecureComponent
resource={CONSOLE_UI_RESOURCE}
scopes={[IAM_SCOPES.ADMIN_DELETE_USER]}
matchAll
errorProps={{ disabled: true }}
>
<Button
id={"delete-selected-users"}
onClick={() => {
setDeleteOpen(true);
}}
label={"Delete Selected"}
icon={<DeleteIcon />}
disabled={checkedUsers.length === 0}
variant={"secondary"}
aria-label="delete-selected-users"
/>
</TooltipWrapper>
</SecureComponent>
<SecureComponent
scopes={[IAM_SCOPES.ADMIN_ADD_USER_TO_GROUP]}
resource={CONSOLE_UI_RESOURCE}
errorProps={{ disabled: true }}
>
<TooltipWrapper
tooltip={
hasPermission("console", [IAM_SCOPES.ADMIN_ADD_USER_TO_GROUP])
? checkedUsers.length === 0
? "Select Users to group"
: "Add to Group"
: permissionTooltipHelper(
[IAM_SCOPES.ADMIN_ADD_USER_TO_GROUP],
"add users to groups"
)
}
<TooltipWrapper
tooltip={
hasPermission("console", [IAM_SCOPES.ADMIN_DELETE_USER])
? checkedUsers.length === 0
? "Select Users to delete"
: "Delete Selected"
: permissionTooltipHelper(
[IAM_SCOPES.ADMIN_DELETE_USER],
"delete users"
)
}
>
<Button
id={"delete-selected-users"}
onClick={() => {
setDeleteOpen(true);
}}
label={"Delete Selected"}
icon={<DeleteIcon />}
disabled={checkedUsers.length === 0}
variant={"secondary"}
aria-label="delete-selected-users"
/>
</TooltipWrapper>
</SecureComponent>
<SecureComponent
scopes={[IAM_SCOPES.ADMIN_ADD_USER_TO_GROUP]}
resource={CONSOLE_UI_RESOURCE}
errorProps={{ disabled: true }}
>
<Button
id={"add-to-group"}
label={"Add to Group"}
icon={<GroupsIcon />}
disabled={checkedUsers.length <= 0}
onClick={() => {
if (checkedUsers.length > 0) {
setAddGroupOpen(true);
}
}}
variant={"regular"}
/>
</TooltipWrapper>
</SecureComponent>
<SecureComponent
scopes={[
IAM_SCOPES.ADMIN_CREATE_USER,
IAM_SCOPES.ADMIN_LIST_USER_POLICIES,
IAM_SCOPES.ADMIN_LIST_GROUPS,
]}
resource={S3_ALL_RESOURCES}
matchAll
errorProps={{ disabled: true }}
>
<TooltipWrapper
tooltip={
hasPermission(
"console",
[
IAM_SCOPES.ADMIN_CREATE_USER,
IAM_SCOPES.ADMIN_LIST_USER_POLICIES,
IAM_SCOPES.ADMIN_LIST_GROUPS,
IAM_SCOPES.ADMIN_ATTACH_USER_OR_GROUP_POLICY,
],
true
)
? "Create User"
: permissionTooltipHelper(
[
IAM_SCOPES.ADMIN_CREATE_USER,
IAM_SCOPES.ADMIN_LIST_USER_POLICIES,
IAM_SCOPES.ADMIN_LIST_GROUPS,
IAM_SCOPES.ADMIN_ATTACH_USER_OR_GROUP_POLICY,
],
"create users"
)
}
<TooltipWrapper
tooltip={
hasPermission("console", [IAM_SCOPES.ADMIN_ADD_USER_TO_GROUP])
? checkedUsers.length === 0
? "Select Users to group"
: "Add to Group"
: permissionTooltipHelper(
[IAM_SCOPES.ADMIN_ADD_USER_TO_GROUP],
"add users to groups"
)
}
>
<Button
id={"add-to-group"}
label={"Add to Group"}
icon={<GroupsIcon />}
disabled={checkedUsers.length <= 0}
onClick={() => {
if (checkedUsers.length > 0) {
setAddGroupOpen(true);
}
}}
variant={"regular"}
/>
</TooltipWrapper>
</SecureComponent>
<SecureComponent
scopes={[
IAM_SCOPES.ADMIN_CREATE_USER,
IAM_SCOPES.ADMIN_LIST_USER_POLICIES,
IAM_SCOPES.ADMIN_LIST_GROUPS,
]}
resource={S3_ALL_RESOURCES}
matchAll
errorProps={{ disabled: true }}
>
<Button
id={"create-user"}
label={"Create User"}
icon={<AddIcon />}
onClick={() => {
navigate(`${IAM_PAGES.USER_ADD}`);
}}
variant={"callAction"}
disabled={
!hasPermission(
<TooltipWrapper
tooltip={
hasPermission(
"console",
[
IAM_SCOPES.ADMIN_CREATE_USER,
@@ -333,27 +303,48 @@ const ListUsers = ({ classes }: IUsersProps) => {
],
true
)
? "Create User"
: permissionTooltipHelper(
[
IAM_SCOPES.ADMIN_CREATE_USER,
IAM_SCOPES.ADMIN_LIST_USER_POLICIES,
IAM_SCOPES.ADMIN_LIST_GROUPS,
IAM_SCOPES.ADMIN_ATTACH_USER_OR_GROUP_POLICY,
],
"create users"
)
}
/>
</TooltipWrapper>
</SecureComponent>
</Grid>
{loading && <LinearProgress />}
{!loading && (
<Fragment>
{records.length > 0 && (
<Fragment>
<TooltipWrapper
tooltip={
viewUser
? ""
: permissionTooltipHelper(
[IAM_SCOPES.ADMIN_GET_USER],
"view user details"
)
>
<Button
id={"create-user"}
label={"Create User"}
icon={<AddIcon />}
onClick={() => {
navigate(`${IAM_PAGES.USER_ADD}`);
}}
variant={"callAction"}
disabled={
!hasPermission(
"console",
[
IAM_SCOPES.ADMIN_CREATE_USER,
IAM_SCOPES.ADMIN_LIST_USER_POLICIES,
IAM_SCOPES.ADMIN_LIST_GROUPS,
IAM_SCOPES.ADMIN_ATTACH_USER_OR_GROUP_POLICY,
],
true
)
}
>
/>
</TooltipWrapper>
</SecureComponent>
</Grid>
{loading && <LinearProgress />}
{!loading && (
<Fragment>
{records.length > 0 && (
<Fragment>
<Grid
item
xs={12}
@@ -383,60 +374,6 @@ const ListUsers = ({ classes }: IUsersProps) => {
/>
</SecureComponent>
</Grid>
</TooltipWrapper>
<HelpBox
title={"Users"}
iconComponent={<UsersIcon />}
help={
<Fragment>
A MinIO user consists of a unique access key (username)
and corresponding secret key (password). Clients must
authenticate their identity by specifying both a valid
access key (username) and the corresponding secret key
(password) of an existing MinIO user.
<br />
Groups provide a simplified method for managing shared
permissions among users with common access patterns and
workloads.
<br />
<br />
Users inherit access permissions to data and resources
through the groups they belong to.
<br />
MinIO uses Policy-Based Access Control (PBAC) to define
the authorized actions and resources to which an
authenticated user has access. Each policy describes one
or more actions and conditions that outline the
permissions of a user or group of users.
<br />
<br />
Each user can access only those resources and operations
which are explicitly granted by the built-in role. MinIO
denies access to any other resource or action by default.
<br />
<br />
You can learn more at our{" "}
<a
href="https://min.io/docs/minio/kubernetes/upstream/administration/identity-access-management/minio-user-management.html?ref=con"
target="_blank"
rel="noopener"
>
documentation
</a>
.
</Fragment>
}
/>
</Fragment>
)}
{records.length === 0 && (
<Grid
container
justifyContent={"center"}
alignContent={"center"}
alignItems={"start"}
>
<Grid item xs={8}>
<HelpBox
title={"Users"}
iconComponent={<UsersIcon />}
@@ -467,35 +404,91 @@ const ListUsers = ({ classes }: IUsersProps) => {
which are explicitly granted by the built-in role. MinIO
denies access to any other resource or action by
default.
<SecureComponent
scopes={[
IAM_SCOPES.ADMIN_CREATE_USER,
IAM_SCOPES.ADMIN_LIST_USER_POLICIES,
IAM_SCOPES.ADMIN_LIST_GROUPS,
]}
matchAll
resource={CONSOLE_UI_RESOURCE}
<br />
<br />
You can learn more at our{" "}
<a
href="https://min.io/docs/minio/kubernetes/upstream/administration/identity-access-management/minio-user-management.html?ref=con"
target="_blank"
rel="noopener"
>
<br />
<br />
To get started,{" "}
<AButton
onClick={() => {
navigate(`${IAM_PAGES.USER_ADD}`);
}}
>
Create a User
</AButton>
.
</SecureComponent>
documentation
</a>
.
</Fragment>
}
/>
</Fragment>
)}
{records.length === 0 && (
<Grid
container
justifyContent={"center"}
alignContent={"center"}
alignItems={"start"}
>
<Grid item xs={8}>
<HelpBox
title={"Users"}
iconComponent={<UsersIcon />}
help={
<Fragment>
A MinIO user consists of a unique access key
(username) and corresponding secret key (password).
Clients must authenticate their identity by specifying
both a valid access key (username) and the
corresponding secret key (password) of an existing
MinIO user.
<br />
Groups provide a simplified method for managing shared
permissions among users with common access patterns
and workloads.
<br />
<br />
Users inherit access permissions to data and resources
through the groups they belong to.
<br />
MinIO uses Policy-Based Access Control (PBAC) to
define the authorized actions and resources to which
an authenticated user has access. Each policy
describes one or more actions and conditions that
outline the permissions of a user or group of users.
<br />
<br />
Each user can access only those resources and
operations which are explicitly granted by the
built-in role. MinIO denies access to any other
resource or action by default.
<SecureComponent
scopes={[
IAM_SCOPES.ADMIN_CREATE_USER,
IAM_SCOPES.ADMIN_LIST_USER_POLICIES,
IAM_SCOPES.ADMIN_LIST_GROUPS,
]}
matchAll
resource={CONSOLE_UI_RESOURCE}
>
<br />
<br />
To get started,{" "}
<AButton
onClick={() => {
navigate(`${IAM_PAGES.USER_ADD}`);
}}
>
Create a User
</AButton>
.
</SecureComponent>
</Fragment>
}
/>
</Grid>
</Grid>
</Grid>
)}
</Fragment>
)}
)}
</Fragment>
)}
</Grid>
</PageLayout>
</Fragment>
);

View File

@@ -22,6 +22,7 @@ import {
BackLink,
Button,
IAMPoliciesIcon,
PageLayout,
PasswordKeyIcon,
TrashIcon,
UsersIcon,
@@ -47,7 +48,6 @@ import ChangeUserPasswordModal from "../Account/ChangeUserPasswordModal";
import DeleteUser from "./DeleteUser";
import ScreenTitle from "../Common/ScreenTitle/ScreenTitle";
import PanelTitle from "../Common/PanelTitle/PanelTitle";
import PageLayout from "../Common/Layout/PageLayout";
import VerticalTabs from "../Common/VerticalTabs/VerticalTabs";
import FormSwitchWrapper from "../Common/FormComponents/FormSwitchWrapper/FormSwitchWrapper";
@@ -282,217 +282,219 @@ const UserDetails = ({ classes }: IUserDetailsProps) => {
/>
)}
<PageLayout className={classes.pageContainer}>
<Grid item xs={12}>
<ScreenTitle
icon={
<Fragment>
<UsersIcon width={40} />
</Fragment>
}
title={userName}
actions={
<Fragment>
<span className={classes.statusLabel}>User Status:</span>
<span className={classes.statusValue}>
{enabled ? "Enabled" : "Disabled"}
</span>
<TooltipWrapper
tooltip={
enableEnabled || disableEnabled
? ""
: hasPermission(
CONSOLE_UI_RESOURCE,
enableUserPermissions
)
? permissionTooltipHelper(
disableUserPermissions,
"disable users"
)
: hasPermission(
CONSOLE_UI_RESOURCE,
disableUserPermissions
)
? permissionTooltipHelper(
enableUserPermissions,
"enable users"
)
: permissionTooltipHelper(
enableDisableUserPermissions,
"enable or disable users"
)
}
>
<FormSwitchWrapper
indicatorLabels={["Enabled", "Disabled"]}
checked={enabled}
value={"group_enabled"}
id="group-status"
name="group-status"
onChange={() => {
setEnabled(!enabled);
saveRecord(!enabled);
}}
switchOnly
disabled={!enableEnabled && !disableEnabled}
/>
</TooltipWrapper>
<TooltipWrapper
tooltip={
hasPermission(CONSOLE_UI_RESOURCE, deleteUserPermissions)
? userLoggedIn === userName
? "You cannot delete the currently logged in User"
: "Delete User"
: permissionTooltipHelper(
deleteUserPermissions,
"delete user"
)
}
>
<Button
id={"delete-user"}
onClick={deleteUser}
icon={<TrashIcon />}
variant={"secondary"}
disabled={
!hasPermission(
CONSOLE_UI_RESOURCE,
deleteUserPermissions
) || userLoggedIn === userName
}
/>
</TooltipWrapper>
<TooltipWrapper tooltip={"Change Password"}>
<Button
id={"change-user-password"}
onClick={changeUserPassword}
icon={<PasswordKeyIcon />}
variant={"regular"}
/>
</TooltipWrapper>
</Fragment>
}
/>
</Grid>
<Grid item xs={12}>
<VerticalTabs>
{{
tabConfig: {
label: "Groups",
disabled: !canAssignGroup,
},
content: (
<React.Fragment>
<div className={classes.actionsTray}>
<PanelTitle>Groups</PanelTitle>
<TooltipWrapper
tooltip={
canAssignGroup
? "Assign groups"
: permissionTooltipHelper(
assignGroupPermissions,
"add users to groups"
)
}
>
<Button
id={"add-groups"}
label={"Add to Groups"}
onClick={() => {
setAddGroupOpen(true);
}}
icon={<AddIcon />}
variant={"callAction"}
disabled={!canAssignGroup}
/>
</TooltipWrapper>
</div>
<div className={classes.tableBlock}>
<TableWrapper
itemActions={groupTableActions}
columns={[{ label: "Name", elementKey: "group" }]}
isLoading={loading}
records={currentGroups}
entityName="Groups"
idField="group"
/>
</div>
</React.Fragment>
),
}}
{{
tabConfig: {
label: "Service Accounts",
disabled: !hasPermission(
CONSOLE_UI_RESOURCE,
editServiceAccountPermissions
),
},
content: (
<UserServiceAccountsPanel
user={userName}
hasPolicy={hasPolicy}
/>
),
}}
{{
tabConfig: {
label: "Policies",
disabled: !canAssignPolicy,
},
content: (
<Grid container spacing={1}>
<Grid item xs={12}>
<ScreenTitle
icon={
<Fragment>
<div className={classes.actionsTray}>
<PanelTitle>Policies</PanelTitle>
<TooltipWrapper
tooltip={
canAssignPolicy
? "Assign Policies"
: permissionTooltipHelper(
assignIAMPolicyPermissions,
"assign policies"
)
}
>
<Button
id={"assign-policies"}
label={"Assign Policies"}
onClick={() => {
setPolicyOpen(true);
}}
icon={<IAMPoliciesIcon />}
variant={"callAction"}
disabled={!canAssignPolicy}
/>
</TooltipWrapper>
</div>
<div className={classes.tableBlock}>
<TableWrapper
itemActions={[
{
type: "view",
onClick: (policy: IPolicyItem) => {
navigate(
`${IAM_PAGES.POLICIES}/${encodeURLString(
policy.policy
)}`
);
},
},
]}
columns={[{ label: "Name", elementKey: "policy" }]}
isLoading={loading}
records={currentPolicies}
entityName="Policies"
idField="policy"
/>
</div>
<UsersIcon width={40} />
</Fragment>
),
}}
</VerticalTabs>
}
title={userName}
actions={
<Fragment>
<span className={classes.statusLabel}>User Status:</span>
<span className={classes.statusValue}>
{enabled ? "Enabled" : "Disabled"}
</span>
<TooltipWrapper
tooltip={
enableEnabled || disableEnabled
? ""
: hasPermission(
CONSOLE_UI_RESOURCE,
enableUserPermissions
)
? permissionTooltipHelper(
disableUserPermissions,
"disable users"
)
: hasPermission(
CONSOLE_UI_RESOURCE,
disableUserPermissions
)
? permissionTooltipHelper(
enableUserPermissions,
"enable users"
)
: permissionTooltipHelper(
enableDisableUserPermissions,
"enable or disable users"
)
}
>
<FormSwitchWrapper
indicatorLabels={["Enabled", "Disabled"]}
checked={enabled}
value={"group_enabled"}
id="group-status"
name="group-status"
onChange={() => {
setEnabled(!enabled);
saveRecord(!enabled);
}}
switchOnly
disabled={!enableEnabled && !disableEnabled}
/>
</TooltipWrapper>
<TooltipWrapper
tooltip={
hasPermission(CONSOLE_UI_RESOURCE, deleteUserPermissions)
? userLoggedIn === userName
? "You cannot delete the currently logged in User"
: "Delete User"
: permissionTooltipHelper(
deleteUserPermissions,
"delete user"
)
}
>
<Button
id={"delete-user"}
onClick={deleteUser}
icon={<TrashIcon />}
variant={"secondary"}
disabled={
!hasPermission(
CONSOLE_UI_RESOURCE,
deleteUserPermissions
) || userLoggedIn === userName
}
/>
</TooltipWrapper>
<TooltipWrapper tooltip={"Change Password"}>
<Button
id={"change-user-password"}
onClick={changeUserPassword}
icon={<PasswordKeyIcon />}
variant={"regular"}
/>
</TooltipWrapper>
</Fragment>
}
/>
</Grid>
<Grid item xs={12}>
<VerticalTabs>
{{
tabConfig: {
label: "Groups",
disabled: !canAssignGroup,
},
content: (
<React.Fragment>
<div className={classes.actionsTray}>
<PanelTitle>Groups</PanelTitle>
<TooltipWrapper
tooltip={
canAssignGroup
? "Assign groups"
: permissionTooltipHelper(
assignGroupPermissions,
"add users to groups"
)
}
>
<Button
id={"add-groups"}
label={"Add to Groups"}
onClick={() => {
setAddGroupOpen(true);
}}
icon={<AddIcon />}
variant={"callAction"}
disabled={!canAssignGroup}
/>
</TooltipWrapper>
</div>
<Grid item xs={12} className={classes.tableBlock}>
<TableWrapper
itemActions={groupTableActions}
columns={[{ label: "Name", elementKey: "group" }]}
isLoading={loading}
records={currentGroups}
entityName="Groups"
idField="group"
/>
</Grid>
</React.Fragment>
),
}}
{{
tabConfig: {
label: "Service Accounts",
disabled: !hasPermission(
CONSOLE_UI_RESOURCE,
editServiceAccountPermissions
),
},
content: (
<UserServiceAccountsPanel
user={userName}
hasPolicy={hasPolicy}
/>
),
}}
{{
tabConfig: {
label: "Policies",
disabled: !canAssignPolicy,
},
content: (
<Fragment>
<div className={classes.actionsTray}>
<PanelTitle>Policies</PanelTitle>
<TooltipWrapper
tooltip={
canAssignPolicy
? "Assign Policies"
: permissionTooltipHelper(
assignIAMPolicyPermissions,
"assign policies"
)
}
>
<Button
id={"assign-policies"}
label={"Assign Policies"}
onClick={() => {
setPolicyOpen(true);
}}
icon={<IAMPoliciesIcon />}
variant={"callAction"}
disabled={!canAssignPolicy}
/>
</TooltipWrapper>
</div>
<div className={classes.tableBlock}>
<TableWrapper
itemActions={[
{
type: "view",
onClick: (policy: IPolicyItem) => {
navigate(
`${IAM_PAGES.POLICIES}/${encodeURLString(
policy.policy
)}`
);
},
},
]}
columns={[{ label: "Name", elementKey: "policy" }]}
isLoading={loading}
records={currentPolicies}
entityName="Policies"
idField="policy"
/>
</div>
</Fragment>
),
}}
</VerticalTabs>
</Grid>
</Grid>
</PageLayout>
</Fragment>

View File

@@ -25,7 +25,7 @@ import {
import { IMessageEvent, w3cwebsocket as W3CWebSocket } from "websocket";
import { useSelector } from "react-redux";
import { Theme } from "@mui/material/styles";
import { Button } from "mds";
import { Button, PageLayout } from "mds";
import createStyles from "@mui/styles/createStyles";
import withStyles from "@mui/styles/withStyles";
import { AppState, useAppDispatch } from "../../../store";
@@ -41,7 +41,6 @@ import {
import { ErrorResponseHandler } from "../../../common/types";
import TableWrapper from "../Common/TableWrapper/TableWrapper";
import api from "../../../common/api";
import PageLayout from "../Common/Layout/PageLayout";
import makeStyles from "@mui/styles/makeStyles";
import { watchMessageReceived, watchResetMessages } from "./watchSlice";
import PageHeaderWrapper from "../Common/PageHeaderWrapper/PageHeaderWrapper";
@@ -175,7 +174,7 @@ const Watch = () => {
<React.Fragment>
<PageHeaderWrapper label="Watch" />
<PageLayout>
<Grid item xs={12}>
<Grid container spacing={1} item xs={12}>
<Grid item xs={12} className={classes.actionsTray}>
<FormControl variant="outlined" className={classes.bucketField}>
<Select
@@ -251,7 +250,7 @@ const Watch = () => {
)}
</Grid>
<div className={classes.tableBlock}>
<Grid item xs={12} className={classes.tableBlock}>
<TableWrapper
columns={[
{
@@ -274,7 +273,7 @@ const Watch = () => {
isLoading={false}
customPaperHeight={classes.watchTableHeight}
/>
</div>
</Grid>
</Grid>
</PageLayout>
</React.Fragment>

View File

@@ -17,7 +17,7 @@
import React from "react";
import Box from "@mui/material/Box";
import Copyright from "../common/Copyright";
import PageLayout from "./Console/Common/Layout/PageLayout";
import { PageLayout } from "mds";
const NotFound: React.FC = () => {
return (