ForwardOptionsContainer
parent
b9336e1cc6
commit
7b7578173f
|
@ -1,8 +1,13 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import PropTypes from "prop-types";
|
import PropTypes from "prop-types";
|
||||||
import { CheckCircleOutlineRounded, RemoveRounded } from "@material-ui/icons";
|
import { CheckCircleOutlineRounded, RemoveRounded } from "@material-ui/icons";
|
||||||
|
import { LinearProgress } from "@material-ui/core";
|
||||||
|
|
||||||
|
const ActiveIcon = ({ active, loading }) => {
|
||||||
|
if (loading && loading === true) {
|
||||||
|
return <LinearProgress />;
|
||||||
|
}
|
||||||
|
|
||||||
const ActiveIcon = ({ active }) => {
|
|
||||||
return active && active === true ? (
|
return active && active === true ? (
|
||||||
<CheckCircleOutlineRounded color="primary" />
|
<CheckCircleOutlineRounded color="primary" />
|
||||||
) : (
|
) : (
|
||||||
|
@ -11,7 +16,8 @@ const ActiveIcon = ({ active }) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
ActiveIcon.propTypes = {
|
ActiveIcon.propTypes = {
|
||||||
active: PropTypes.bool
|
active: PropTypes.bool,
|
||||||
|
loading: PropTypes.bool
|
||||||
};
|
};
|
||||||
|
|
||||||
export default ActiveIcon;
|
export default ActiveIcon;
|
||||||
|
|
|
@ -11,7 +11,7 @@ import ForwardOptionsDialog from "../../session/components/ForwardOptionsDialog"
|
||||||
const ActiveSessionContainer = ({ actions, session, forwards, domain }) => {
|
const ActiveSessionContainer = ({ actions, session, forwards, domain }) => {
|
||||||
const [expanded, setExpanded] = useState(false);
|
const [expanded, setExpanded] = useState(false);
|
||||||
const [optionsDialogOpen, setOptionsDialogOpen] = useState(false);
|
const [optionsDialogOpen, setOptionsDialogOpen] = useState(false);
|
||||||
const [forwardOptions, setForwardOptions] = useState(null);
|
const [focusedForward, setFocusedForward] = useState(null);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
actions.loadActiveSession();
|
actions.loadActiveSession();
|
||||||
|
@ -23,18 +23,20 @@ const ActiveSessionContainer = ({ actions, session, forwards, domain }) => {
|
||||||
if (expand) actions.loadSessionForwards(session.sessionId);
|
if (expand) actions.loadSessionForwards(session.sessionId);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleOptionsDialogOpen = (options) => () => {
|
const handleOptionsDialogOpen = forward => () => {
|
||||||
setForwardOptions(options);
|
setFocusedForward(forward);
|
||||||
setOptionsDialogOpen(true);
|
setOptionsDialogOpen(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleOptionsDialogClose = () => {
|
const handleOptionsDialogClose = () => {
|
||||||
setOptionsDialogOpen(false);
|
setOptionsDialogOpen(false);
|
||||||
setForwardOptions(null);
|
setFocusedForward(null);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleForwardClick = (forward) => (event) => {
|
const handleForwardClick = forward => event => {
|
||||||
const url = `${domain.scheme}://${domain.name}${forward.from}${forward.suffix || ""}`;
|
const url = `${domain.scheme}://${domain.name}${
|
||||||
|
forward.from
|
||||||
|
}${forward.suffix || ""}`;
|
||||||
window.open(url, "_blank");
|
window.open(url, "_blank");
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
};
|
};
|
||||||
|
@ -52,7 +54,7 @@ const ActiveSessionContainer = ({ actions, session, forwards, domain }) => {
|
||||||
<ForwardOptionsDialog
|
<ForwardOptionsDialog
|
||||||
open={optionsDialogOpen}
|
open={optionsDialogOpen}
|
||||||
handleClose={handleOptionsDialogClose}
|
handleClose={handleOptionsDialogClose}
|
||||||
options={forwardOptions}
|
forward={focusedForward}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
|
@ -34,3 +34,24 @@ export function loadSessionForwards(sessionId) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function loadForwardOptions(optionId) {
|
||||||
|
return async function(dispatch, getState) {
|
||||||
|
try {
|
||||||
|
const options = getState().options[optionId];
|
||||||
|
if (options && (options.loading || options.loaded)) return;
|
||||||
|
|
||||||
|
dispatch({ type: types.LOAD_FORWARD_OPTIONS_STARTED, id: optionId });
|
||||||
|
const data = await dispatch(
|
||||||
|
sendHttpRequest(api.getForwardOptions(optionId))
|
||||||
|
);
|
||||||
|
dispatch({
|
||||||
|
type: types.LOAD_FORWARD_OPTIONS_SUCCESS,
|
||||||
|
payload: data,
|
||||||
|
id: optionId
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
|
@ -3,3 +3,6 @@ export const LOAD_SERVER_SESSIONS_SUCCESS = "LOAD_SERVER_SESSIONS_SUCCESS";
|
||||||
|
|
||||||
export const LOAD_SESSION_FORWARDS_STARTED = "LOAD_SESSION_FORWARDS_STARTED";
|
export const LOAD_SESSION_FORWARDS_STARTED = "LOAD_SESSION_FORWARDS_STARTED";
|
||||||
export const LOAD_SESSION_FORWARDS_SUCCESS = "LOAD_SESSION_FORWARDS_SUCCESS";
|
export const LOAD_SESSION_FORWARDS_SUCCESS = "LOAD_SESSION_FORWARDS_SUCCESS";
|
||||||
|
|
||||||
|
export const LOAD_FORWARD_OPTIONS_STARTED = "LOAD_FORWARD_OPTIONS_STARTED";
|
||||||
|
export const LOAD_FORWARD_OPTIONS_SUCCESS = "LOAD_FORWARD_OPTIONS_SUCCESS";
|
||||||
|
|
|
@ -2,10 +2,14 @@ import { get } from "../../api/axiosApi";
|
||||||
const baseUrl = `${process.env.REVERSE_PROXY_API_URL}/server`;
|
const baseUrl = `${process.env.REVERSE_PROXY_API_URL}/server`;
|
||||||
|
|
||||||
const getServerSessions = () => get(`${baseUrl}/sessions`);
|
const getServerSessions = () => get(`${baseUrl}/sessions`);
|
||||||
const getSessionForwards = (sessionId) =>
|
const getSessionForwards = sessionId =>
|
||||||
get(`${baseUrl}/session-forwards/${sessionId}`);
|
get(`${baseUrl}/session-forwards/${sessionId}`);
|
||||||
|
|
||||||
|
const getForwardOptions = optionId =>
|
||||||
|
get(`${baseUrl}/forward-options/${optionId}`);
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
getServerSessions,
|
getServerSessions,
|
||||||
getSessionForwards
|
getSessionForwards,
|
||||||
|
getForwardOptions
|
||||||
};
|
};
|
||||||
|
|
|
@ -21,10 +21,12 @@ import Typography from "@material-ui/core/Typography";
|
||||||
|
|
||||||
const useStyles = makeStyles(styles);
|
const useStyles = makeStyles(styles);
|
||||||
|
|
||||||
const ForwardOptionsComponent = ({ options }) => {
|
const ForwardOptionsComponent = ({ title, options }) => {
|
||||||
const classes = useStyles();
|
const classes = useStyles();
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
const loading = !options || options.loading;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<TableContainer component={Paper}>
|
<TableContainer component={Paper}>
|
||||||
|
@ -53,7 +55,7 @@ const ForwardOptionsComponent = ({ options }) => {
|
||||||
</StyledTableCell>
|
</StyledTableCell>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
<StyledTableCell align="center">
|
<StyledTableCell align="center">
|
||||||
<ActiveIcon active={options.trailingSlash} />
|
<ActiveIcon active={options.trailingSlash} loading={loading} />
|
||||||
</StyledTableCell>
|
</StyledTableCell>
|
||||||
</StyledTableRow>
|
</StyledTableRow>
|
||||||
<StyledTableRow>
|
<StyledTableRow>
|
||||||
|
@ -65,20 +67,21 @@ const ForwardOptionsComponent = ({ options }) => {
|
||||||
</StyledTableCell>
|
</StyledTableCell>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
<StyledTableCell align="center">
|
<StyledTableCell align="center">
|
||||||
<ActiveIcon active={options.pathOverwrite} />
|
<ActiveIcon active={options.pathOverwrite} loading={loading} />
|
||||||
</StyledTableCell>
|
</StyledTableCell>
|
||||||
</StyledTableRow>
|
</StyledTableRow>
|
||||||
</TableBody>
|
</TableBody>
|
||||||
</Table>
|
</Table>
|
||||||
</TableContainer>
|
</TableContainer>
|
||||||
<Typography variant="caption" display="block" gutterBottom>
|
<Typography variant="caption" display="block" gutterBottom>
|
||||||
{options.title}
|
{title}
|
||||||
</Typography>
|
</Typography>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
ForwardOptionsComponent.propTypes = {
|
ForwardOptionsComponent.propTypes = {
|
||||||
|
title: PropTypes.string.isRequired,
|
||||||
options: PropTypes.object.isRequired
|
options: PropTypes.object.isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
import React, { useEffect } from "react";
|
||||||
|
import { connect } from "react-redux";
|
||||||
|
import { bindActionCreators } from "redux";
|
||||||
|
import PropTypes from "prop-types";
|
||||||
|
import { loadForwardOptions } from "../actionCreators";
|
||||||
|
import ForwardOptionsComponent from "./ForwardOptionsComponent";
|
||||||
|
|
||||||
|
const ForwardOptionsContainer = ({ actions, forward, options }) => {
|
||||||
|
useEffect(() => {
|
||||||
|
actions.loadForwardOptions(forward.optionId);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const forwardOptions = options[forward.optionId];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{forwardOptions && (
|
||||||
|
<ForwardOptionsComponent
|
||||||
|
title={`${forward.from} >>> ${forward.to}`}
|
||||||
|
options={forwardOptions}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
ForwardOptionsContainer.propTypes = {
|
||||||
|
actions: PropTypes.object.isRequired,
|
||||||
|
forward: PropTypes.object.isRequired,
|
||||||
|
options: PropTypes.object.isRequired
|
||||||
|
};
|
||||||
|
|
||||||
|
function mapStateToProps(state) {
|
||||||
|
return {
|
||||||
|
options: state.options
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function mapDispatchToProps(dispatch) {
|
||||||
|
return {
|
||||||
|
actions: bindActionCreators({ loadForwardOptions }, dispatch)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export default connect(
|
||||||
|
mapStateToProps,
|
||||||
|
mapDispatchToProps
|
||||||
|
)(ForwardOptionsContainer);
|
|
@ -8,9 +8,9 @@ import {
|
||||||
DialogTitle
|
DialogTitle
|
||||||
} from "@material-ui/core";
|
} from "@material-ui/core";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import ForwardOptionsComponent from "./ForwardOptionsComponent";
|
import ForwardOptionsContainer from "./ForwardOptionsContainer";
|
||||||
|
|
||||||
const ForwardOptionsDialog = ({ open, handleClose, options }) => {
|
const ForwardOptionsDialog = ({ open, handleClose, forward }) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -25,7 +25,7 @@ const ForwardOptionsDialog = ({ open, handleClose, options }) => {
|
||||||
{t("Session.Forwards.Options.Title")}
|
{t("Session.Forwards.Options.Title")}
|
||||||
</DialogTitle>
|
</DialogTitle>
|
||||||
<DialogContent id="optopns-dialog-content">
|
<DialogContent id="optopns-dialog-content">
|
||||||
{options ? <ForwardOptionsComponent options={options} /> : ""}
|
{forward ? <ForwardOptionsContainer forward={forward} /> : "N/A"}
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
<DialogActions>
|
<DialogActions>
|
||||||
<Button onClick={handleClose} color="primary">
|
<Button onClick={handleClose} color="primary">
|
||||||
|
@ -40,7 +40,7 @@ const ForwardOptionsDialog = ({ open, handleClose, options }) => {
|
||||||
ForwardOptionsDialog.propTypes = {
|
ForwardOptionsDialog.propTypes = {
|
||||||
open: PropTypes.bool.isRequired,
|
open: PropTypes.bool.isRequired,
|
||||||
handleClose: PropTypes.func.isRequired,
|
handleClose: PropTypes.func.isRequired,
|
||||||
options: PropTypes.object
|
forward: PropTypes.object
|
||||||
};
|
};
|
||||||
|
|
||||||
export default ForwardOptionsDialog;
|
export default ForwardOptionsDialog;
|
||||||
|
|
|
@ -8,24 +8,24 @@ import { loadServerSessions, loadSessionForwards } from "../actionCreators";
|
||||||
|
|
||||||
const SessionContainer = ({ actions, sessions, forwards }) => {
|
const SessionContainer = ({ actions, sessions, forwards }) => {
|
||||||
const [optionsDialogOpen, setOptionsDialogOpen] = useState(false);
|
const [optionsDialogOpen, setOptionsDialogOpen] = useState(false);
|
||||||
const [forwardOptions, setForwardOptions] = useState(null);
|
const [focusedForward, setFocusedForward] = useState(null);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
actions.loadServerSessions();
|
actions.loadServerSessions();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const handleToggle = (sessionId) => (_, expanded) => {
|
const handleToggle = sessionId => (_, expanded) => {
|
||||||
if (expanded) actions.loadSessionForwards(sessionId);
|
if (expanded) actions.loadSessionForwards(sessionId);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleOptionsDialogOpen = (options) => () => {
|
const handleOptionsDialogOpen = forward => () => {
|
||||||
setForwardOptions(options);
|
setFocusedForward(forward);
|
||||||
setOptionsDialogOpen(true);
|
setOptionsDialogOpen(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleOptionsDialogClose = () => {
|
const handleOptionsDialogClose = () => {
|
||||||
setOptionsDialogOpen(false);
|
setOptionsDialogOpen(false);
|
||||||
setForwardOptions(null);
|
setFocusedForward(null);
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -39,7 +39,7 @@ const SessionContainer = ({ actions, sessions, forwards }) => {
|
||||||
<ForwardOptionsDialog
|
<ForwardOptionsDialog
|
||||||
open={optionsDialogOpen}
|
open={optionsDialogOpen}
|
||||||
handleClose={handleOptionsDialogClose}
|
handleClose={handleOptionsDialogClose}
|
||||||
options={forwardOptions}
|
forward={focusedForward}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
|
@ -67,7 +67,7 @@ const SessionForwardsComponent = ({
|
||||||
</TableRow>
|
</TableRow>
|
||||||
</TableHead>
|
</TableHead>
|
||||||
<TableBody>
|
<TableBody>
|
||||||
{forwards.map((row) => (
|
{forwards.map(row => (
|
||||||
<StyledTableRow key={row.forwardId}>
|
<StyledTableRow key={row.forwardId}>
|
||||||
<StyledTableCell component="th" scope="row">
|
<StyledTableCell component="th" scope="row">
|
||||||
{forwards.indexOf(row) + 1}
|
{forwards.indexOf(row) + 1}
|
||||||
|
@ -83,15 +83,12 @@ const SessionForwardsComponent = ({
|
||||||
</StyledTableCell>
|
</StyledTableCell>
|
||||||
<StyledTableCell>{row.to}</StyledTableCell>
|
<StyledTableCell>{row.to}</StyledTableCell>
|
||||||
<StyledTableCell align="right">
|
<StyledTableCell align="right">
|
||||||
{row.options ? (
|
{row.optionId ? (
|
||||||
<Tooltip title={t("Session.Forwards.Options.Title")}>
|
<Tooltip title={t("Session.Forwards.Options.Title")}>
|
||||||
<IconButton
|
<IconButton
|
||||||
aria-label="options"
|
aria-label="options"
|
||||||
size="small"
|
size="small"
|
||||||
onClick={openOptionsDialog({
|
onClick={openOptionsDialog(row)}
|
||||||
...row.options,
|
|
||||||
title: `${row.from} >>> ${row.to}`
|
|
||||||
})}
|
|
||||||
>
|
>
|
||||||
<DonutLargeRoundedIcon color="primary" />
|
<DonutLargeRoundedIcon color="primary" />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
|
|
|
@ -35,3 +35,26 @@ export function forwardsReducer(state = initialState.forwards, action) {
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function optionsReducer(state = initialState.options, action) {
|
||||||
|
switch (action.type) {
|
||||||
|
case types.LOAD_FORWARD_OPTIONS_STARTED:
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
[action.id]: { loading: true, loaded: false }
|
||||||
|
};
|
||||||
|
|
||||||
|
case types.LOAD_FORWARD_OPTIONS_SUCCESS:
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
[action.id]: {
|
||||||
|
...action.payload,
|
||||||
|
loading: false,
|
||||||
|
loaded: true
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
default:
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -3,7 +3,8 @@ import ajaxStatusReducer from "./ajaxStatusReducer";
|
||||||
import serverReducer from "../../features/server/reducer";
|
import serverReducer from "../../features/server/reducer";
|
||||||
import {
|
import {
|
||||||
sessionsReducer,
|
sessionsReducer,
|
||||||
forwardsReducer
|
forwardsReducer,
|
||||||
|
optionsReducer
|
||||||
} from "../../features/session/reducers";
|
} from "../../features/session/reducers";
|
||||||
import releaseNotesReducer from "../../features/releaseNotes/reducer";
|
import releaseNotesReducer from "../../features/releaseNotes/reducer";
|
||||||
import frontendSessionReducer from "../../features/frontendSession/reducer";
|
import frontendSessionReducer from "../../features/frontendSession/reducer";
|
||||||
|
@ -16,6 +17,7 @@ const rootReducer = combineReducers({
|
||||||
server: serverReducer,
|
server: serverReducer,
|
||||||
sessions: sessionsReducer,
|
sessions: sessionsReducer,
|
||||||
forwards: forwardsReducer,
|
forwards: forwardsReducer,
|
||||||
|
options: optionsReducer,
|
||||||
releaseNotes: releaseNotesReducer,
|
releaseNotes: releaseNotesReducer,
|
||||||
charts: chartsReducer,
|
charts: chartsReducer,
|
||||||
snackbar: snackbarReducer,
|
snackbar: snackbarReducer,
|
||||||
|
|
|
@ -6,6 +6,7 @@ export default {
|
||||||
},
|
},
|
||||||
sessions: Object.assign([], { loading: false, loaded: false }),
|
sessions: Object.assign([], { loading: false, loaded: false }),
|
||||||
forwards: {},
|
forwards: {},
|
||||||
|
options: {},
|
||||||
releaseNotes: Object.assign([], { loading: false, loaded: false }),
|
releaseNotes: Object.assign([], { loading: false, loaded: false }),
|
||||||
charts: {
|
charts: {
|
||||||
server: {
|
server: {
|
||||||
|
|
Loading…
Reference in New Issue