diff --git a/src/components/alerts/alert.css b/src/components/alerts/alert.css index c4f00a741912c0ea92b73d5f387b759f707dce4b..0787a9fb12436804149417d930db8afd01de5c71 100644 --- a/src/components/alerts/alert.css +++ b/src/components/alerts/alert.css @@ -30,7 +30,29 @@ } .alert-close-button { + outline-style:none; +} + +.alert-close-button-container { margin-top: 7px; margin-right: 4px; outline-style:none; + width: 30px; + height: 30px; +} + +.connection-button { + padding: 0.55rem 0.9rem; + border-radius: 0.35rem; + background: #FF8C1A; + color: white; + font-weight: 700; + font-size: 0.77rem; + margin: 0.25rem; + border: none; + cursor: pointer; + display: flex; + align-items: center; + margin-right: 13px; + outline-style:none; } diff --git a/src/components/alerts/alert.jsx b/src/components/alerts/alert.jsx index d0f65309e086f3cc2582131ce21677c2d9a4845e..2ec848984c77aaac28a9a85f6a3bce048089b617 100644 --- a/src/components/alerts/alert.jsx +++ b/src/components/alerts/alert.jsx @@ -1,5 +1,6 @@ import React from 'react'; import PropTypes from 'prop-types'; +import {FormattedMessage} from 'react-intl'; import Box from '../box/box.jsx'; import CloseButton from '../close-button/close-button.jsx'; @@ -9,7 +10,9 @@ import styles from './alert.css'; const AlertComponent = ({ iconURL, message, - onCloseAlert + onCloseAlert, + onReconnect, + showReconnect }) => ( <Box className={styles.alert} @@ -23,19 +26,37 @@ const AlertComponent = ({ ) : null} {message} </div> - <CloseButton - className={styles.alertCloseButton} - color={CloseButton.COLOR_ORANGE} - size={CloseButton.SIZE_LARGE} - onClick={onCloseAlert} - /> + {showReconnect ? ( + <button + className={styles.connectionButton} + onClick={onReconnect} + > + <FormattedMessage + defaultMessage="Reconnect" + description="Button to reconnect the device" + id="gui.connection.reconnect" + /> + </button> + ) : null} + <Box + className={styles.alertCloseButtonContainer} + > + <CloseButton + className={styles.alertCloseButton} + color={CloseButton.COLOR_ORANGE} + size={CloseButton.SIZE_LARGE} + onClick={onCloseAlert} + /> + </Box> </Box> ); AlertComponent.propTypes = { iconURL: PropTypes.string, message: PropTypes.string, - onCloseAlert: PropTypes.func.isRequired + onCloseAlert: PropTypes.func.isRequired, + onReconnect: PropTypes.func, + showReconnect: PropTypes.bool.isRequired }; export default AlertComponent; diff --git a/src/components/alerts/alerts.jsx b/src/components/alerts/alerts.jsx index 1835a50a820e7de90443449ecec60c54f33779f5..9a87f766c376a0562225e118c9ef53cea0d29f4f 100644 --- a/src/components/alerts/alerts.jsx +++ b/src/components/alerts/alerts.jsx @@ -15,10 +15,12 @@ const AlertsComponent = ({ > {alertsList.map((a, index) => ( <Alert + extensionId={a.extensionId} iconURL={a.iconURL} index={index} key={index} message={a.message} + showReconnect={a.showReconnect} onCloseAlert={onCloseAlert} /> ))} diff --git a/src/components/gui/gui.css b/src/components/gui/gui.css index 3e4d763c4817107abd738ec6c4c8367aae8246d6..eb4f1c929a39974b58fe42c951057b2ab4454bc6 100644 --- a/src/components/gui/gui.css +++ b/src/components/gui/gui.css @@ -303,7 +303,7 @@ $fade-out-distance: 15px; /* Alerts */ .alerts-container { - width: 448px; + width: 520px; z-index: $z-index-alerts; left: 0; right: 0; diff --git a/src/containers/alert.jsx b/src/containers/alert.jsx index cb38427ad751c6a73b85a2da7ee0565e9ecec21d..62ff58448a03c172687a9a3c5518b516b3f0b187 100644 --- a/src/containers/alert.jsx +++ b/src/containers/alert.jsx @@ -1,40 +1,68 @@ import React from 'react'; import bindAll from 'lodash.bindall'; import PropTypes from 'prop-types'; +import {connect} from 'react-redux'; import AlertComponent from '../components/alerts/alert.jsx'; +import {openConnectionModal} from '../reducers/modals'; +import {setConnectionModalExtensionId} from '../reducers/connection-modal'; class Alert extends React.Component { constructor (props) { super(props); bindAll(this, [ - 'handleOnCloseAlert' + 'handleOnCloseAlert', + 'handleOnReconnect' ]); } handleOnCloseAlert () { this.props.onCloseAlert(this.props.index); } + handleOnReconnect () { + this.props.onOpenConnectionModal(this.props.extensionId); + this.handleOnCloseAlert(); + } render () { const { index, // eslint-disable-line no-unused-vars iconURL, - message + message, + showReconnect } = this.props; return ( <AlertComponent iconURL={iconURL} message={message} + showReconnect={showReconnect} onCloseAlert={this.handleOnCloseAlert} + onReconnect={this.handleOnReconnect} /> ); } } +const mapStateToProps = state => ({ + state: state +}); + +const mapDispatchToProps = dispatch => ({ + onOpenConnectionModal: id => { + dispatch(setConnectionModalExtensionId(id)); + dispatch(openConnectionModal()); + } +}); + Alert.propTypes = { + extensionId: PropTypes.string, iconURL: PropTypes.string, index: PropTypes.number, message: PropTypes.string, - onCloseAlert: PropTypes.func.isRequired + onCloseAlert: PropTypes.func.isRequired, + onOpenConnectionModal: PropTypes.func, + showReconnect: PropTypes.bool.isRequired }; -export default Alert; +export default connect( + mapStateToProps, + mapDispatchToProps +)(Alert); diff --git a/src/reducers/alerts.js b/src/reducers/alerts.js index fefc97b37327eb2310dfa1b430afe1bfccf992cb..ee5ef0931596878c9c0cf59102921848fb2f8873 100644 --- a/src/reducers/alerts.js +++ b/src/reducers/alerts.js @@ -15,11 +15,14 @@ const reducer = function (state, action) { const newList = state.alertsList.slice(); const newAlert = {message: action.data.message}; const extensionId = action.data.extensionId; + newAlert.showReconnect = false; if (extensionId) { // if it's an extension const extension = extensionData.find(ext => ext.extensionId === extensionId); if (extension && extension.name) { // TODO: is this the right place to assemble this message? + newAlert.extensionId = extensionId; newAlert.message = `${newAlert.message} ${extension.name}.`; + newAlert.showReconnect = true; } if (extension && extension.smallPeripheralImage) { newAlert.iconURL = extension.smallPeripheralImage;