From e31d7962a506b6f72cdd06a3cebaa109ad6630eb Mon Sep 17 00:00:00 2001 From: Jake Mensch Date: Sun, 19 Apr 2020 14:57:41 -0700 Subject: [PATCH 1/2] displaying version and github shas in footer --- .github/workflows/Continuous_Delivery.yml | 1 + src/App.jsx | 21 +++++++-- src/components/common/HoverOverInfo.jsx | 37 +++++++++++----- src/components/main/footer/Footer.jsx | 53 +++++++++++++++++------ src/redux/reducers/metadata.js | 47 ++++++++++++++++++++ src/redux/rootReducer.js | 2 + src/redux/rootSaga.js | 2 + src/redux/sagas/metadata.js | 26 +++++++++++ src/styles/main/_footer.scss | 27 +++++++++--- 9 files changed, 181 insertions(+), 35 deletions(-) create mode 100644 src/redux/reducers/metadata.js create mode 100644 src/redux/sagas/metadata.js diff --git a/.github/workflows/Continuous_Delivery.yml b/.github/workflows/Continuous_Delivery.yml index 1482c80d0..f08161230 100644 --- a/.github/workflows/Continuous_Delivery.yml +++ b/.github/workflows/Continuous_Delivery.yml @@ -32,6 +32,7 @@ jobs: echo REACT_APP_MAPBOX_TOKEN=${{ secrets.MAPBOX_TOKEN }} > .env echo DB_URL=${{ secrets.DB_URL }} >> .env echo BASE_URL=${{ secrets.BASE_URL }} >> .env + echo GITHUB_SHA=${{ github.sha }} >> .env - name: Build project run: npm run build - name: Run Tests diff --git a/src/App.jsx b/src/App.jsx index 0b257e74b..f4b613588 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,7 +1,10 @@ import React, { useEffect } from 'react'; +import PropTypes from 'proptypes'; import { connect } from 'react-redux'; import { HashRouter as Router } from 'react-router-dom'; +import { getMetadataRequest } from '@reducers/metadata'; + import Routes from './Routes'; import Header from './components/main/header/Header'; import Footer from './components/main/footer/Footer'; @@ -9,10 +12,12 @@ import { SnapshotRenderer } from './components/export/SnapshotService'; const basename = process.env.NODE_ENV === 'development' ? '/' : process.env.BASE_URL || '/'; -const App = () => { +const App = ({ + getMetadata, +}) => { useEffect(() => { - // fetch data on load?? - }, []); + getMetadata(); + }); return ( @@ -24,4 +29,12 @@ const App = () => { ); }; -export default connect(null, null)(App); +const mapDispatchToProps = dispatch => ({ + getMetadata: () => dispatch(getMetadataRequest()), +}); + +export default connect(null, mapDispatchToProps)(App); + +App.propTypes = { + getMetadata: PropTypes.func.isRequired, +}; diff --git a/src/components/common/HoverOverInfo.jsx b/src/components/common/HoverOverInfo.jsx index c8591694a..0375e290c 100644 --- a/src/components/common/HoverOverInfo.jsx +++ b/src/components/common/HoverOverInfo.jsx @@ -23,16 +23,26 @@ const HoverOverInfo = ({ { showTooltip && (
-
- - { title } -
- { text } + { title && ( +
+ + { title } +
+ )} + { + text instanceof Array + ? ( + text.map((line, idx) => ( +
{ line }
+ )) + ) + : text + }
)} @@ -44,9 +54,12 @@ export default HoverOverInfo; HoverOverInfo.propTypes = { title: PropTypes.string, - text: PropTypes.string, + text: PropTypes.oneOfType([ + PropTypes.string, + PropTypes.arrayOf(PropTypes.string), + ]), position: PropTypes.oneOf(['top', 'bottom', 'left', 'right']), - children: PropTypes.element, + children: PropTypes.node, }; HoverOverInfo.defaultProps = { diff --git a/src/components/main/footer/Footer.jsx b/src/components/main/footer/Footer.jsx index 46136fceb..c70033c1f 100644 --- a/src/components/main/footer/Footer.jsx +++ b/src/components/main/footer/Footer.jsx @@ -3,35 +3,60 @@ import { connect } from 'react-redux'; import { Switch, Route } from 'react-router-dom'; import propTypes from 'proptypes'; import moment from 'moment'; +import HoverOverInfo from '@components/common/HoverOverInfo'; import StaticFooter from './StaticFooter'; const Footer = ({ lastUpdated, -}) => ( -
- - - -

- Data Updated Through: -   - {lastUpdated && moment(1000 * lastUpdated).format('MMMM Do YYYY, h:mm:ss a')} -

-
-
-
-); + version, + backendSha, +}) => { + const frontendSha = process.env.GITHUB_SHA || 'DEVELOPMENT'; + return ( +
+ + + + + Data Updated Through: +   + {lastUpdated && moment(1000 * lastUpdated).format('MMMM Do YYYY, h:mm:ss a')} + + { version && backendSha && ( + + + Version { version } + + + )} + + +
+ ); +}; const mapStateToProps = state => ({ lastUpdated: state.data.lastUpdated, + version: state.metadata.version, + backendSha: state.metadata.gitSha, }); Footer.propTypes = { lastUpdated: propTypes.number, + version: propTypes.string, + backendSha: propTypes.string, }; Footer.defaultProps = { lastUpdated: undefined, + version: undefined, + backendSha: undefined, }; export default connect(mapStateToProps, null)(Footer); diff --git a/src/redux/reducers/metadata.js b/src/redux/reducers/metadata.js new file mode 100644 index 000000000..292df2a69 --- /dev/null +++ b/src/redux/reducers/metadata.js @@ -0,0 +1,47 @@ +export const types = { + GET_METADATA_REQUEST: 'GET_METADATA_REQUEST', + GET_METADATA_SUCCESS: 'GET_METADATA_SUCCESS', + GET_METADATA_FAILURE: 'GET_METADATA_FAILURE', +}; + +export const getMetadataRequest = () => ({ + type: types.GET_METADATA_REQUEST, +}); + +export const getMetadataSuccess = response => ({ + type: types.GET_METADATA_SUCCESS, + payload: response, +}); + +export const getMetadataFailure = error => ({ + type: types.GET_METADATA_FAILURE, + payload: error, +}); + +const initialState = {}; + +export default (state = initialState, action) => { + switch (action.type) { + case types.GET_METADATA_SUCCESS: + return { + ...action.payload, + }; + case types.GET_METADATA_FAILURE: { + const { + response: { status }, + message, + } = action.payload; + + return { + ...state, + error: { + code: status, + message, + error: action.payload, + }, + }; + } + default: + return state; + } +}; diff --git a/src/redux/rootReducer.js b/src/redux/rootReducer.js index 616a845ff..fa6f38701 100644 --- a/src/redux/rootReducer.js +++ b/src/redux/rootReducer.js @@ -1,4 +1,5 @@ import { combineReducers } from 'redux'; +import metadata from './reducers/metadata'; import data from './reducers/data'; import filters from './reducers/filters'; import ui from './reducers/ui'; @@ -6,6 +7,7 @@ import comparisonData from './reducers/comparisonData'; import comparisonFilters from './reducers/comparisonFilters'; export default combineReducers({ + metadata, data, filters, ui, diff --git a/src/redux/rootSaga.js b/src/redux/rootSaga.js index 7034b4a30..17bb6b993 100644 --- a/src/redux/rootSaga.js +++ b/src/redux/rootSaga.js @@ -1,11 +1,13 @@ import { all } from 'redux-saga/effects'; +import metadata from './sagas/metadata'; import data from './sagas/data'; import comparisonData from './sagas/comparisonData'; export default function* rootSaga() { yield all([ + metadata(), data(), comparisonData(), ]); diff --git a/src/redux/sagas/metadata.js b/src/redux/sagas/metadata.js new file mode 100644 index 000000000..772faea9b --- /dev/null +++ b/src/redux/sagas/metadata.js @@ -0,0 +1,26 @@ +import axios from 'axios'; +import { + takeLatest, + call, + put, +} from 'redux-saga/effects'; + +import { + types, + getMetadataSuccess, + getMetadataFailure, +} from '../reducers/metadata'; + +function* getMetadata() { + const url = `${process.env.DB_URL}/apistatus`; + try { + const { data } = yield call(axios.get, url); + yield put(getMetadataSuccess(data)); + } catch (e) { + yield put(getMetadataFailure(e)); + } +} + +export default function* rootSaga() { + yield takeLatest(types.GET_METADATA_REQUEST, getMetadata); +} diff --git a/src/styles/main/_footer.scss b/src/styles/main/_footer.scss index b47129fb8..7e9b914bc 100644 --- a/src/styles/main/_footer.scss +++ b/src/styles/main/_footer.scss @@ -4,12 +4,29 @@ footer.navbar { width: 100vw; height: $footer-height; background: $brand-main-color; + color: $brand-bg-color; + text-align: center; - p { - width: 100vw; - color: $brand-bg-color; - font-weight: bold; - text-align: center; + .last-updated { + display: inline-block; + margin: 0 auto; line-height: $footer-height; } + + .version { + position: absolute; + right: 20px; + top: 0; + line-height: $footer-height; + font-size: 12px; + cursor: default; + .hover-over-tooltip { + color: $brand-main-color; + font-weight: normal; + font-size: 14px; + font-family: $brand-text-family; + width: auto; + word-break: keep-all; + } + } } From e55419a9b0b3ed79057f55a5328ad116ede89e70 Mon Sep 17 00:00:00 2001 From: Jake Mensch Date: Sun, 19 Apr 2020 15:07:27 -0700 Subject: [PATCH 2/2] linting --- src/components/main/footer/Footer.jsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/components/main/footer/Footer.jsx b/src/components/main/footer/Footer.jsx index c70033c1f..ca8d556aa 100644 --- a/src/components/main/footer/Footer.jsx +++ b/src/components/main/footer/Footer.jsx @@ -31,7 +31,9 @@ const Footer = ({ backendSha.substr(0, 7), ]} > - Version { version } + Version +   + { version } )}