release notes page

master
Tudor Stanciu 2020-05-14 15:29:32 +03:00
parent 3a7613e9ff
commit de4f0c5b4f
26 changed files with 245 additions and 82 deletions

View File

@ -15,6 +15,7 @@
"Menu": {
"Home": "Home",
"Sessions": "Sessions",
"ReleaseNotes": "Release notes",
"About": "About"
},
"General": {
@ -43,5 +44,9 @@
"PathOverwriteTooltip": "Option by which the base path of the application is automatically overwritten in all http text responses received from it."
}
}
},
"ReleaseNotes": {
"Title": "Release notes",
"Version": "Version"
}
}

View File

@ -6,6 +6,7 @@
"Menu": {
"Home": "Acasă",
"Sessions": "Sesiuni",
"ReleaseNotes": "Note lansare",
"About": "Despre"
},
"General": {
@ -34,5 +35,9 @@
"PathOverwriteTooltip": "Opțiune prin care calea de bază a aplicației este suprascrisă automat în toate răspunsurile de text http primite de la aceasta."
}
}
},
"ReleaseNotes": {
"Title": "Note lansare",
"Version": "Versiune"
}
}

View File

@ -7,6 +7,7 @@ import PageNotFound from "./PageNotFound";
import { ToastContainer } from "react-toastify";
import "react-toastify/dist/ReactToastify.css";
import SessionContainer from "../features/session/components/SessionContainer";
import ReleaseNotesContainer from "../features/releaseNotes/components/ReleaseNotesContainer";
function App() {
const contentStyle = {
@ -23,6 +24,7 @@ function App() {
<Route exact path="/" component={HomePage} />
<Route path="/about" component={AboutPage} />
<Route path="/sessions" component={SessionContainer} />
<Route path="/release-notes" component={ReleaseNotesContainer} />
<Route component={PageNotFound} />
</Switch>
<ToastContainer autoClose={3000} />

View File

@ -0,0 +1,11 @@
const styles = (theme) => ({
root: {
width: "100%"
},
heading: {
fontSize: theme.typography.pxToRem(15),
fontWeight: theme.typography.fontWeightRegular
}
});
export default styles;

View File

@ -5,15 +5,13 @@ import { bindActionCreators } from "redux";
import PropTypes from "prop-types";
import {
loadSystemDateTime,
loadSystemVersion,
loadReleaseNotes
loadSystemVersion
} from "../../features/system/actionCreators";
const HomePage = ({ actions }) => {
const testButton = () => {
actions.loadSystemDateTime();
actions.loadSystemVersion();
actions.loadReleaseNotes();
};
return (
@ -46,7 +44,7 @@ function mapStateToProps() {
function mapDispatchToProps(dispatch) {
return {
actions: bindActionCreators(
{ loadSystemDateTime, loadSystemVersion, loadReleaseNotes },
{ loadSystemDateTime, loadSystemVersion },
dispatch
)
};

View File

@ -17,6 +17,10 @@ const Navigation = () => {
{t("Menu.Sessions")}
</NavLink>
{" | "}
<NavLink to="/release-notes" activeStyle={activeStyle} style={style}>
{t("Menu.ReleaseNotes")}
</NavLink>
{" | "}
<NavLink to="/about" activeStyle={activeStyle} style={style}>
{t("Menu.About")}
</NavLink>

View File

@ -0,0 +1,18 @@
import * as types from "./actionTypes";
import api from "./api";
import { sendHttpRequest } from "../../redux/actions/httpActions";
export function loadReleaseNotes() {
return async function (dispatch, getState) {
try {
const notes = getState().releaseNotes;
if (notes && (notes.loading || notes.loaded)) return;
dispatch({ type: types.LOAD_RELEASE_NOTES_STARTED });
const data = await dispatch(sendHttpRequest(api.getReleaseNotes()));
dispatch({ type: types.LOAD_RELEASE_NOTES_SUCCESS, payload: data });
} catch (error) {
throw error;
}
};
}

View File

@ -0,0 +1,2 @@
export const LOAD_RELEASE_NOTES_STARTED = "LOAD_RELEASE_NOTES_STARTED";
export const LOAD_RELEASE_NOTES_SUCCESS = "LOAD_RELEASE_NOTES_SUCCESS";

View File

@ -0,0 +1,8 @@
import { get } from "../../api/axiosApi";
const baseUrl = process.env.REVERSE_PROXY_API_URL + "/system";
const getReleaseNotes = () => get(`${baseUrl}/release-notes`);
export default {
getReleaseNotes
};

View File

@ -0,0 +1,36 @@
import React, { useEffect } from "react";
import { connect } from "react-redux";
import { bindActionCreators } from "redux";
import PropTypes from "prop-types";
import { loadReleaseNotes } from "../actionCreators";
import ReleaseNotesListComponent from "./ReleaseNotesListComponent";
const ReleaseNotesContainer = ({ actions, releaseNotes }) => {
useEffect(() => {
actions.loadReleaseNotes();
}, []);
return <ReleaseNotesListComponent releaseNotes={releaseNotes} />;
};
ReleaseNotesContainer.propTypes = {
actions: PropTypes.object.isRequired,
releaseNotes: PropTypes.array.isRequired
};
function mapStateToProps(state) {
return {
releaseNotes: state.releaseNotes
};
}
function mapDispatchToProps(dispatch) {
return {
actions: bindActionCreators({ loadReleaseNotes }, dispatch)
};
}
export default connect(
mapStateToProps,
mapDispatchToProps
)(ReleaseNotesContainer);

View File

@ -0,0 +1,50 @@
import React from "react";
import { makeStyles } from "@material-ui/core/styles";
import ExpansionPanel from "@material-ui/core/ExpansionPanel";
import ExpansionPanelSummary from "@material-ui/core/ExpansionPanelSummary";
import ExpansionPanelDetails from "@material-ui/core/ExpansionPanelDetails";
import ExpandMoreIcon from "@material-ui/icons/ExpandMore";
import PropTypes from "prop-types";
import Spinner from "../../../components/common/Spinner";
import { useTranslation } from "react-i18next";
import ReleaseNotesSummary from "./ReleaseNotesSummary";
import styles from "../../../components/common/styles/divStyles";
const useStyles = makeStyles(styles);
const ReleaseNotesListComponent = ({ releaseNotes }) => {
const classes = useStyles();
const { t } = useTranslation();
return (
<div className={classes.root}>
<h2>{t("ReleaseNotes.Title")}</h2>
{releaseNotes.loading ? (
<Spinner />
) : (
releaseNotes.loaded &&
releaseNotes.map((note) => {
return (
<ExpansionPanel key={note.version}>
<ExpansionPanelSummary
expandIcon={<ExpandMoreIcon />}
id={`panel-${note.version}-header`}
>
<ReleaseNotesSummary releaseNote={note} />
</ExpansionPanelSummary>
<ExpansionPanelDetails>
<div>TO DO</div>
</ExpansionPanelDetails>
</ExpansionPanel>
);
})
)}
</div>
);
};
ReleaseNotesListComponent.propTypes = {
releaseNotes: PropTypes.array.isRequired
};
export default ReleaseNotesListComponent;

View File

@ -0,0 +1,33 @@
import React from "react";
import PropTypes from "prop-types";
import { Grid } from "@material-ui/core";
import { makeStyles } from "@material-ui/core/styles";
import { useTranslation } from "react-i18next";
import styles from "../../../components/common/styles/gridStyles";
const useStyles = makeStyles(styles);
const ReleaseNotesSummary = ({ releaseNote }) => {
const classes = useStyles();
const { t } = useTranslation();
return (
<Grid container className={classes.miniContainer}>
<Grid item xs={12} sm={5} md={5}>
{`${t("ReleaseNotes.Version")}: `}
<span className={classes.value}>{releaseNote.version}</span>
</Grid>
<Grid item xs={12} sm={5} md={5}>
{`${t("ReleaseNotes.Version")}: `}
<span className={classes.value}>{releaseNote.version}</span>
</Grid>
</Grid>
);
};
ReleaseNotesSummary.propTypes = {
releaseNote: PropTypes.object.isRequired
};
export default ReleaseNotesSummary;

View File

@ -0,0 +1,18 @@
import * as types from "./actionTypes";
import initialState from "../../redux/reducers/initialState";
export default function releaseNotesReducer(
state = initialState.releaseNotes,
action
) {
switch (action.type) {
case types.LOAD_RELEASE_NOTES_STARTED:
return Object.assign([], { loading: true, loaded: false });
case types.LOAD_RELEASE_NOTES_SUCCESS:
return Object.assign(action.payload, { loading: false, loaded: true });
default:
return state;
}
}

View File

@ -9,7 +9,7 @@ import TableRow from "@material-ui/core/TableRow";
import Paper from "@material-ui/core/Paper";
import Tooltip from "@material-ui/core/Tooltip";
import { useTranslation } from "react-i18next";
import styles from "../styles/tableStyles";
import styles from "../../../components/common/styles/tableStyles";
import {
StyledTableCell,
StyledTableRow

View File

@ -14,7 +14,7 @@ import Tooltip from "@material-ui/core/Tooltip";
import SessionForwardsHeaderComponent from "./SessionForwardsHeaderComponent";
import { Grid } from "@material-ui/core";
import { useTranslation } from "react-i18next";
import styles from "../styles/tableStyles";
import styles from "../../../components/common/styles/tableStyles";
import {
StyledTableCell,
StyledTableRow

View File

@ -3,7 +3,7 @@ import PropTypes from "prop-types";
import { Grid } from "@material-ui/core";
import { makeStyles } from "@material-ui/core/styles";
import { useTranslation } from "react-i18next";
import styles from "../styles/gridStyles";
import styles from "../../../components/common/styles/gridStyles";
const useStyles = makeStyles(styles);

View File

@ -9,16 +9,9 @@ import SessionSummary from "./SessionSummary";
import SessionForwardsComponent from "./SessionForwardsComponent";
import Spinner from "../../../components/common/Spinner";
import { useTranslation } from "react-i18next";
import styles from "../../../components/common/styles/divStyles";
const useStyles = makeStyles((theme) => ({
root: {
width: "100%"
},
heading: {
fontSize: theme.typography.pxToRem(15),
fontWeight: theme.typography.fontWeightRegular
}
}));
const useStyles = makeStyles(styles);
const SessionListComponent = ({
sessions,

View File

@ -4,7 +4,7 @@ import { Grid } from "@material-ui/core";
import { makeStyles } from "@material-ui/core/styles";
import ActiveIcon from "../../../components/common/ActiveIcon";
import { useTranslation } from "react-i18next";
import styles from "../styles/gridStyles";
import styles from "../../../components/common/styles/gridStyles";
const useStyles = makeStyles(styles);
@ -13,7 +13,6 @@ const SessionSummary = ({ session }) => {
const { t } = useTranslation();
return (
<>
<Grid container className={classes.miniContainer}>
<Grid item xs={12} sm={5} md={5}>
{`${t("Session.Session")}: `}
@ -56,7 +55,6 @@ const SessionSummary = ({ session }) => {
</span>
</Grid>
</Grid>
</>
);
};

View File

@ -23,14 +23,3 @@ export function loadSystemVersion() {
}
};
}
export function loadReleaseNotes() {
return async function (dispatch) {
try {
const data = await dispatch(sendHttpRequest(api.getReleaseNotes()));
dispatch({ type: types.LOAD_RELEASE_NOTES_SUCCESS, payload: data });
} catch (error) {
throw error;
}
};
}

View File

@ -1,3 +1,2 @@
export const LOAD_SYSTEM_DATETIME_SUCCESS = "LOAD_SYSTEM_DATETIME_SUCCESS";
export const LOAD_SYSTEM_VERSION_SUCCESS = "LOAD_SYSTEM_VERSION_SUCCESS";
export const LOAD_RELEASE_NOTES_SUCCESS = "LOAD_RELEASE_NOTES_SUCCESS";

View File

@ -3,10 +3,8 @@ const baseUrl = process.env.REVERSE_PROXY_API_URL + "/system";
const getSystemDateTime = () => get(`${baseUrl}/datetime`);
const getSystemVersion = () => get(`${baseUrl}/version`);
const getReleaseNotes = () => get(`${baseUrl}/release-notes`);
export default {
getSystemDateTime,
getSystemVersion,
getReleaseNotes
getSystemVersion
};

View File

@ -14,13 +14,6 @@ export default function systemReducer(state = initialState.system, action) {
...state,
...action.payload
};
case types.LOAD_RELEASE_NOTES_SUCCESS:
return {
...state,
releaseNotes: action.payload
};
default:
return state;
}

View File

@ -5,11 +5,13 @@ import {
sessionsReducer,
forwardsReducer
} from "../../features/session/reducers";
import releaseNotesReducer from "../../features/releaseNotes/reducer";
const rootReducer = combineReducers({
system: systemReducer,
sessions: sessionsReducer,
forwards: forwardsReducer,
releaseNotes: releaseNotesReducer,
ajaxCallsInProgress: ajaxStatusReducer
});

View File

@ -2,5 +2,6 @@ export default {
system: {},
sessions: Object.assign([], { loading: false, loaded: false }),
forwards: {},
releaseNotes: Object.assign([], { loading: false, loaded: false }),
ajaxCallsInProgress: 0
};