From 7e6e3cbc4901e112d5ffc2eb848b2f620fb81ce5 Mon Sep 17 00:00:00 2001 From: "Scott E. Graves" Date: Fri, 30 Aug 2019 16:51:49 -0500 Subject: [PATCH] #8: Add tooltips to settings [partial] --- src/App.js | 8 +++-- .../ConfigurationItem/ConfigurationItem.js | 14 ++++++-- src/components/InfoDetails/InfoDetails.css | 11 ++++++ src/components/InfoDetails/InfoDetails.js | 30 ++++++++++++++++ src/redux/actions/error_actions.js | 34 +++++++++++++++++++ src/redux/reducers/error_reducer.js | 25 +++++++++++++- 6 files changed, 116 insertions(+), 6 deletions(-) create mode 100644 src/components/InfoDetails/InfoDetails.css create mode 100644 src/components/InfoDetails/InfoDetails.js diff --git a/src/App.js b/src/App.js index 6f15cbe..780b5e5 100644 --- a/src/App.js +++ b/src/App.js @@ -7,6 +7,7 @@ import DependencyList from './components/DependencyList/DependencyList'; import DownloadProgress from './components/DownloadProgress/DownloadProgress'; import ErrorDetails from './components/ErrorDetails/ErrorDetails'; import Grid from './components/UI/Grid/Grid'; +import InfoDetails from './components/InfoDetails/InfoDetails'; import IPCContainer from './containers/IPCContainer/IPCContainer'; import Loading from './components/UI/Loading/Loading'; import Modal from './components/UI/Modal/Modal'; @@ -121,6 +122,7 @@ class App extends IPCContainer { !this.props.DismissDependencies && this.props.AllowMount; + const infoDisplay = this.createModalConditionally(this.props.DisplayInfo, , true); const rebootDisplay = this.createModalConditionally(this.props.RebootRequired, ); const configDisplay = this.createModalConditionally(showConfig, ); const dependencyDisplay = this.createModalConditionally(showDependencies, ); @@ -156,12 +158,13 @@ class App extends IPCContainer { return (
{selectAppPlatformDisplay} - {errorDisplay} {dependencyDisplay} {upgradeDisplay} - {downloadDisplay} {configDisplay} + {infoDisplay} + {downloadDisplay} {rebootDisplay} + {errorDisplay}
@@ -203,6 +206,7 @@ const mapStateToProps = state => { DismissDependencies: state.install.DismissDependencies, DisplayConfiguration: state.mounts.DisplayConfiguration, DisplayError: state.error.DisplayError, + DisplayInfo: state.error.DisplayInfo, DisplaySelectAppPlatform: state.common.DisplaySelectAppPlatform, DownloadActive: state.download.DownloadActive, InstallActive: state.install.InstallActive, diff --git a/src/components/ConfigurationItem/ConfigurationItem.js b/src/components/ConfigurationItem/ConfigurationItem.js index 13b4e24..f143839 100644 --- a/src/components/ConfigurationItem/ConfigurationItem.js +++ b/src/components/ConfigurationItem/ConfigurationItem.js @@ -3,8 +3,16 @@ import './ConfigurationItem.css'; import settings from '../../assets/settings'; import {FontAwesomeIcon} from '@fortawesome/react-fontawesome'; import {faInfoCircle} from '@fortawesome/free-solid-svg-icons'; +import {connect} from 'react-redux'; +import {notifyInfo} from '../../redux/actions/error_actions'; -export default props => { +const mapDispatchToProps = dispatch => { + return { + notifyInfo: (title, msg) => dispatch(notifyInfo(title, msg)) + } +}; + +export default connect(null, mapDispatchToProps)(props => { const handleChanged = (e) => { const target = e.target; if (target.type === 'checkbox') { @@ -17,7 +25,7 @@ export default props => { if (settings[props.grouping] && settings[props.grouping][props.label]) { const displayInfo = () => { const description = settings[props.grouping][props.label]; - alert(description); + props.notifyInfo(props.label, description); }; infoDisplay = {
); -}; \ No newline at end of file +}); \ No newline at end of file diff --git a/src/components/InfoDetails/InfoDetails.css b/src/components/InfoDetails/InfoDetails.css new file mode 100644 index 0000000..28fe9d2 --- /dev/null +++ b/src/components/InfoDetails/InfoDetails.css @@ -0,0 +1,11 @@ +.InfoDetailsHeading { + text-align: center; + margin-bottom: 4px; +} + +.InfoDetailsContent { + max-height: 70vh; + min-width: 80vw; + overflow-y: auto; + margin-bottom: 8px; +} \ No newline at end of file diff --git a/src/components/InfoDetails/InfoDetails.js b/src/components/InfoDetails/InfoDetails.js new file mode 100644 index 0000000..37d6d0c --- /dev/null +++ b/src/components/InfoDetails/InfoDetails.js @@ -0,0 +1,30 @@ +import React from 'react'; +import {dismissInfo} from '../../redux/actions/error_actions'; +import {connect} from 'react-redux'; +import Box from '../UI/Box/Box'; +import Button from '../UI/Button/Button'; +import './InfoDetails.css'; + +const mapStateToProps = state => { + return { + InfoMessage: state.error.InfoStack.length > 0 ? state.error.InfoStack[0] : '', + }; +}; + +const mapDispatchToProps = dispatch => { + return { + dismissInfo: () => dispatch(dismissInfo()), + }; +}; + +export default connect(mapStateToProps, mapDispatchToProps)(props => { + return ( + +

{props.InfoMessage.title}

+
+

{props.InfoMessage.message}

+
+ +
+ ); +}); \ No newline at end of file diff --git a/src/redux/actions/error_actions.js b/src/redux/actions/error_actions.js index f46c8cc..0fdcf4c 100644 --- a/src/redux/actions/error_actions.js +++ b/src/redux/actions/error_actions.js @@ -13,6 +13,14 @@ export const clearError = () => { }; }; +export const CLEAR_INFO = 'error/clearInfo'; +export const clearInfo = () => { + return { + type: CLEAR_INFO, + payload: null, + }; +}; + export const dismissError = () => { return (dispatch, getState) => { dispatch(clearError()); @@ -27,6 +35,12 @@ export const dismissError = () => { }; }; +export const dismissInfo = () => { + return dispatch => { + dispatch(clearInfo()); + }; +}; + export const notifyError = (msg, critical, callback) => { return dispatch => { ErrorActions = [callback, ...ErrorActions]; @@ -36,6 +50,14 @@ export const notifyError = (msg, critical, callback) => { }; }; +export const notifyInfo = (title, msg) => { + return dispatch => { + title = title ? title.toString() : 'Information'; + msg = msg ? msg.toString() : ''; + dispatch(setInfo(title, msg)); + }; +}; + export const SET_ERROR_INFO = 'error/setErrorInfo'; export const setErrorInfo = (msg, critical) => { return { @@ -45,4 +67,16 @@ export const setErrorInfo = (msg, critical) => { critical } } +}; + + +export const SET_INFO = 'error/setInfo'; +export const setInfo = (title, msg) => { + return { + type: SET_INFO, + payload: { + title, + msg + } + } }; \ No newline at end of file diff --git a/src/redux/reducers/error_reducer.js b/src/redux/reducers/error_reducer.js index 8a25120..0bb20d2 100644 --- a/src/redux/reducers/error_reducer.js +++ b/src/redux/reducers/error_reducer.js @@ -1,13 +1,17 @@ import {createReducer} from 'redux-starter-kit'; import { CLEAR_ERROR, - SET_ERROR_INFO + CLEAR_INFO, + SET_ERROR_INFO, + SET_INFO } from '../actions/error_actions'; export const errorReducer = createReducer({ DisplayError: false, + DisplayInfo: false, ErrorCritical: false, ErrorStack: [], + InfoStack: [], }, { [CLEAR_ERROR]: state => { const errorStack = (state.ErrorStack.length > 0) ? state.ErrorStack.slice(1) : []; @@ -17,6 +21,14 @@ export const errorReducer = createReducer({ ErrorStack: errorStack, } }, + [CLEAR_INFO]: state => { + const infoStack = (state.InfoStack.length > 0) ? state.InfoStack.slice(1) : []; + return { + ...state, + DisplayInfo: (infoStack.length > 0), + InfoStack: infoStack, + } + }, [SET_ERROR_INFO]: (state, action) => { const errorStack = [action.payload.msg, ...state.ErrorStack]; return { @@ -25,5 +37,16 @@ export const errorReducer = createReducer({ ErrorCritical: state.ErrorCritical || action.payload.critical, ErrorStack: errorStack, } + }, + [SET_INFO]: (state, action) => { + const infoStack = [{ + title: action.payload.title, + message: action.payload.msg + }, ...state.InfoStack]; + return { + ...state, + DisplayInfo: true, + InfoStack: infoStack, + } } }); \ No newline at end of file