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:
Daniel Valdivia
2021-11-04 13:31:55 -07:00
committed by GitHub
parent 1bb7012d53
commit a9937afc64
8 changed files with 197 additions and 197 deletions

View File

@@ -8,7 +8,7 @@ RUN yarn install
COPY ./portal-ui . COPY ./portal-ui .
RUN yarn install && make build-static RUN make build-static
USER node USER node

View File

@@ -29,6 +29,9 @@ export class API {
.catch((err) => { .catch((err) => {
// if we get unauthorized, kick out the user // if we get unauthorized, kick out the user
if (err.status === 401) { if (err.status === 401) {
if (window.location.pathname !== "/") {
localStorage.setItem("redirect-path", window.location.pathname);
}
clearSession(); clearSession();
// Refresh the whole page to ensure cache is clear // Refresh the whole page to ensure cache is clear
// and we dont end on an infinite loop // and we dont end on an infinite loop

View File

@@ -29,7 +29,7 @@ import {
serverIsLoading, serverIsLoading,
serverNeedsRestart, serverNeedsRestart,
setMenuOpen, setMenuOpen,
setSnackBarMessage setSnackBarMessage,
} from "../../actions"; } from "../../actions";
import { ISessionResponse } from "./types"; import { ISessionResponse } from "./types";
import { snackBarMessage } from "../../types"; import { snackBarMessage } from "../../types";
@@ -75,44 +75,44 @@ const styles = (theme: Theme) =>
display: "flex", display: "flex",
"& .MuiPaper-root.MuiSnackbarContent-root": { "& .MuiPaper-root.MuiSnackbarContent-root": {
borderRadius: "0px 0px 5px 5px", borderRadius: "0px 0px 5px 5px",
boxShadow: "none" boxShadow: "none",
} },
}, },
toolbar: { toolbar: {
background: theme.palette.background.default, background: theme.palette.background.default,
color: "black", color: "black",
paddingRight: 24 // keep right padding when drawer closed paddingRight: 24, // keep right padding when drawer closed
}, },
toolbarIcon: { toolbarIcon: {
display: "flex", display: "flex",
alignItems: "center", alignItems: "center",
justifyContent: "flex-end", justifyContent: "flex-end",
padding: "0 8px", padding: "0 8px",
...theme.mixins.toolbar ...theme.mixins.toolbar,
}, },
appBar: { appBar: {
zIndex: theme.zIndex.drawer + 1, zIndex: theme.zIndex.drawer + 1,
transition: theme.transitions.create(["width", "margin"], { transition: theme.transitions.create(["width", "margin"], {
easing: theme.transitions.easing.sharp, easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.leavingScreen duration: theme.transitions.duration.leavingScreen,
}) }),
}, },
appBarShift: { appBarShift: {
marginLeft: drawerWidth, marginLeft: drawerWidth,
width: `calc(100% - ${drawerWidth}px)`, width: `calc(100% - ${drawerWidth}px)`,
transition: theme.transitions.create(["width", "margin"], { transition: theme.transitions.create(["width", "margin"], {
easing: theme.transitions.easing.sharp, easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.enteringScreen duration: theme.transitions.duration.enteringScreen,
}) }),
}, },
menuButton: { menuButton: {
marginRight: 36 marginRight: 36,
}, },
menuButtonHidden: { menuButtonHidden: {
display: "none" display: "none",
}, },
title: { title: {
flexGrow: 1 flexGrow: 1,
}, },
drawerPaper: { drawerPaper: {
position: "relative", position: "relative",
@@ -120,44 +120,44 @@ const styles = (theme: Theme) =>
width: drawerWidth, width: drawerWidth,
transition: theme.transitions.create("width", { transition: theme.transitions.create("width", {
easing: theme.transitions.easing.sharp, easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.enteringScreen duration: theme.transitions.duration.enteringScreen,
}), }),
overflowX: "hidden", overflowX: "hidden",
background: background:
"transparent linear-gradient(90deg, #073052 0%, #081C42 100%) 0% 0% no-repeat padding-box", "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: { drawerPaperClose: {
overflowX: "hidden", overflowX: "hidden",
transition: theme.transitions.create("width", { transition: theme.transitions.create("width", {
easing: theme.transitions.easing.sharp, easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.leavingScreen duration: theme.transitions.duration.leavingScreen,
}), }),
width: theme.spacing(7), width: theme.spacing(7),
[theme.breakpoints.up("sm")]: { [theme.breakpoints.up("sm")]: {
width: theme.spacing(9) width: theme.spacing(9),
} },
}, },
content: { content: {
flexGrow: 1, flexGrow: 1,
height: "100vh", height: "100vh",
overflow: "auto", overflow: "auto",
position: "relative" position: "relative",
}, },
container: { container: {
paddingBottom: theme.spacing(4), paddingBottom: theme.spacing(4),
margin: 0, margin: 0,
width: "100%", width: "100%",
maxWidth: "initial" maxWidth: "initial",
}, },
paper: { paper: {
padding: theme.spacing(2), padding: theme.spacing(2),
display: "flex", display: "flex",
overflow: "auto", overflow: "auto",
flexDirection: "column" flexDirection: "column",
}, },
fixedHeight: { fixedHeight: {
minHeight: 240 minHeight: 240,
}, },
warningBar: { warningBar: {
background: theme.palette.primary.main, background: theme.palette.primary.main,
@@ -165,13 +165,13 @@ const styles = (theme: Theme) =>
heigh: "60px", heigh: "60px",
widht: "100%", widht: "100%",
lineHeight: "60px", lineHeight: "60px",
textAlign: "center" textAlign: "center",
}, },
progress: { progress: {
height: "3px", height: "3px",
backgroundColor: "#eaeaea" backgroundColor: "#eaeaea",
}, },
...snackBarCommon ...snackBarCommon,
}); });
interface IConsoleProps { interface IConsoleProps {
@@ -190,17 +190,17 @@ interface IConsoleProps {
} }
const Console = ({ const Console = ({
classes, classes,
open, open,
needsRestart, needsRestart,
isServerLoading, isServerLoading,
serverNeedsRestart, serverNeedsRestart,
serverIsLoading, serverIsLoading,
session, session,
loadingProgress, loadingProgress,
snackBarMessage, snackBarMessage,
setSnackBarMessage setSnackBarMessage,
}: IConsoleProps) => { }: IConsoleProps) => {
const [openSnackbar, setOpenSnackbar] = useState<boolean>(false); const [openSnackbar, setOpenSnackbar] = useState<boolean>(false);
const restartServer = () => { const restartServer = () => {
@@ -223,185 +223,186 @@ const Console = ({
}); });
}; };
const allowedPages = session.pages.reduce( const allowedPages = !session
(result: any, item: any, index: any) => { ? []
result[item] = true; : session.pages.reduce((result: any, item: any, index: any) => {
return result; result[item] = true;
}, return result;
{} }, {});
);
const routes = [ const routes = [
{ {
component: Dashboard, component: Dashboard,
path: "/dashboard" path: "/dashboard",
}, },
{ {
component: Metrics, component: Metrics,
path: "/metrics" path: "/metrics",
}, },
{ {
component: Buckets, component: Buckets,
path: "/buckets" path: "/buckets",
}, },
{ {
component: Buckets, component: Buckets,
path: "/buckets/*" path: "/buckets/*",
}, },
{ {
component: Watch, component: Watch,
path: "/tools/watch" path: "/tools/watch",
}, },
{ {
component: Users, component: Users,
path: "/users/:userName+" path: "/users/:userName+",
}, },
{ {
component: Users, component: Users,
path: "/users" path: "/users",
}, },
{ {
component: Groups, component: Groups,
path: "/groups" path: "/groups",
}, },
{ {
component: GroupsDetails, component: GroupsDetails,
path: "/groups/:groupName+" path: "/groups/:groupName+",
}, },
{ {
component: Policies, component: Policies,
path: "/policies/*" path: "/policies/*",
}, },
{ {
component: Policies, component: Policies,
path: "/policies" path: "/policies",
}, },
{ {
component: Heal, component: Heal,
path: "/tools/heal" path: "/tools/heal",
}, },
{ {
component: Trace, component: Trace,
path: "/tools/trace" path: "/tools/trace",
}, },
{ {
component: HealthInfo, component: HealthInfo,
path: "/tools/diagnostics" path: "/tools/diagnostics",
}, },
{ {
component: ErrorLogs, component: ErrorLogs,
path: "/tools/logs" path: "/tools/logs",
}, },
{ {
component: LogsSearchMain, component: LogsSearchMain,
path: "/tools/audit-logs" path: "/tools/audit-logs",
}, },
{ {
component: Tools, component: Tools,
path: "/tools" path: "/tools",
}, },
{ {
component: ConfigurationMain, component: ConfigurationMain,
path: "/settings" path: "/settings",
}, },
{ {
component: ConfigurationMain, component: ConfigurationMain,
path: "/settings/:option" path: "/settings/:option",
}, },
{ {
component: AddNotificationEndpoint, component: AddNotificationEndpoint,
path: "/notification-endpoints/add/:service" path: "/notification-endpoints/add/:service",
}, },
{ {
component: NotificationTypeSelector, component: NotificationTypeSelector,
path: "/notification-endpoints/add" path: "/notification-endpoints/add",
}, },
{ {
component: NotificationEndpoints, component: NotificationEndpoints,
path: "/notification-endpoints" path: "/notification-endpoints",
}, },
{ {
component: AddTierConfiguration, component: AddTierConfiguration,
path: "/tiers/add/:service" path: "/tiers/add/:service",
}, },
{ {
component: TierTypeSelector, component: TierTypeSelector,
path: "/tiers/add" path: "/tiers/add",
}, },
{ {
component: ListTiersConfiguration, component: ListTiersConfiguration,
path: "/tiers" path: "/tiers",
}, },
{ {
component: Account, component: Account,
path: "/account", path: "/account",
props: { props: {
changePassword: session.pages.includes("/account/change-password") changePassword: (!session ? [] : session.pages).includes(
} "/account/change-password"
),
},
}, },
{ {
component: ListTenants, component: ListTenants,
path: "/tenants" path: "/tenants",
}, },
{ {
component: AddTenant, component: AddTenant,
path: "/tenants/add" path: "/tenants/add",
}, },
{ {
component: Storage, component: Storage,
path: "/storage" path: "/storage",
}, },
{ {
component: Storage, component: Storage,
path: "/storage/volumes" path: "/storage/volumes",
}, },
{ {
component: Storage, component: Storage,
path: "/storage/drives" path: "/storage/drives",
}, },
{ {
component: TenantDetails, component: TenantDetails,
path: "/namespaces/:tenantNamespace/tenants/:tenantName" path: "/namespaces/:tenantNamespace/tenants/:tenantName",
}, },
{ {
component: Hop, component: Hop,
path: "/namespaces/:tenantNamespace/tenants/:tenantName/hop" path: "/namespaces/:tenantNamespace/tenants/:tenantName/hop",
}, },
{ {
component: TenantDetails, component: TenantDetails,
path: "/namespaces/:tenantNamespace/tenants/:tenantName/pods/:podName" path: "/namespaces/:tenantNamespace/tenants/:tenantName/pods/:podName",
}, },
{ {
component: TenantDetails, component: TenantDetails,
path: "/namespaces/:tenantNamespace/tenants/:tenantName/summary" path: "/namespaces/:tenantNamespace/tenants/:tenantName/summary",
}, },
{ {
component: TenantDetails, component: TenantDetails,
path: "/namespaces/:tenantNamespace/tenants/:tenantName/metrics" path: "/namespaces/:tenantNamespace/tenants/:tenantName/metrics",
}, },
{ {
component: TenantDetails, component: TenantDetails,
path: "/namespaces/:tenantNamespace/tenants/:tenantName/pods" path: "/namespaces/:tenantNamespace/tenants/:tenantName/pods",
}, },
{ {
component: TenantDetails, component: TenantDetails,
path: "/namespaces/:tenantNamespace/tenants/:tenantName/pools" path: "/namespaces/:tenantNamespace/tenants/:tenantName/pools",
}, },
{ {
component: TenantDetails, component: TenantDetails,
path: "/namespaces/:tenantNamespace/tenants/:tenantName/volumes" path: "/namespaces/:tenantNamespace/tenants/:tenantName/volumes",
}, },
{ {
component: TenantDetails, component: TenantDetails,
path: "/namespaces/:tenantNamespace/tenants/:tenantName/license" path: "/namespaces/:tenantNamespace/tenants/:tenantName/license",
}, },
{ {
component: TenantDetails, component: TenantDetails,
path: "/namespaces/:tenantNamespace/tenants/:tenantName/security" path: "/namespaces/:tenantNamespace/tenants/:tenantName/security",
}, },
{ {
component: License, component: License,
path: "/license" path: "/license",
} },
]; ];
const allowedRoutes = routes.filter((route: any) => allowedPages[route.path]); const allowedRoutes = routes.filter((route: any) => allowedPages[route.path]);
@@ -432,7 +433,7 @@ const Console = ({
return ( return (
<Fragment> <Fragment>
{session.status === "ok" ? ( {session && session.status === "ok" ? (
<div className={classes.root}> <div className={classes.root}>
<CssBaseline /> <CssBaseline />
{!hideMenu && <Menu pages={session.pages} />} {!hideMenu && <Menu pages={session.pages} />}
@@ -486,7 +487,7 @@ const Console = ({
snackBarMessage.type === "error" snackBarMessage.type === "error"
? classes.errorSnackBar ? classes.errorSnackBar
: "" : ""
}` }`,
}} }}
/> />
</div> </div>
@@ -520,14 +521,14 @@ const mapState = (state: AppState) => ({
isServerLoading: state.system.serverIsLoading, isServerLoading: state.system.serverIsLoading,
session: state.console.session, session: state.console.session,
loadingProgress: state.system.loadingProgress, loadingProgress: state.system.loadingProgress,
snackBarMessage: state.system.snackBar snackBarMessage: state.system.snackBar,
}); });
const connector = connect(mapState, { const connector = connect(mapState, {
setMenuOpen, setMenuOpen,
serverNeedsRestart, serverNeedsRestart,
serverIsLoading, serverIsLoading,
setSnackBarMessage setSnackBarMessage,
}); });
export default withStyles(styles)(connector(Console)); export default withStyles(styles)(connector(Console));

View File

@@ -14,36 +14,34 @@ import { modalBasic } from "../Common/FormComponents/common/styleLibrary";
import withStyles from "@mui/styles/withStyles"; import withStyles from "@mui/styles/withStyles";
type UserPickerModalProps = { type UserPickerModalProps = {
classes?: any, classes?: any;
title?: string title?: string;
preSelectedUsers?: string[] preSelectedUsers?: string[];
selectedGroup?: string, selectedGroup?: string;
open: boolean, open: boolean;
onClose: () => void, onClose: () => void;
onSaveClick: () => void, onSaveClick: () => void;
groupStatus?: string, groupStatus?: string;
} };
const styles = (theme: Theme) => const styles = (theme: Theme) =>
createStyles({ createStyles({
buttonContainer: { buttonContainer: {
textAlign: "right", textAlign: "right",
marginTop: "1rem" marginTop: "1rem",
}, },
...modalBasic ...modalBasic,
}); });
const AddGroupMember = ({ const AddGroupMember = ({
classes, classes,
title = "", title = "",
groupStatus = "enabled", groupStatus = "enabled",
preSelectedUsers = [], preSelectedUsers = [],
selectedGroup = "", selectedGroup = "",
open, open,
onClose onClose,
}: UserPickerModalProps) => { }: UserPickerModalProps) => {
const [selectedUsers, setSelectedUsers] = useState(preSelectedUsers); const [selectedUsers, setSelectedUsers] = useState(preSelectedUsers);
function addMembersToGroup() { function addMembersToGroup() {
@@ -51,8 +49,7 @@ const AddGroupMember = ({
.invoke("PUT", `/api/v1/group?name=${encodeURI(selectedGroup)}`, { .invoke("PUT", `/api/v1/group?name=${encodeURI(selectedGroup)}`, {
group: selectedGroup, group: selectedGroup,
members: selectedUsers, members: selectedUsers,
status: groupStatus status: groupStatus,
}) })
.then((res) => { .then((res) => {
onClose(); onClose();
@@ -64,16 +61,8 @@ const AddGroupMember = ({
} }
return ( return (
<ModalWrapper <ModalWrapper modalOpen={open} onClose={onClose} title={title}>
modalOpen={open} <PredefinedList label={`Selected Group`} content={selectedGroup} />
onClose={onClose}
title={title}
>
<PredefinedList
label={`Selected Group`}
content={selectedGroup}
/>
<br /> <br />
<UsersSelectors <UsersSelectors
@@ -83,7 +72,6 @@ const AddGroupMember = ({
/> />
<Grid item xs={12} className={classes.buttonContainer}> <Grid item xs={12} className={classes.buttonContainer}>
<button <button
type="button" type="button"
color="primary" color="primary"
@@ -106,15 +94,12 @@ const AddGroupMember = ({
Save Save
</Button> </Button>
</Grid> </Grid>
</ModalWrapper> </ModalWrapper>
); );
}; };
const mapDispatchToProps = { const mapDispatchToProps = {
setModalErrorSnackMessage setModalErrorSnackMessage,
}; };
const connector = connect(null, mapDispatchToProps); const connector = connect(null, mapDispatchToProps);

View File

@@ -31,7 +31,7 @@ import {
actionsTray, actionsTray,
containerForHeader, containerForHeader,
linkStyles, linkStyles,
searchField searchField,
} from "../Common/FormComponents/common/styleLibrary"; } from "../Common/FormComponents/common/styleLibrary";
import { ErrorResponseHandler } from "../../../common/types"; import { ErrorResponseHandler } from "../../../common/types";
import api from "../../../common/api"; import api from "../../../common/api";
@@ -53,42 +53,42 @@ interface IGroupsProps {
const styles = (theme: Theme) => const styles = (theme: Theme) =>
createStyles({ createStyles({
seeMore: { seeMore: {
marginTop: theme.spacing(3) marginTop: theme.spacing(3),
}, },
paper: { paper: {
// padding: theme.spacing(2), // padding: theme.spacing(2),
display: "flex", display: "flex",
overflow: "auto", overflow: "auto",
flexDirection: "column" flexDirection: "column",
}, },
addSideBar: { addSideBar: {
width: "320px", width: "320px",
padding: "20px" padding: "20px",
}, },
tableToolbar: { tableToolbar: {
paddingLeft: theme.spacing(2), paddingLeft: theme.spacing(2),
paddingRight: theme.spacing(0) paddingRight: theme.spacing(0),
}, },
wrapCell: { wrapCell: {
maxWidth: "200px", maxWidth: "200px",
whiteSpace: "normal", whiteSpace: "normal",
wordWrap: "break-word" wordWrap: "break-word",
}, },
twHeight: { twHeight: {
minHeight: 600 minHeight: 600,
}, },
minTableHeader: { minTableHeader: {
color: "#393939", color: "#393939",
"& tr": { "& tr": {
"& th": { "& th": {
fontWeight: "bold" fontWeight: "bold",
} },
} },
}, },
...linkStyles(theme.palette.info.main), ...linkStyles(theme.palette.info.main),
...actionsTray, ...actionsTray,
...searchField, ...searchField,
...containerForHeader(theme.spacing(4)) ...containerForHeader(theme.spacing(4)),
}); });
const Groups = ({ classes, setErrorSnackMessage }: IGroupsProps) => { const Groups = ({ classes, setErrorSnackMessage }: IGroupsProps) => {
@@ -158,7 +158,7 @@ const Groups = ({ classes, setErrorSnackMessage }: IGroupsProps) => {
const tableActions = [ const tableActions = [
{ type: "view", onClick: viewAction }, { type: "view", onClick: viewAction },
{ type: "delete", onClick: deleteAction } { type: "delete", onClick: deleteAction },
]; ];
return ( return (
@@ -202,7 +202,7 @@ const Groups = ({ classes, setErrorSnackMessage }: IGroupsProps) => {
<InputAdornment position="start"> <InputAdornment position="start">
<SearchIcon /> <SearchIcon />
</InputAdornment> </InputAdornment>
) ),
}} }}
onChange={(e) => { onChange={(e) => {
setFilter(e.target.value); setFilter(e.target.value);
@@ -313,7 +313,7 @@ const Groups = ({ classes, setErrorSnackMessage }: IGroupsProps) => {
}; };
const mapDispatchToProps = { const mapDispatchToProps = {
setErrorSnackMessage setErrorSnackMessage,
}; };
const connector = connect(null, mapDispatchToProps); const connector = connect(null, mapDispatchToProps);

View File

@@ -3,8 +3,15 @@ import PageHeader from "../Common/PageHeader/PageHeader";
import { Link, useParams } from "react-router-dom"; import { Link, useParams } from "react-router-dom";
import { Theme } from "@mui/material/styles"; import { Theme } from "@mui/material/styles";
import createStyles from "@mui/styles/createStyles"; import createStyles from "@mui/styles/createStyles";
import { actionsTray, containerForHeader, searchField } from "../Common/FormComponents/common/styleLibrary"; import {
import { setErrorSnackMessage, setModalErrorSnackMessage } from "../../../actions"; actionsTray,
containerForHeader,
searchField,
} from "../Common/FormComponents/common/styleLibrary";
import {
setErrorSnackMessage,
setModalErrorSnackMessage,
} from "../../../actions";
import { connect } from "react-redux"; import { connect } from "react-redux";
import withStyles from "@mui/styles/withStyles"; import withStyles from "@mui/styles/withStyles";
import { Button, Grid, IconButton, Tooltip } from "@mui/material"; import { Button, Grid, IconButton, Tooltip } from "@mui/material";
@@ -22,17 +29,16 @@ import AddGroupMember from "./AddGroupMember";
import { ErrorResponseHandler } from "../../../common/types"; import { ErrorResponseHandler } from "../../../common/types";
import DeleteGroup from "./DeleteGroup"; import DeleteGroup from "./DeleteGroup";
const styles = (theme: Theme) => const styles = (theme: Theme) =>
createStyles({ createStyles({
breadcrumLink: { breadcrumLink: {
textDecoration: "none", textDecoration: "none",
color: "black" color: "black",
}, },
...actionsTray, ...actionsTray,
...searchField, ...searchField,
actionsTray: { ...actionsTray.actionsTray }, actionsTray: { ...actionsTray.actionsTray },
...containerForHeader(theme.spacing(4)) ...containerForHeader(theme.spacing(4)),
}); });
interface IGroupDetailsProps { interface IGroupDetailsProps {
@@ -42,24 +48,22 @@ interface IGroupDetailsProps {
} }
type TabItemsProps = { type TabItemsProps = {
activeTab: number, activeTab: number;
onTabChange: (tab: number) => void onTabChange: (tab: number) => void;
} };
type DetailsHeaderProps = { type DetailsHeaderProps = {
classes: any classes: any;
} };
type GroupInfo = { type GroupInfo = {
members?: any[] members?: any[];
name?: string name?: string;
policy?: string policy?: string;
status?: string status?: string;
} };
const TabItems = ({ activeTab, onTabChange }: TabItemsProps) => { const TabItems = ({ activeTab, onTabChange }: TabItemsProps) => {
return ( return (
<List component="nav" dense={true}> <List component="nav" dense={true}>
<ListItem <ListItem
@@ -80,12 +84,10 @@ const TabItems = ({ activeTab, onTabChange }: TabItemsProps) => {
> >
<ListItemText primary="Policies" /> <ListItemText primary="Policies" />
</ListItem> </ListItem>
</List> </List>
); );
}; };
export const formatPolicy = (policy: string = ""): string[] => { export const formatPolicy = (policy: string = ""): string[] => {
if (policy.length <= 0) return []; if (policy.length <= 0) return [];
return policy.split(","); return policy.split(",");
@@ -95,7 +97,6 @@ export const getPoliciesAsString = (policies: string[]): string => {
return policies.join(", "); return policies.join(", ");
}; };
const GroupDetailsHeader = ({ classes }: DetailsHeaderProps) => { const GroupDetailsHeader = ({ classes }: DetailsHeaderProps) => {
return ( return (
<PageHeader <PageHeader
@@ -111,9 +112,7 @@ const GroupDetailsHeader = ({ classes }: DetailsHeaderProps) => {
); );
}; };
const GroupsDetails = ({ classes }: IGroupDetailsProps) => { const GroupsDetails = ({ classes }: IGroupDetailsProps) => {
const [currentTab, setCurrentTab] = useState<number>(0); const [currentTab, setCurrentTab] = useState<number>(0);
const [groupDetails, setGroupDetails] = useState<GroupInfo>({}); const [groupDetails, setGroupDetails] = useState<GroupInfo>({});
@@ -122,15 +121,9 @@ const GroupsDetails = ({ classes }: IGroupDetailsProps) => {
const [usersOpen, setUsersOpen] = useState<boolean>(false); const [usersOpen, setUsersOpen] = useState<boolean>(false);
const [deleteOpen, setDeleteOpen] = useState<boolean>(false); const [deleteOpen, setDeleteOpen] = useState<boolean>(false);
const { const { groupName = "" } = useParams<Record<string, string>>();
groupName = ""
} = useParams<Record<string, string>>();
const { const { members = [], policy = "", status: groupEnabled } = groupDetails;
members = [],
policy = "",
status: groupEnabled
} = groupDetails;
useEffect(() => { useEffect(() => {
if (groupName) { if (groupName) {
@@ -148,18 +141,18 @@ const GroupsDetails = ({ classes }: IGroupDetailsProps) => {
.invoke("GET", `/api/v1/group?name=${encodeURI(groupName)}`) .invoke("GET", `/api/v1/group?name=${encodeURI(groupName)}`)
.then((res: any) => { .then((res: any) => {
setGroupDetails(res); setGroupDetails(res);
}).catch(() => { })
setGroupDetails({}); .catch(() => {
}); setGroupDetails({});
}; });
}
function toggleGroupStatus(nextStatus: boolean) { function toggleGroupStatus(nextStatus: boolean) {
return api return api
.invoke("PUT", `/api/v1/group?name=${encodeURI(groupName)}`, { .invoke("PUT", `/api/v1/group?name=${encodeURI(groupName)}`, {
group: groupName, group: groupName,
members: members, members: members,
status: nextStatus ? "enabled" : "disabled" status: nextStatus ? "enabled" : "disabled",
}) })
.then((res) => { .then((res) => {
fetchGroupInfo(); fetchGroupInfo();
@@ -170,7 +163,6 @@ const GroupsDetails = ({ classes }: IGroupDetailsProps) => {
} }
return ( return (
<React.Fragment> <React.Fragment>
<GroupDetailsHeader classes={classes} /> <GroupDetailsHeader classes={classes} />
<Grid container className={classes.container}> <Grid container className={classes.container}>
@@ -183,7 +175,9 @@ const GroupsDetails = ({ classes }: IGroupDetailsProps) => {
} }
title={groupName} title={groupName}
subTitle={ subTitle={
<Fragment>Status: {isGroupEnabled ? "Enabled" : "Disabled"}</Fragment> <Fragment>
Status: {isGroupEnabled ? "Enabled" : "Disabled"}
</Fragment>
} }
actions={ actions={
<Fragment> <Fragment>
@@ -214,9 +208,12 @@ const GroupsDetails = ({ classes }: IGroupDetailsProps) => {
</Grid> </Grid>
<Grid item xs={2}> <Grid item xs={2}>
<TabItems activeTab={currentTab} onTabChange={(num) => { <TabItems
setCurrentTab(num); activeTab={currentTab}
}} /> onTabChange={(num) => {
setCurrentTab(num);
}}
/>
</Grid> </Grid>
<Grid item xs={10}> <Grid item xs={10}>
<Grid item xs={12}> <Grid item xs={12}>
@@ -270,8 +267,8 @@ const GroupsDetails = ({ classes }: IGroupDetailsProps) => {
type: "view", type: "view",
onClick: (policy) => { onClick: (policy) => {
history.push(`/policies/${policy}`); history.push(`/policies/${policy}`);
} },
} },
]} ]}
columns={[{ label: "Policy", elementKey: "" }]} columns={[{ label: "Policy", elementKey: "" }]}
isLoading={false} isLoading={false}
@@ -297,12 +294,10 @@ const GroupsDetails = ({ classes }: IGroupDetailsProps) => {
/> />
) : null} ) : null}
{usersOpen ? {usersOpen ? (
<AddGroupMember <AddGroupMember
selectedGroup={groupName} selectedGroup={groupName}
onSaveClick={() => { onSaveClick={() => {}}
}}
title={memberActionText} title={memberActionText}
groupStatus={groupEnabled} groupStatus={groupEnabled}
classes={classes} classes={classes}
@@ -311,7 +306,9 @@ const GroupsDetails = ({ classes }: IGroupDetailsProps) => {
onClose={() => { onClose={() => {
setUsersOpen(false); setUsersOpen(false);
fetchGroupInfo(); fetchGroupInfo();
}} /> : null} }}
/>
) : null}
{deleteOpen && ( {deleteOpen && (
<DeleteGroup <DeleteGroup
@@ -328,14 +325,12 @@ const GroupsDetails = ({ classes }: IGroupDetailsProps) => {
{/*Modals*/} {/*Modals*/}
</React.Fragment> </React.Fragment>
); );
}; };
const mapDispatchToProps = { const mapDispatchToProps = {
setErrorSnackMessage setErrorSnackMessage,
}; };
const connector = connect(null, mapDispatchToProps); const connector = connect(null, mapDispatchToProps);
export default withStyles(styles)(connector(GroupsDetails)); export default withStyles(styles)(connector(GroupsDetails));

View File

@@ -40,7 +40,15 @@ const LoginCallback: FC<RouteComponentProps> = ({ location }) => {
// store the jwt token // store the jwt token
storage.setItem("token", res.sessionId); storage.setItem("token", res.sessionId);
// We push to history the new URL. // 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) => { .catch((res: any) => {

View File

@@ -242,7 +242,15 @@ const Login = ({
if (loginStrategy.loginStrategy === loginStrategyType.form) { if (loginStrategy.loginStrategy === loginStrategyType.form) {
localStorage.setItem("userLoggedIn", encodeFileName(accessKey)); 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) => { .catch((err) => {
setLoginSending(false); setLoginSending(false);