Updated Entities results panel styles (#2753)

Signed-off-by: Benjamin Perez <benjamin@bexsoft.net>
This commit is contained in:
Alex
2023-03-31 22:09:37 -06:00
committed by GitHub
parent 4f5b1b0aa7
commit 62fa0e2043
2 changed files with 312 additions and 178 deletions

View File

@@ -27,13 +27,15 @@ import {
InputBox,
Loader,
RemoveIcon,
SearchIcon,
SectionTitle,
UptimeIcon,
TimeIcon,
} from "mds";
import PolicySelectors from "../../Policies/PolicySelectors";
import { useSelector } from "react-redux";
import { LDAPEntitiesResponse } from "./types";
import { DateTime } from "luxon";
import LDAPResultsBlock from "./LDAPResultsBlock";
const LDAPEntitiesQuery = () => {
const dispatch = useAppDispatch();
@@ -107,90 +109,128 @@ const LDAPEntitiesQuery = () => {
};
return (
<Box sx={{ marginTop: 15, paddingTop: 0 }} withBorders>
<Box sx={{ marginTop: 15, paddingTop: 0 }}>
<Grid container sx={{ marginTop: 5 }}>
<Grid item sm={12} md={6} lg={5} sx={{ padding: 10, paddingTop: 0 }}>
<SectionTitle separator>Query Filters</SectionTitle>
<SectionTitle>Query Filters</SectionTitle>
<Box sx={{ padding: "0 10px" }}>
<h4>Users</h4>
<Box
sx={{
overflowY: "auto",
minHeight: 220,
maxHeight: 250,
"& > div > div": {
width: "100%",
},
}}
>
{users.map((userDat, index) => {
return (
<InputBox
id={`search-user-${index}`}
key={`search-user-${index}`}
value={userDat}
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
const usersElements = [...users];
usersElements[index] = e.target.value;
setUsers(usersElements);
}}
overlayIcon={
users.length === index + 1 ? <AddIcon /> : <RemoveIcon />
}
overlayAction={() => {
alterUsersList(users.length === index + 1, index);
}}
/>
);
})}
<Box
sx={{
padding: "0 10px",
display: "flex",
flexDirection: "column",
gap: 40,
}}
>
<Box sx={{ padding: "10px 26px" }} withBorders>
<Box sx={{ display: "flex" }}>
<h4 style={{ margin: 0, marginBottom: 10, fontSize: 14 }}>
Users
</h4>
</Box>
<Box
sx={{
overflowY: "auto",
minHeight: 50,
maxHeight: 250,
"& > div > div": {
width: "100%",
},
}}
>
{users.map((userDat, index) => {
return (
<InputBox
id={`search-user-${index}`}
key={`search-user-${index}`}
value={userDat}
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
const usersElements = [...users];
usersElements[index] = e.target.value;
setUsers(usersElements);
}}
overlayIcon={
users.length === index + 1 ? (
<AddIcon />
) : (
<RemoveIcon />
)
}
overlayAction={() => {
alterUsersList(users.length === index + 1, index);
}}
/>
);
})}
</Box>
</Box>
<h4>Groups</h4>
<Box
sx={{
overflowY: "auto",
minHeight: 220,
maxHeight: 250,
"& > div > div": {
width: "100%",
},
}}
>
{groups.map((groupDat, index) => {
return (
<InputBox
id={`search-group-${index}`}
key={`search-group-${index}`}
value={groupDat}
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
const groupsElements = [...groups];
groupsElements[index] = e.target.value;
setGroups(groupsElements);
}}
overlayIcon={
groups.length === index + 1 ? <AddIcon /> : <RemoveIcon />
}
overlayAction={() => {
alterGroupsList(groups.length === index + 1, index);
}}
/>
);
})}
<Box sx={{ padding: "10px 26px" }} withBorders>
<h4 style={{ margin: 0, marginBottom: 10, fontSize: 14 }}>
Groups
</h4>
<Box
sx={{
overflowY: "auto",
minHeight: 50,
maxHeight: "calc(100vh - 340px)",
"& > div > div": {
width: "100%",
},
}}
>
{groups.map((groupDat, index) => {
return (
<InputBox
id={`search-group-${index}`}
key={`search-group-${index}`}
value={groupDat}
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
const groupsElements = [...groups];
groupsElements[index] = e.target.value;
setGroups(groupsElements);
}}
overlayIcon={
groups.length === index + 1 ? (
<AddIcon />
) : (
<RemoveIcon />
)
}
overlayAction={() => {
alterGroupsList(groups.length === index + 1, index);
}}
/>
);
})}
</Box>
</Box>
<h4>Policies</h4>
<Box
sx={{
minHeight: 220,
maxHeight: "calc(100vh - 740px)",
}}
>
<PolicySelectors selectedPolicy={selectedPolicies} noTitle />
<Box sx={{ padding: "10px 26px" }} withBorders>
<h4 style={{ margin: 0, marginBottom: 10, fontSize: 14 }}>
Policies
</h4>
<Box
sx={{
minHeight: 265,
maxHeight: "calc(100vh - 740px)",
}}
>
<PolicySelectors selectedPolicy={selectedPolicies} noTitle />
</Box>
</Box>
</Box>
</Grid>
<Grid item sm={12} md={6} lg={7} sx={{ padding: 10, paddingTop: 0 }}>
<Grid
item
sm={12}
md={6}
lg={7}
sx={{
padding: 10,
paddingTop: 0,
display: "flex",
flexDirection: "column",
}}
>
{loading ? (
<Box sx={{ textAlign: "center" }}>
<Loader />
@@ -198,8 +238,6 @@ const LDAPEntitiesQuery = () => {
) : (
<Fragment>
<SectionTitle
separator
sx={{ marginBottom: 15 }}
actions={
<Box
sx={{
@@ -211,8 +249,13 @@ const LDAPEntitiesQuery = () => {
>
{results?.timestamp ? (
<Fragment>
<UptimeIcon
style={{ width: 18, height: 18, marginRight: 5 }}
<TimeIcon
style={{
width: 14,
height: 14,
marginRight: 5,
fill: "#BEBFBF",
}}
/>
{DateTime.fromISO(results.timestamp).toFormat(
"D HH:mm:ss"
@@ -224,114 +267,30 @@ const LDAPEntitiesQuery = () => {
</Box>
}
>
Results
Query Results
</SectionTitle>
{results ? (
<Box>
<Box
sx={{
backgroundColor: "#FBFAFA",
padding: "8px 22px",
flexGrow: 1,
overflowY: "auto",
}}
>
{!results.groups && !results.users && !results.policies && (
<Box sx={{ textAlign: "center" }}>
<h4>No Results Available</h4>
</Box>
)}
{!!results.groups && (
<Box className={"resultElement"}>
<SectionTitle separator sx={{ fontSize: 12 }}>
Group Mappings
</SectionTitle>
<Box sx={{ padding: "0 15px" }}>
{results.groups.map((groupData, index) => {
return (
<Fragment key={`policy-res-${index}`}>
<h4>{groupData.group}</h4>
{groupData.policies && (
<Fragment>
Policies:
<ul>
{groupData.policies.map(
(policy, index2) => (
<li key={`policy-group-${index2}`}>
{policy}
</li>
)
)}
</ul>
</Fragment>
)}
</Fragment>
);
})}
</Box>
</Box>
<LDAPResultsBlock results={results} entityName={"Group"} />
)}
{!!results.users && (
<Box className={"resultElement"}>
<SectionTitle separator sx={{ fontSize: 12 }}>
User Mappings
</SectionTitle>
<Box sx={{ padding: "0 15px" }}>
{results.users.map((groupData, index) => {
return (
<Fragment key={`users-res-${index}`}>
<h4>{groupData.user}</h4>
{groupData.policies && (
<Fragment>
Policies:
<ul>
{groupData.policies.map(
(policy, index2) => (
<li key={`policy-users-${index2}`}>
{policy}
</li>
)
)}
</ul>
</Fragment>
)}
</Fragment>
);
})}
</Box>
</Box>
<LDAPResultsBlock results={results} entityName={"User"} />
)}
{!!results.policies && (
<Box className={"resultElement"}>
<SectionTitle separator sx={{ fontSize: 12 }}>
Policy Mappings
</SectionTitle>
<Box sx={{ padding: "0 15px" }}>
{results.policies.map((groupData, index) => {
return (
<Fragment key={`policy-map-${index}`}>
<h4>{groupData.policy}</h4>
{groupData.groups && (
<Fragment>
Groups:
<ul>
{groupData.groups.map((group, index2) => (
<li key={`policy-map-group-${index}`}>
{group}
</li>
))}
</ul>
</Fragment>
)}
{groupData.users && (
<Fragment>
Users:
<ul>
{groupData.users.map((user, index3) => (
<li key={`policy-map-user-${index}`}>
{user}
</li>
))}
</ul>
</Fragment>
)}
</Fragment>
);
})}
</Box>
</Box>
<LDAPResultsBlock results={results} entityName={"Policy"} />
)}
</Box>
) : (
@@ -342,12 +301,22 @@ const LDAPEntitiesQuery = () => {
</Grid>
</Grid>
<Grid container>
<Grid item xs={12} sx={{ display: "flex", justifyContent: "flex-end" }}>
<Grid
item
xs={12}
sx={{
display: "flex",
justifyContent: "flex-start",
marginTop: 45,
padding: "0 20px",
}}
>
<Button
id={"search-entity"}
type={"button"}
variant={"callAction"}
onClick={searchEntities}
icon={<SearchIcon />}
>
Search
</Button>

View File

@@ -0,0 +1,165 @@
// This file is part of MinIO Console Server
// Copyright (c) 2023 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import React, { Fragment } from "react";
import { Box, CollapseCaret, GroupsMenuIcon, SectionTitle } from "mds";
import { LDAPEntitiesResponse } from "./types";
interface IResultBlock {
entityName: "Group" | "User" | "Policy";
results: LDAPEntitiesResponse;
}
interface IEntityResultName {
name: string;
}
interface IEntityResultItem {
blockName: "Policies" | "Groups" | "Users";
results: string[];
}
const EntityResultTitle = ({ name }: IEntityResultName) => {
return (
<h4>
<CollapseCaret style={{ transform: "rotateZ(90deg)" }} />
{name}
</h4>
);
};
const EntityResultItems = ({ blockName, results }: IEntityResultItem) => {
return (
<Fragment>
<strong>{blockName}:</strong>
<ul>
{results.map((res, index) => (
<li key={`policy-${blockName}-${index}`}>{res}</li>
))}
</ul>
</Fragment>
);
};
const LDAPResultsBlock = ({ entityName, results }: IResultBlock) => {
let entityLength = 0;
switch (entityName) {
case "Group":
entityLength = results.groups?.length || 0;
break;
case "Policy":
entityLength = results.policies?.length || 0;
break;
case "User":
entityLength = results.users?.length || 0;
break;
}
return (
<Box
className={"resultElement"}
sx={{
marginTop: 50,
"&:first-of-type": {
marginTop: 0,
},
}}
>
<SectionTitle
separator
sx={{ fontSize: 12 }}
icon={<GroupsMenuIcon style={{ width: 17, height: 17 }} />}
actions={
<Box sx={{ fontSize: 14 }}>
<strong>{entityLength}</strong> Entit
{entityLength === 1 ? "y" : "ies"} Found
</Box>
}
>
{entityName} Mappings
</SectionTitle>
<Box
className={"resultsList"}
sx={{
h4: {
borderBottom: "#e2e2e2 1px solid",
padding: "12px 0",
margin: 0,
marginBottom: 15,
display: "flex",
alignItems: "center",
"& svg": {
marginRight: 10,
fill: "#3C77A7",
},
},
}}
>
{entityName === "Group" &&
results.groups?.map((groupData, index) => {
return (
<Fragment key={`policy-res-${index}`}>
<EntityResultTitle name={groupData.group} />
{groupData.policies && (
<EntityResultItems
blockName={"Policies"}
results={groupData.policies}
/>
)}
</Fragment>
);
})}
{entityName === "User" &&
results.users?.map((groupData, index) => {
return (
<Fragment key={`users-res-${index}`}>
<EntityResultTitle name={groupData.user} />
{groupData.policies && (
<EntityResultItems
blockName={"Policies"}
results={groupData.policies}
/>
)}
</Fragment>
);
})}
{entityName === "Policy" &&
results.policies?.map((groupData, index) => {
return (
<Fragment key={`policy-map-${index}`}>
<EntityResultTitle name={groupData.policy} />
{groupData.groups && (
<EntityResultItems
blockName={"Groups"}
results={groupData.groups}
/>
)}
{groupData.users && (
<EntityResultItems
blockName={"Users"}
results={groupData.users}
/>
)}
</Fragment>
);
})}
</Box>
</Box>
);
};
export default LDAPResultsBlock;