Redirect back to original URL if user redirected to loging screen (#1187)
* Redirect back to original URL if user redirected to loging screen Signed-off-by: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com> * Cover SSO cases Signed-off-by: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com> Co-authored-by: Lenin Alevski <alevsk.8772@gmail.com> Co-authored-by: Alex <33497058+bexsoft@users.noreply.github.com>
This commit is contained in:
@@ -8,7 +8,7 @@ RUN yarn install
|
||||
|
||||
COPY ./portal-ui .
|
||||
|
||||
RUN yarn install && make build-static
|
||||
RUN make build-static
|
||||
|
||||
USER node
|
||||
|
||||
|
||||
@@ -29,6 +29,9 @@ export class API {
|
||||
.catch((err) => {
|
||||
// if we get unauthorized, kick out the user
|
||||
if (err.status === 401) {
|
||||
if (window.location.pathname !== "/") {
|
||||
localStorage.setItem("redirect-path", window.location.pathname);
|
||||
}
|
||||
clearSession();
|
||||
// Refresh the whole page to ensure cache is clear
|
||||
// and we dont end on an infinite loop
|
||||
|
||||
@@ -29,7 +29,7 @@ import {
|
||||
serverIsLoading,
|
||||
serverNeedsRestart,
|
||||
setMenuOpen,
|
||||
setSnackBarMessage
|
||||
setSnackBarMessage,
|
||||
} from "../../actions";
|
||||
import { ISessionResponse } from "./types";
|
||||
import { snackBarMessage } from "../../types";
|
||||
@@ -75,44 +75,44 @@ const styles = (theme: Theme) =>
|
||||
display: "flex",
|
||||
"& .MuiPaper-root.MuiSnackbarContent-root": {
|
||||
borderRadius: "0px 0px 5px 5px",
|
||||
boxShadow: "none"
|
||||
}
|
||||
boxShadow: "none",
|
||||
},
|
||||
},
|
||||
toolbar: {
|
||||
background: theme.palette.background.default,
|
||||
color: "black",
|
||||
paddingRight: 24 // keep right padding when drawer closed
|
||||
paddingRight: 24, // keep right padding when drawer closed
|
||||
},
|
||||
toolbarIcon: {
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "flex-end",
|
||||
padding: "0 8px",
|
||||
...theme.mixins.toolbar
|
||||
...theme.mixins.toolbar,
|
||||
},
|
||||
appBar: {
|
||||
zIndex: theme.zIndex.drawer + 1,
|
||||
transition: theme.transitions.create(["width", "margin"], {
|
||||
easing: theme.transitions.easing.sharp,
|
||||
duration: theme.transitions.duration.leavingScreen
|
||||
})
|
||||
duration: theme.transitions.duration.leavingScreen,
|
||||
}),
|
||||
},
|
||||
appBarShift: {
|
||||
marginLeft: drawerWidth,
|
||||
width: `calc(100% - ${drawerWidth}px)`,
|
||||
transition: theme.transitions.create(["width", "margin"], {
|
||||
easing: theme.transitions.easing.sharp,
|
||||
duration: theme.transitions.duration.enteringScreen
|
||||
})
|
||||
duration: theme.transitions.duration.enteringScreen,
|
||||
}),
|
||||
},
|
||||
menuButton: {
|
||||
marginRight: 36
|
||||
marginRight: 36,
|
||||
},
|
||||
menuButtonHidden: {
|
||||
display: "none"
|
||||
display: "none",
|
||||
},
|
||||
title: {
|
||||
flexGrow: 1
|
||||
flexGrow: 1,
|
||||
},
|
||||
drawerPaper: {
|
||||
position: "relative",
|
||||
@@ -120,44 +120,44 @@ const styles = (theme: Theme) =>
|
||||
width: drawerWidth,
|
||||
transition: theme.transitions.create("width", {
|
||||
easing: theme.transitions.easing.sharp,
|
||||
duration: theme.transitions.duration.enteringScreen
|
||||
duration: theme.transitions.duration.enteringScreen,
|
||||
}),
|
||||
overflowX: "hidden",
|
||||
background:
|
||||
"transparent linear-gradient(90deg, #073052 0%, #081C42 100%) 0% 0% no-repeat padding-box",
|
||||
boxShadow: "0px 3px 7px #00000014"
|
||||
boxShadow: "0px 3px 7px #00000014",
|
||||
},
|
||||
drawerPaperClose: {
|
||||
overflowX: "hidden",
|
||||
transition: theme.transitions.create("width", {
|
||||
easing: theme.transitions.easing.sharp,
|
||||
duration: theme.transitions.duration.leavingScreen
|
||||
duration: theme.transitions.duration.leavingScreen,
|
||||
}),
|
||||
width: theme.spacing(7),
|
||||
[theme.breakpoints.up("sm")]: {
|
||||
width: theme.spacing(9)
|
||||
}
|
||||
width: theme.spacing(9),
|
||||
},
|
||||
},
|
||||
content: {
|
||||
flexGrow: 1,
|
||||
height: "100vh",
|
||||
overflow: "auto",
|
||||
position: "relative"
|
||||
position: "relative",
|
||||
},
|
||||
container: {
|
||||
paddingBottom: theme.spacing(4),
|
||||
margin: 0,
|
||||
width: "100%",
|
||||
maxWidth: "initial"
|
||||
maxWidth: "initial",
|
||||
},
|
||||
paper: {
|
||||
padding: theme.spacing(2),
|
||||
display: "flex",
|
||||
overflow: "auto",
|
||||
flexDirection: "column"
|
||||
flexDirection: "column",
|
||||
},
|
||||
fixedHeight: {
|
||||
minHeight: 240
|
||||
minHeight: 240,
|
||||
},
|
||||
warningBar: {
|
||||
background: theme.palette.primary.main,
|
||||
@@ -165,13 +165,13 @@ const styles = (theme: Theme) =>
|
||||
heigh: "60px",
|
||||
widht: "100%",
|
||||
lineHeight: "60px",
|
||||
textAlign: "center"
|
||||
textAlign: "center",
|
||||
},
|
||||
progress: {
|
||||
height: "3px",
|
||||
backgroundColor: "#eaeaea"
|
||||
backgroundColor: "#eaeaea",
|
||||
},
|
||||
...snackBarCommon
|
||||
...snackBarCommon,
|
||||
});
|
||||
|
||||
interface IConsoleProps {
|
||||
@@ -190,17 +190,17 @@ interface IConsoleProps {
|
||||
}
|
||||
|
||||
const Console = ({
|
||||
classes,
|
||||
open,
|
||||
needsRestart,
|
||||
isServerLoading,
|
||||
serverNeedsRestart,
|
||||
serverIsLoading,
|
||||
session,
|
||||
loadingProgress,
|
||||
snackBarMessage,
|
||||
setSnackBarMessage
|
||||
}: IConsoleProps) => {
|
||||
classes,
|
||||
open,
|
||||
needsRestart,
|
||||
isServerLoading,
|
||||
serverNeedsRestart,
|
||||
serverIsLoading,
|
||||
session,
|
||||
loadingProgress,
|
||||
snackBarMessage,
|
||||
setSnackBarMessage,
|
||||
}: IConsoleProps) => {
|
||||
const [openSnackbar, setOpenSnackbar] = useState<boolean>(false);
|
||||
|
||||
const restartServer = () => {
|
||||
@@ -223,185 +223,186 @@ const Console = ({
|
||||
});
|
||||
};
|
||||
|
||||
const allowedPages = session.pages.reduce(
|
||||
(result: any, item: any, index: any) => {
|
||||
result[item] = true;
|
||||
return result;
|
||||
},
|
||||
{}
|
||||
);
|
||||
const allowedPages = !session
|
||||
? []
|
||||
: session.pages.reduce((result: any, item: any, index: any) => {
|
||||
result[item] = true;
|
||||
return result;
|
||||
}, {});
|
||||
const routes = [
|
||||
{
|
||||
component: Dashboard,
|
||||
path: "/dashboard"
|
||||
path: "/dashboard",
|
||||
},
|
||||
{
|
||||
component: Metrics,
|
||||
path: "/metrics"
|
||||
path: "/metrics",
|
||||
},
|
||||
{
|
||||
component: Buckets,
|
||||
path: "/buckets"
|
||||
path: "/buckets",
|
||||
},
|
||||
{
|
||||
component: Buckets,
|
||||
path: "/buckets/*"
|
||||
path: "/buckets/*",
|
||||
},
|
||||
{
|
||||
component: Watch,
|
||||
path: "/tools/watch"
|
||||
path: "/tools/watch",
|
||||
},
|
||||
{
|
||||
component: Users,
|
||||
path: "/users/:userName+"
|
||||
path: "/users/:userName+",
|
||||
},
|
||||
{
|
||||
component: Users,
|
||||
path: "/users"
|
||||
path: "/users",
|
||||
},
|
||||
{
|
||||
component: Groups,
|
||||
path: "/groups"
|
||||
path: "/groups",
|
||||
},
|
||||
{
|
||||
component: GroupsDetails,
|
||||
path: "/groups/:groupName+"
|
||||
path: "/groups/:groupName+",
|
||||
},
|
||||
{
|
||||
component: Policies,
|
||||
path: "/policies/*"
|
||||
path: "/policies/*",
|
||||
},
|
||||
{
|
||||
component: Policies,
|
||||
path: "/policies"
|
||||
path: "/policies",
|
||||
},
|
||||
{
|
||||
component: Heal,
|
||||
path: "/tools/heal"
|
||||
path: "/tools/heal",
|
||||
},
|
||||
{
|
||||
component: Trace,
|
||||
path: "/tools/trace"
|
||||
path: "/tools/trace",
|
||||
},
|
||||
{
|
||||
component: HealthInfo,
|
||||
path: "/tools/diagnostics"
|
||||
path: "/tools/diagnostics",
|
||||
},
|
||||
{
|
||||
component: ErrorLogs,
|
||||
path: "/tools/logs"
|
||||
path: "/tools/logs",
|
||||
},
|
||||
{
|
||||
component: LogsSearchMain,
|
||||
path: "/tools/audit-logs"
|
||||
path: "/tools/audit-logs",
|
||||
},
|
||||
{
|
||||
component: Tools,
|
||||
path: "/tools"
|
||||
path: "/tools",
|
||||
},
|
||||
{
|
||||
component: ConfigurationMain,
|
||||
path: "/settings"
|
||||
path: "/settings",
|
||||
},
|
||||
{
|
||||
component: ConfigurationMain,
|
||||
path: "/settings/:option"
|
||||
path: "/settings/:option",
|
||||
},
|
||||
{
|
||||
component: AddNotificationEndpoint,
|
||||
path: "/notification-endpoints/add/:service"
|
||||
path: "/notification-endpoints/add/:service",
|
||||
},
|
||||
{
|
||||
component: NotificationTypeSelector,
|
||||
path: "/notification-endpoints/add"
|
||||
path: "/notification-endpoints/add",
|
||||
},
|
||||
{
|
||||
component: NotificationEndpoints,
|
||||
path: "/notification-endpoints"
|
||||
path: "/notification-endpoints",
|
||||
},
|
||||
{
|
||||
component: AddTierConfiguration,
|
||||
path: "/tiers/add/:service"
|
||||
path: "/tiers/add/:service",
|
||||
},
|
||||
{
|
||||
component: TierTypeSelector,
|
||||
path: "/tiers/add"
|
||||
path: "/tiers/add",
|
||||
},
|
||||
{
|
||||
component: ListTiersConfiguration,
|
||||
path: "/tiers"
|
||||
path: "/tiers",
|
||||
},
|
||||
{
|
||||
component: Account,
|
||||
path: "/account",
|
||||
props: {
|
||||
changePassword: session.pages.includes("/account/change-password")
|
||||
}
|
||||
changePassword: (!session ? [] : session.pages).includes(
|
||||
"/account/change-password"
|
||||
),
|
||||
},
|
||||
},
|
||||
{
|
||||
component: ListTenants,
|
||||
path: "/tenants"
|
||||
path: "/tenants",
|
||||
},
|
||||
{
|
||||
component: AddTenant,
|
||||
path: "/tenants/add"
|
||||
path: "/tenants/add",
|
||||
},
|
||||
{
|
||||
component: Storage,
|
||||
path: "/storage"
|
||||
path: "/storage",
|
||||
},
|
||||
{
|
||||
component: Storage,
|
||||
path: "/storage/volumes"
|
||||
path: "/storage/volumes",
|
||||
},
|
||||
{
|
||||
component: Storage,
|
||||
path: "/storage/drives"
|
||||
path: "/storage/drives",
|
||||
},
|
||||
{
|
||||
component: TenantDetails,
|
||||
path: "/namespaces/:tenantNamespace/tenants/:tenantName"
|
||||
path: "/namespaces/:tenantNamespace/tenants/:tenantName",
|
||||
},
|
||||
{
|
||||
component: Hop,
|
||||
path: "/namespaces/:tenantNamespace/tenants/:tenantName/hop"
|
||||
path: "/namespaces/:tenantNamespace/tenants/:tenantName/hop",
|
||||
},
|
||||
{
|
||||
component: TenantDetails,
|
||||
path: "/namespaces/:tenantNamespace/tenants/:tenantName/pods/:podName"
|
||||
path: "/namespaces/:tenantNamespace/tenants/:tenantName/pods/:podName",
|
||||
},
|
||||
{
|
||||
component: TenantDetails,
|
||||
path: "/namespaces/:tenantNamespace/tenants/:tenantName/summary"
|
||||
path: "/namespaces/:tenantNamespace/tenants/:tenantName/summary",
|
||||
},
|
||||
{
|
||||
component: TenantDetails,
|
||||
path: "/namespaces/:tenantNamespace/tenants/:tenantName/metrics"
|
||||
path: "/namespaces/:tenantNamespace/tenants/:tenantName/metrics",
|
||||
},
|
||||
{
|
||||
component: TenantDetails,
|
||||
path: "/namespaces/:tenantNamespace/tenants/:tenantName/pods"
|
||||
path: "/namespaces/:tenantNamespace/tenants/:tenantName/pods",
|
||||
},
|
||||
{
|
||||
component: TenantDetails,
|
||||
path: "/namespaces/:tenantNamespace/tenants/:tenantName/pools"
|
||||
path: "/namespaces/:tenantNamespace/tenants/:tenantName/pools",
|
||||
},
|
||||
{
|
||||
component: TenantDetails,
|
||||
path: "/namespaces/:tenantNamespace/tenants/:tenantName/volumes"
|
||||
path: "/namespaces/:tenantNamespace/tenants/:tenantName/volumes",
|
||||
},
|
||||
{
|
||||
component: TenantDetails,
|
||||
path: "/namespaces/:tenantNamespace/tenants/:tenantName/license"
|
||||
path: "/namespaces/:tenantNamespace/tenants/:tenantName/license",
|
||||
},
|
||||
{
|
||||
component: TenantDetails,
|
||||
path: "/namespaces/:tenantNamespace/tenants/:tenantName/security"
|
||||
path: "/namespaces/:tenantNamespace/tenants/:tenantName/security",
|
||||
},
|
||||
{
|
||||
component: License,
|
||||
path: "/license"
|
||||
}
|
||||
path: "/license",
|
||||
},
|
||||
];
|
||||
const allowedRoutes = routes.filter((route: any) => allowedPages[route.path]);
|
||||
|
||||
@@ -432,7 +433,7 @@ const Console = ({
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
{session.status === "ok" ? (
|
||||
{session && session.status === "ok" ? (
|
||||
<div className={classes.root}>
|
||||
<CssBaseline />
|
||||
{!hideMenu && <Menu pages={session.pages} />}
|
||||
@@ -486,7 +487,7 @@ const Console = ({
|
||||
snackBarMessage.type === "error"
|
||||
? classes.errorSnackBar
|
||||
: ""
|
||||
}`
|
||||
}`,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
@@ -520,14 +521,14 @@ const mapState = (state: AppState) => ({
|
||||
isServerLoading: state.system.serverIsLoading,
|
||||
session: state.console.session,
|
||||
loadingProgress: state.system.loadingProgress,
|
||||
snackBarMessage: state.system.snackBar
|
||||
snackBarMessage: state.system.snackBar,
|
||||
});
|
||||
|
||||
const connector = connect(mapState, {
|
||||
setMenuOpen,
|
||||
serverNeedsRestart,
|
||||
serverIsLoading,
|
||||
setSnackBarMessage
|
||||
setSnackBarMessage,
|
||||
});
|
||||
|
||||
export default withStyles(styles)(connector(Console));
|
||||
|
||||
@@ -14,36 +14,34 @@ import { modalBasic } from "../Common/FormComponents/common/styleLibrary";
|
||||
import withStyles from "@mui/styles/withStyles";
|
||||
|
||||
type UserPickerModalProps = {
|
||||
classes?: any,
|
||||
title?: string
|
||||
preSelectedUsers?: string[]
|
||||
selectedGroup?: string,
|
||||
open: boolean,
|
||||
onClose: () => void,
|
||||
onSaveClick: () => void,
|
||||
groupStatus?: string,
|
||||
}
|
||||
|
||||
classes?: any;
|
||||
title?: string;
|
||||
preSelectedUsers?: string[];
|
||||
selectedGroup?: string;
|
||||
open: boolean;
|
||||
onClose: () => void;
|
||||
onSaveClick: () => void;
|
||||
groupStatus?: string;
|
||||
};
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
buttonContainer: {
|
||||
textAlign: "right",
|
||||
marginTop: "1rem"
|
||||
marginTop: "1rem",
|
||||
},
|
||||
...modalBasic
|
||||
...modalBasic,
|
||||
});
|
||||
|
||||
const AddGroupMember = ({
|
||||
classes,
|
||||
title = "",
|
||||
groupStatus = "enabled",
|
||||
preSelectedUsers = [],
|
||||
selectedGroup = "",
|
||||
open,
|
||||
onClose
|
||||
}: UserPickerModalProps) => {
|
||||
|
||||
classes,
|
||||
title = "",
|
||||
groupStatus = "enabled",
|
||||
preSelectedUsers = [],
|
||||
selectedGroup = "",
|
||||
open,
|
||||
onClose,
|
||||
}: UserPickerModalProps) => {
|
||||
const [selectedUsers, setSelectedUsers] = useState(preSelectedUsers);
|
||||
|
||||
function addMembersToGroup() {
|
||||
@@ -51,8 +49,7 @@ const AddGroupMember = ({
|
||||
.invoke("PUT", `/api/v1/group?name=${encodeURI(selectedGroup)}`, {
|
||||
group: selectedGroup,
|
||||
members: selectedUsers,
|
||||
status: groupStatus
|
||||
|
||||
status: groupStatus,
|
||||
})
|
||||
.then((res) => {
|
||||
onClose();
|
||||
@@ -64,16 +61,8 @@ const AddGroupMember = ({
|
||||
}
|
||||
|
||||
return (
|
||||
<ModalWrapper
|
||||
modalOpen={open}
|
||||
onClose={onClose}
|
||||
title={title}
|
||||
>
|
||||
|
||||
<PredefinedList
|
||||
label={`Selected Group`}
|
||||
content={selectedGroup}
|
||||
/>
|
||||
<ModalWrapper modalOpen={open} onClose={onClose} title={title}>
|
||||
<PredefinedList label={`Selected Group`} content={selectedGroup} />
|
||||
|
||||
<br />
|
||||
<UsersSelectors
|
||||
@@ -83,7 +72,6 @@ const AddGroupMember = ({
|
||||
/>
|
||||
|
||||
<Grid item xs={12} className={classes.buttonContainer}>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
color="primary"
|
||||
@@ -106,15 +94,12 @@ const AddGroupMember = ({
|
||||
Save
|
||||
</Button>
|
||||
</Grid>
|
||||
|
||||
</ModalWrapper>
|
||||
);
|
||||
|
||||
};
|
||||
|
||||
|
||||
const mapDispatchToProps = {
|
||||
setModalErrorSnackMessage
|
||||
setModalErrorSnackMessage,
|
||||
};
|
||||
|
||||
const connector = connect(null, mapDispatchToProps);
|
||||
|
||||
@@ -31,7 +31,7 @@ import {
|
||||
actionsTray,
|
||||
containerForHeader,
|
||||
linkStyles,
|
||||
searchField
|
||||
searchField,
|
||||
} from "../Common/FormComponents/common/styleLibrary";
|
||||
import { ErrorResponseHandler } from "../../../common/types";
|
||||
import api from "../../../common/api";
|
||||
@@ -53,42 +53,42 @@ interface IGroupsProps {
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
seeMore: {
|
||||
marginTop: theme.spacing(3)
|
||||
marginTop: theme.spacing(3),
|
||||
},
|
||||
paper: {
|
||||
// padding: theme.spacing(2),
|
||||
display: "flex",
|
||||
overflow: "auto",
|
||||
flexDirection: "column"
|
||||
flexDirection: "column",
|
||||
},
|
||||
addSideBar: {
|
||||
width: "320px",
|
||||
padding: "20px"
|
||||
padding: "20px",
|
||||
},
|
||||
tableToolbar: {
|
||||
paddingLeft: theme.spacing(2),
|
||||
paddingRight: theme.spacing(0)
|
||||
paddingRight: theme.spacing(0),
|
||||
},
|
||||
wrapCell: {
|
||||
maxWidth: "200px",
|
||||
whiteSpace: "normal",
|
||||
wordWrap: "break-word"
|
||||
wordWrap: "break-word",
|
||||
},
|
||||
twHeight: {
|
||||
minHeight: 600
|
||||
minHeight: 600,
|
||||
},
|
||||
minTableHeader: {
|
||||
color: "#393939",
|
||||
"& tr": {
|
||||
"& th": {
|
||||
fontWeight: "bold"
|
||||
}
|
||||
}
|
||||
fontWeight: "bold",
|
||||
},
|
||||
},
|
||||
},
|
||||
...linkStyles(theme.palette.info.main),
|
||||
...actionsTray,
|
||||
...searchField,
|
||||
...containerForHeader(theme.spacing(4))
|
||||
...containerForHeader(theme.spacing(4)),
|
||||
});
|
||||
|
||||
const Groups = ({ classes, setErrorSnackMessage }: IGroupsProps) => {
|
||||
@@ -158,7 +158,7 @@ const Groups = ({ classes, setErrorSnackMessage }: IGroupsProps) => {
|
||||
|
||||
const tableActions = [
|
||||
{ type: "view", onClick: viewAction },
|
||||
{ type: "delete", onClick: deleteAction }
|
||||
{ type: "delete", onClick: deleteAction },
|
||||
];
|
||||
|
||||
return (
|
||||
@@ -202,7 +202,7 @@ const Groups = ({ classes, setErrorSnackMessage }: IGroupsProps) => {
|
||||
<InputAdornment position="start">
|
||||
<SearchIcon />
|
||||
</InputAdornment>
|
||||
)
|
||||
),
|
||||
}}
|
||||
onChange={(e) => {
|
||||
setFilter(e.target.value);
|
||||
@@ -313,7 +313,7 @@ const Groups = ({ classes, setErrorSnackMessage }: IGroupsProps) => {
|
||||
};
|
||||
|
||||
const mapDispatchToProps = {
|
||||
setErrorSnackMessage
|
||||
setErrorSnackMessage,
|
||||
};
|
||||
|
||||
const connector = connect(null, mapDispatchToProps);
|
||||
|
||||
@@ -3,8 +3,15 @@ import PageHeader from "../Common/PageHeader/PageHeader";
|
||||
import { Link, useParams } from "react-router-dom";
|
||||
import { Theme } from "@mui/material/styles";
|
||||
import createStyles from "@mui/styles/createStyles";
|
||||
import { actionsTray, containerForHeader, searchField } from "../Common/FormComponents/common/styleLibrary";
|
||||
import { setErrorSnackMessage, setModalErrorSnackMessage } from "../../../actions";
|
||||
import {
|
||||
actionsTray,
|
||||
containerForHeader,
|
||||
searchField,
|
||||
} from "../Common/FormComponents/common/styleLibrary";
|
||||
import {
|
||||
setErrorSnackMessage,
|
||||
setModalErrorSnackMessage,
|
||||
} from "../../../actions";
|
||||
import { connect } from "react-redux";
|
||||
import withStyles from "@mui/styles/withStyles";
|
||||
import { Button, Grid, IconButton, Tooltip } from "@mui/material";
|
||||
@@ -22,17 +29,16 @@ import AddGroupMember from "./AddGroupMember";
|
||||
import { ErrorResponseHandler } from "../../../common/types";
|
||||
import DeleteGroup from "./DeleteGroup";
|
||||
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
breadcrumLink: {
|
||||
textDecoration: "none",
|
||||
color: "black"
|
||||
color: "black",
|
||||
},
|
||||
...actionsTray,
|
||||
...searchField,
|
||||
actionsTray: { ...actionsTray.actionsTray },
|
||||
...containerForHeader(theme.spacing(4))
|
||||
...containerForHeader(theme.spacing(4)),
|
||||
});
|
||||
|
||||
interface IGroupDetailsProps {
|
||||
@@ -42,24 +48,22 @@ interface IGroupDetailsProps {
|
||||
}
|
||||
|
||||
type TabItemsProps = {
|
||||
activeTab: number,
|
||||
onTabChange: (tab: number) => void
|
||||
}
|
||||
activeTab: number;
|
||||
onTabChange: (tab: number) => void;
|
||||
};
|
||||
|
||||
type DetailsHeaderProps = {
|
||||
classes: any
|
||||
}
|
||||
classes: any;
|
||||
};
|
||||
|
||||
type GroupInfo = {
|
||||
members?: any[]
|
||||
name?: string
|
||||
policy?: string
|
||||
status?: string
|
||||
}
|
||||
|
||||
members?: any[];
|
||||
name?: string;
|
||||
policy?: string;
|
||||
status?: string;
|
||||
};
|
||||
|
||||
const TabItems = ({ activeTab, onTabChange }: TabItemsProps) => {
|
||||
|
||||
return (
|
||||
<List component="nav" dense={true}>
|
||||
<ListItem
|
||||
@@ -80,12 +84,10 @@ const TabItems = ({ activeTab, onTabChange }: TabItemsProps) => {
|
||||
>
|
||||
<ListItemText primary="Policies" />
|
||||
</ListItem>
|
||||
|
||||
</List>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
export const formatPolicy = (policy: string = ""): string[] => {
|
||||
if (policy.length <= 0) return [];
|
||||
return policy.split(",");
|
||||
@@ -95,7 +97,6 @@ export const getPoliciesAsString = (policies: string[]): string => {
|
||||
return policies.join(", ");
|
||||
};
|
||||
|
||||
|
||||
const GroupDetailsHeader = ({ classes }: DetailsHeaderProps) => {
|
||||
return (
|
||||
<PageHeader
|
||||
@@ -111,9 +112,7 @@ const GroupDetailsHeader = ({ classes }: DetailsHeaderProps) => {
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
const GroupsDetails = ({ classes }: IGroupDetailsProps) => {
|
||||
|
||||
const [currentTab, setCurrentTab] = useState<number>(0);
|
||||
const [groupDetails, setGroupDetails] = useState<GroupInfo>({});
|
||||
|
||||
@@ -122,15 +121,9 @@ const GroupsDetails = ({ classes }: IGroupDetailsProps) => {
|
||||
const [usersOpen, setUsersOpen] = useState<boolean>(false);
|
||||
const [deleteOpen, setDeleteOpen] = useState<boolean>(false);
|
||||
|
||||
const {
|
||||
groupName = ""
|
||||
} = useParams<Record<string, string>>();
|
||||
const { groupName = "" } = useParams<Record<string, string>>();
|
||||
|
||||
const {
|
||||
members = [],
|
||||
policy = "",
|
||||
status: groupEnabled
|
||||
} = groupDetails;
|
||||
const { members = [], policy = "", status: groupEnabled } = groupDetails;
|
||||
|
||||
useEffect(() => {
|
||||
if (groupName) {
|
||||
@@ -148,18 +141,18 @@ const GroupsDetails = ({ classes }: IGroupDetailsProps) => {
|
||||
.invoke("GET", `/api/v1/group?name=${encodeURI(groupName)}`)
|
||||
.then((res: any) => {
|
||||
setGroupDetails(res);
|
||||
}).catch(() => {
|
||||
setGroupDetails({});
|
||||
});
|
||||
};
|
||||
})
|
||||
.catch(() => {
|
||||
setGroupDetails({});
|
||||
});
|
||||
}
|
||||
|
||||
function toggleGroupStatus(nextStatus: boolean) {
|
||||
|
||||
return api
|
||||
.invoke("PUT", `/api/v1/group?name=${encodeURI(groupName)}`, {
|
||||
group: groupName,
|
||||
members: members,
|
||||
status: nextStatus ? "enabled" : "disabled"
|
||||
status: nextStatus ? "enabled" : "disabled",
|
||||
})
|
||||
.then((res) => {
|
||||
fetchGroupInfo();
|
||||
@@ -170,7 +163,6 @@ const GroupsDetails = ({ classes }: IGroupDetailsProps) => {
|
||||
}
|
||||
|
||||
return (
|
||||
|
||||
<React.Fragment>
|
||||
<GroupDetailsHeader classes={classes} />
|
||||
<Grid container className={classes.container}>
|
||||
@@ -183,7 +175,9 @@ const GroupsDetails = ({ classes }: IGroupDetailsProps) => {
|
||||
}
|
||||
title={groupName}
|
||||
subTitle={
|
||||
<Fragment>Status: {isGroupEnabled ? "Enabled" : "Disabled"}</Fragment>
|
||||
<Fragment>
|
||||
Status: {isGroupEnabled ? "Enabled" : "Disabled"}
|
||||
</Fragment>
|
||||
}
|
||||
actions={
|
||||
<Fragment>
|
||||
@@ -214,9 +208,12 @@ const GroupsDetails = ({ classes }: IGroupDetailsProps) => {
|
||||
</Grid>
|
||||
|
||||
<Grid item xs={2}>
|
||||
<TabItems activeTab={currentTab} onTabChange={(num) => {
|
||||
setCurrentTab(num);
|
||||
}} />
|
||||
<TabItems
|
||||
activeTab={currentTab}
|
||||
onTabChange={(num) => {
|
||||
setCurrentTab(num);
|
||||
}}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={10}>
|
||||
<Grid item xs={12}>
|
||||
@@ -270,8 +267,8 @@ const GroupsDetails = ({ classes }: IGroupDetailsProps) => {
|
||||
type: "view",
|
||||
onClick: (policy) => {
|
||||
history.push(`/policies/${policy}`);
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
]}
|
||||
columns={[{ label: "Policy", elementKey: "" }]}
|
||||
isLoading={false}
|
||||
@@ -297,12 +294,10 @@ const GroupsDetails = ({ classes }: IGroupDetailsProps) => {
|
||||
/>
|
||||
) : null}
|
||||
|
||||
{usersOpen ?
|
||||
{usersOpen ? (
|
||||
<AddGroupMember
|
||||
selectedGroup={groupName}
|
||||
onSaveClick={() => {
|
||||
|
||||
}}
|
||||
onSaveClick={() => {}}
|
||||
title={memberActionText}
|
||||
groupStatus={groupEnabled}
|
||||
classes={classes}
|
||||
@@ -311,7 +306,9 @@ const GroupsDetails = ({ classes }: IGroupDetailsProps) => {
|
||||
onClose={() => {
|
||||
setUsersOpen(false);
|
||||
fetchGroupInfo();
|
||||
}} /> : null}
|
||||
}}
|
||||
/>
|
||||
) : null}
|
||||
|
||||
{deleteOpen && (
|
||||
<DeleteGroup
|
||||
@@ -328,14 +325,12 @@ const GroupsDetails = ({ classes }: IGroupDetailsProps) => {
|
||||
{/*Modals*/}
|
||||
</React.Fragment>
|
||||
);
|
||||
|
||||
};
|
||||
|
||||
|
||||
const mapDispatchToProps = {
|
||||
setErrorSnackMessage
|
||||
setErrorSnackMessage,
|
||||
};
|
||||
|
||||
const connector = connect(null, mapDispatchToProps);
|
||||
|
||||
export default withStyles(styles)(connector(GroupsDetails));
|
||||
export default withStyles(styles)(connector(GroupsDetails));
|
||||
|
||||
@@ -40,7 +40,15 @@ const LoginCallback: FC<RouteComponentProps> = ({ location }) => {
|
||||
// store the jwt token
|
||||
storage.setItem("token", res.sessionId);
|
||||
// We push to history the new URL.
|
||||
window.location.href = "/";
|
||||
let targetPath = "/";
|
||||
if (
|
||||
localStorage.getItem("redirect-path") &&
|
||||
localStorage.getItem("redirect-path") != ""
|
||||
) {
|
||||
targetPath = `${localStorage.getItem("redirect-path")}`;
|
||||
localStorage.setItem("redirect-path", "");
|
||||
}
|
||||
window.location.href = targetPath;
|
||||
}
|
||||
})
|
||||
.catch((res: any) => {
|
||||
|
||||
@@ -242,7 +242,15 @@ const Login = ({
|
||||
if (loginStrategy.loginStrategy === loginStrategyType.form) {
|
||||
localStorage.setItem("userLoggedIn", encodeFileName(accessKey));
|
||||
}
|
||||
history.push("/");
|
||||
let targetPath = "/";
|
||||
if (
|
||||
localStorage.getItem("redirect-path") &&
|
||||
localStorage.getItem("redirect-path") != ""
|
||||
) {
|
||||
targetPath = `${localStorage.getItem("redirect-path")}`;
|
||||
localStorage.setItem("redirect-path", "");
|
||||
}
|
||||
history.push(targetPath);
|
||||
})
|
||||
.catch((err) => {
|
||||
setLoginSending(false);
|
||||
|
||||
Reference in New Issue
Block a user