diff --git a/.eslintrc.js b/.eslintrc.js index d1af6c8b8..da11fbc21 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -40,7 +40,7 @@ module.exports = { rules: { 'arrow-parens': [2, 'as-needed', { 'requireForBlockBody': true }], 'camelcase': [0], - 'class-methods-use-this': [0], + 'class-methods-use-this': [1], 'comma-dangle': [2, { 'arrays': 'only-multiline', 'objects': 'only-multiline', @@ -54,37 +54,50 @@ module.exports = { 'lines-between-class-members': [1], 'max-len': [0], 'newline-per-chained-call': [0, { 'ignoreChainWithDepth': 2 }], - 'no-mixed-operators': [0], + 'no-mixed-operators': [1], 'no-nested-ternary': [0], - 'no-param-reassign': [0], // TODO: enable this check + 'no-param-reassign': ['error', { + props: true, + ignorePropertyModificationsFor: [ + 'acc', // for reduce accumulators + 'document', // for IIFE with window & document params + 'c2pFrame', // for mutable iframe c2p element + 'trackerEl', // for trackers.forEach() + 'categoryEl', // for categories.forEach() + 'dataEntry', // for data.forEach() + 'appEntry', // for apps.forEach() + 'sEntry', // for apps.forEach() + 'confMutable', // for mutable conf settings + 'eventMutable', // for mutable event details objects + ] + }], 'no-plusplus': [0], - 'no-prototype-builtins': [0], // TODO: enable this check - 'no-restricted-syntax': [0], // TODO: enable this check + 'no-prototype-builtins': [0], + 'no-restricted-syntax': [1], 'no-tabs': [0], 'no-underscore-dangle': [0], 'no-unused-vars': [1], 'no-useless-escape': [1], 'operator-linebreak': [0], - 'prefer-object-spread': [0], // TODO: enable this check + 'prefer-object-spread': [1], 'space-before-function-paren': [2, 'never'], - 'template-curly-spacing': [0], // Plugin: Import 'import/no-cycle': [0], - 'import/prefer-default-export': [0], + 'import/prefer-default-export': [1], // Plugin: React - 'react/destructuring-assignment': [0], + 'react/destructuring-assignment': [1], 'react/static-property-placement': [0], 'react/jsx-curly-newline': [0], 'react/jsx-indent': [1, 'tab'], 'react/jsx-indent-props': [1, 'tab'], - 'react/jsx-props-no-spreading': [0], // TODO: enable this check - 'react/no-access-state-in-setstate': [0], // TODO: enable this check + 'react/jsx-props-no-spreading': [1], + 'react/no-access-state-in-setstate': [1], 'react/no-danger': [0], 'react/prop-types': [0], 'react/jsx-fragments': [1, 'element'], - 'react/sort-comp': [2, { + 'react/sort-comp': [1, { order: [ "static-variables", "instance-variables", @@ -104,5 +117,8 @@ module.exports = { 'jsx-a11y/mouse-events-have-key-events': [0], 'jsx-a11y/no-noninteractive-element-interactions': [0], 'jsx-a11y/no-static-element-interactions': [0], + 'jsx-a11y/label-has-associated-control': [0], //ToDo: enable this check. Throws 2 errors, should work. + 'jsx-a11y/media-has-caption': [0], //ToDo: enable this check. Need Captions to enable. + 'jsx-a11y/anchor-has-content': [0], //ToDo: enable this check. Need anchor text to enable. }, }; diff --git a/_locales/en/messages.json b/_locales/en/messages.json index 1d7d86010..7a28e4a4a 100644 --- a/_locales/en/messages.json +++ b/_locales/en/messages.json @@ -704,6 +704,9 @@ "panel_detail_menu_premium_title": { "message": "Premium" }, + "panel_detail_learn_more": { + "message": "Learn More" + }, "panel_detail_history_title": { "message": "History" }, diff --git a/app/Account/AccountReducer.js b/app/Account/AccountReducer.js index 48076f6b0..8365f113a 100644 --- a/app/Account/AccountReducer.js +++ b/app/Account/AccountReducer.js @@ -39,61 +39,62 @@ export default (state = initialState, action) => { case UPDATE_PANEL_DATA: { const { account } = action.data; if (account === null) { - return Object.assign({}, initialState); + return { ...initialState }; } const { userID, user, userSettings, subscriptionData } = account; - return Object.assign({}, state, { + return { + ...state, loggedIn: true, userID, user, userSettings, - subscriptionData, - }); + subscriptionData + }; } case REGISTER_SUCCESS: case LOGIN_SUCCESS: { - return Object.assign({}, state, { - loggedIn: true, - }); + return { ...state, loggedIn: true }; } case LOGOUT_SUCCESS: { - return Object.assign({}, initialState); + return { ...initialState }; } case GET_USER_SUCCESS: { const { user } = action.payload; - return Object.assign({}, state, { + return { + ...state, loggedIn: true, user - }); + }; } case GET_USER_SETTINGS_SUCCESS: { const { settings } = action.payload; - return Object.assign({}, state, { + return { + ...state, loggedIn: true, userSettings: settings - }); + }; } case GET_USER_SUBSCRIPTION_DATA_FAIL: { const { subscriptionData } = initialState; - return Object.assign({}, state, { - subscriptionData, - }); + return { ...state, subscriptionData }; } case GET_USER_SUBSCRIPTION_DATA_SUCCESS: { const { subscriptionData } = action.payload; - return Object.assign({}, state, { + return { + ...state, loggedIn: true, subscriptionData - }); + }; } case RESET_PASSWORD_SUCCESS: { const toastMessage = t('banner_check_your_email_title'); - return Object.assign({}, state, { + return { + ...state, toastMessage, resetPasswordError: false - }); + }; } case RESET_PASSWORD_FAIL: { const { errors } = action.payload; @@ -108,10 +109,11 @@ export default (state = initialState, action) => { errorText = t('server_error_message'); } }); - return Object.assign({}, state, { + return { + ...state, toastMessage: errorText, resetPasswordError: true - }); + }; } default: return state; diff --git a/app/content-scripts/click_to_play.js b/app/content-scripts/click_to_play.js index 95c329857..a17479c69 100644 --- a/app/content-scripts/click_to_play.js +++ b/app/content-scripts/click_to_play.js @@ -160,11 +160,11 @@ const Click2PlayContentScript = (function(win, doc) { if (name === 'c2p') { if (message) { // Dequeue C2P data stored while the script injection was taking place - for (const app_id in message) { - if (message.hasOwnProperty(app_id)) { - applyC2P(app_id, message[app_id].data, message[app_id].html); - delete message[app_id]; - } + const messageKeys = Object.keys(message); + for (let i = 0; i < messageKeys.length; i++) { + const app_id = messageKeys[i]; + applyC2P(app_id, message[app_id].data, message[app_id].html); + delete message[app_id]; } } } diff --git a/app/content-scripts/page_performance.js b/app/content-scripts/page_performance.js index 2360367dc..467333c4d 100644 --- a/app/content-scripts/page_performance.js +++ b/app/content-scripts/page_performance.js @@ -27,7 +27,8 @@ const { sendMessage } = msg; * Use to call init to initialize functionality * @var {Object} initialized to an object with init method as its property */ -const PageInfo = (function(window, document) { +const PageInfo = (function(window, doc) { + const document = doc; let state = document.readyState; /** * Calculate page domain and latency. Send pageInfo to background.js. diff --git a/app/content-scripts/utils/msg.js b/app/content-scripts/utils/msg.js index 3de4d16f8..f97f98342 100644 --- a/app/content-scripts/utils/msg.js +++ b/app/content-scripts/utils/msg.js @@ -13,8 +13,6 @@ /** * @namespace ContentScriptUtils */ -/* eslint no-use-before-define: 0 */ - import { log } from '../../../src/utils/common'; import { sendMessageInPromise as panelSendPromiseMessage, sendMessage as panelSendMessage } from '../../panel/utils/msg'; diff --git a/app/hub/Views/AppView/AppView.jsx b/app/hub/Views/AppView/AppView.jsx index e46108282..4ae9db2c9 100644 --- a/app/hub/Views/AppView/AppView.jsx +++ b/app/hub/Views/AppView/AppView.jsx @@ -31,7 +31,8 @@ class AppView extends Component { * Lifecycle Event */ componentDidUpdate(prevProps) { - if (prevProps.children !== this.props.children) { + const { children } = this.props; + if (prevProps.children !== children) { this.mainContent.current.scrollTop = 0; } } diff --git a/app/hub/Views/AppView/AppViewContainer.jsx b/app/hub/Views/AppView/AppViewContainer.jsx index 2d98688d3..012b24f89 100644 --- a/app/hub/Views/AppView/AppViewContainer.jsx +++ b/app/hub/Views/AppView/AppViewContainer.jsx @@ -25,7 +25,8 @@ class AppViewContainer extends Component { * Handle clicking to exit the Toast Message. */ _exitToast = () => { - this.props.actions.setToast({ + const { actions } = this.props; + actions.setToast({ toastMessage: '', toastClass: '', }); @@ -36,11 +37,13 @@ class AppViewContainer extends Component { * @return {JSX} JSX for rendering the Home View of the Hub app */ render() { - const childProps = { - ...this.props, - exitToast: this._exitToast, - }; - return ; + const { app, children } = this.props; + + return ( + + {children} + + ); } } diff --git a/app/hub/Views/AppView/AppViewReducer.js b/app/hub/Views/AppView/AppViewReducer.js index 970f51132..94ee686f2 100644 --- a/app/hub/Views/AppView/AppViewReducer.js +++ b/app/hub/Views/AppView/AppViewReducer.js @@ -19,12 +19,13 @@ function AppViewReducer(state = initialState, action) { switch (action.type) { case SET_TOAST: { const { toastMessage, toastClass } = action.data; - return Object.assign({}, state, { - app: Object.assign({}, { + return { + ...state, + app: { toastMessage, toastClass - }), - }); + } + }; } default: return state; } diff --git a/app/hub/Views/AppView/index.js b/app/hub/Views/AppView/index.js index 8fc86ded9..9d9d20ffc 100644 --- a/app/hub/Views/AppView/index.js +++ b/app/hub/Views/AppView/index.js @@ -23,7 +23,7 @@ import AppViewReducer from './AppViewReducer'; * @return {function} this function returns a plain object, which will be merged into the component's props * @memberof HubContainers */ -const mapStateToProps = state => Object.assign({}, state.app); +const mapStateToProps = state => ({ ...state.app }); /** * Bind the component's action creators using Redux's bindActionCreators. @@ -32,7 +32,7 @@ const mapStateToProps = state => Object.assign({}, state.app); * @memberof SetupContainers */ const mapDispatchToProps = dispatch => ({ - actions: bindActionCreators(Object.assign({}, { setToast }), dispatch), + actions: bindActionCreators({ setToast }, dispatch), }); export const reducer = AppViewReducer; diff --git a/app/hub/Views/CreateAccountView/CreateAccountView.jsx b/app/hub/Views/CreateAccountView/CreateAccountView.jsx index af0667bde..7804b0c62 100644 --- a/app/hub/Views/CreateAccountView/CreateAccountView.jsx +++ b/app/hub/Views/CreateAccountView/CreateAccountView.jsx @@ -105,7 +105,7 @@ const CreateAccountView = (props) => { /> {confirmEmailError && (
- {t('your_emails_do_not_match')} + {t('your_email_do_not_match')}
)} diff --git a/app/hub/Views/CreateAccountView/CreateAccountViewContainer.jsx b/app/hub/Views/CreateAccountView/CreateAccountViewContainer.jsx index f0099d3b2..fdbad32c0 100644 --- a/app/hub/Views/CreateAccountView/CreateAccountViewContainer.jsx +++ b/app/hub/Views/CreateAccountView/CreateAccountViewContainer.jsx @@ -45,7 +45,8 @@ class CreateAccountViewContainer extends Component { validateInput: false, }; - this.props.actions.setToast({ + const { actions } = this.props; + actions.setToast({ toastMessage: '', toastClass: '', }); @@ -59,7 +60,8 @@ class CreateAccountViewContainer extends Component { const { name, value } = event.target; this.setState({ [name]: value }); - if (!this.state.validateInput) { + const { validateInput } = this.state; + if (!validateInput) { return; } @@ -132,20 +134,21 @@ class CreateAccountViewContainer extends Component { if (!emailIsValid || !confirmIsValid || !legalConsentChecked || !passwordIsValid) { return; } - this.props.actions.setToast({ + const { actions, history } = this.props; + actions.setToast({ toastMessage: '', toastClass: '' }); - this.props.actions.register(email, confirmEmail, firstName, lastName, password).then((success) => { + actions.register(email, confirmEmail, firstName, lastName, password).then((success) => { if (success) { - this.props.actions.getUser(); - this.props.actions.setToast({ + actions.getUser(); + actions.setToast({ toastMessage: t('hub_create_account_toast_success'), toastClass: 'success' }); - this.props.history.push('/'); + history.push('/'); } else { - this.props.actions.setToast({ + actions.setToast({ toastMessage: t('hub_create_account_toast_error'), toastClass: 'alert' }); @@ -172,30 +175,26 @@ class CreateAccountViewContainer extends Component { passwordInvalidError, passwordLengthError, } = this.state; - const createAccountChildProps = { - email, - emailError, - confirmEmail, - confirmEmailError, - firstName, - lastName, - legalConsentChecked, - legalConsentNotCheckedError, - password, - passwordInvalidError, - passwordLengthError, - handleInputChange: this._handleInputChange, - handleLegalConsentCheckboxChange: this._handleLegalConsentCheckboxChange, - handleSubmit: this._handleCreateAccountAttempt - }; - const signedInChildProps = { - email: user && user.email || email, - }; return loggedIn ? ( - + ) : ( - + ); } } diff --git a/app/hub/Views/CreateAccountView/__tests__/__snapshots__/CreateAccountView.test.jsx.snap b/app/hub/Views/CreateAccountView/__tests__/__snapshots__/CreateAccountView.test.jsx.snap index ca188b1ae..082755213 100644 --- a/app/hub/Views/CreateAccountView/__tests__/__snapshots__/CreateAccountView.test.jsx.snap +++ b/app/hub/Views/CreateAccountView/__tests__/__snapshots__/CreateAccountView.test.jsx.snap @@ -306,7 +306,7 @@ exports[`app/hub/Views/CreateAccount component Snapshot tests with react-test-re
- your_emails_do_not_match + your_email_do_not_match
diff --git a/app/hub/Views/CreateAccountView/index.js b/app/hub/Views/CreateAccountView/index.js index 2fe88b9f9..da18f1190 100644 --- a/app/hub/Views/CreateAccountView/index.js +++ b/app/hub/Views/CreateAccountView/index.js @@ -24,7 +24,7 @@ import { setToast } from '../AppView/AppViewActions'; * @return {function} this function returns a plain object, which will be merged into the component's props * @memberof HubContainers */ -const mapStateToProps = state => Object.assign({}, state.account); +const mapStateToProps = state => ({ ...state.account }); /** * Bind the component's action creators using Redux's bindActionCreators. @@ -33,11 +33,11 @@ const mapStateToProps = state => Object.assign({}, state.account); * @memberof SetupContainers */ const mapDispatchToProps = dispatch => ({ - actions: bindActionCreators(Object.assign({}, { + actions: bindActionCreators({ setToast, register, - getUser, - }), dispatch), + getUser + }, dispatch), }); export default connect(mapStateToProps, mapDispatchToProps)(CreateAccountViewContainer); diff --git a/app/hub/Views/HomeView/HomeViewContainer.jsx b/app/hub/Views/HomeView/HomeViewContainer.jsx index 81caf36c6..53e472312 100644 --- a/app/hub/Views/HomeView/HomeViewContainer.jsx +++ b/app/hub/Views/HomeView/HomeViewContainer.jsx @@ -56,8 +56,9 @@ class HomeViewContainer extends Component { * Function to handle toggling Metrics Opt-In */ _handleToggleMetrics = () => { - const enable_metrics = !this.props.home.enable_metrics; - this.props.actions.setMetrics({ enable_metrics }); + const { actions, home } = this.props; + const enable_metrics = !home.enable_metrics; + actions.setMetrics({ enable_metrics }); } /** @@ -68,7 +69,8 @@ class HomeViewContainer extends Component { _handlePremiumPromoModalClick = (type = 'basic') => { // GH-1777 // we want to show the promo modal exactly once per Hub visit - this.props.actions.markPremiumPromoModalShown(); + const { actions } = this.props; + actions.markPremiumPromoModalShown(); sendMessage('SET_PREMIUM_PROMO_MODAL_SEEN', {}); @@ -106,23 +108,14 @@ class HomeViewContainer extends Component { _render() { const { justInstalled } = this.state; const { home, user } = this.props; - const isPlus = user && user.plusAccess || false; - const isPremium = user && user.premiumAccess || false; + const isPlus = (user && user.plusAccess) || false; + const isPremium = (user && user.premiumAccess) || false; const { premium_promo_modal_shown, setup_complete, tutorial_complete, enable_metrics, } = home; - const childProps = { - justInstalled, - setup_complete, - tutorial_complete, - enable_metrics, - changeMetrics: this._handleToggleMetrics, - email: user ? user.email : '', - isPlus, - }; const showPromoModal = !premium_promo_modal_shown && !isPremium; @@ -137,7 +130,15 @@ class HomeViewContainer extends Component { handleGetPlusClick={this._handleGetPlusClick} handleTryMidnightClick={this._handleTryMidnightClick} /> - + ); } diff --git a/app/hub/Views/HomeView/HomeViewReducer.js b/app/hub/Views/HomeView/HomeViewReducer.js index 1582d7e62..2461abac6 100644 --- a/app/hub/Views/HomeView/HomeViewReducer.js +++ b/app/hub/Views/HomeView/HomeViewReducer.js @@ -23,26 +23,25 @@ function HomeViewReducer(state = initialState, action) { tutorial_complete, enable_metrics, } = action.data; - return Object.assign({}, state, { - home: Object.assign({}, state.home, { + return { + ...state, + home: { + ...state.home, setup_complete, tutorial_complete, - enable_metrics, - }), - }); + enable_metrics + } + }; } case MARK_PREMIUM_PROMO_MODAL_SHOWN: { - return Object.assign({}, state, { - home: Object.assign({}, state.home, { - premium_promo_modal_shown: true, - }) - }); + return { + ...state, + home: { ...state.home, premium_promo_modal_shown: true } + }; } case SET_METRICS: { const { enable_metrics } = action.data; - return Object.assign({}, state, { - home: Object.assign({}, state.home, { enable_metrics }), - }); + return { ...state, home: { ...state.home, enable_metrics } }; } default: return state; diff --git a/app/hub/Views/HomeView/index.js b/app/hub/Views/HomeView/index.js index 4e4a35da3..9a947b809 100644 --- a/app/hub/Views/HomeView/index.js +++ b/app/hub/Views/HomeView/index.js @@ -25,7 +25,7 @@ import { getUser } from '../../../Account/AccountActions'; * @return {function} this function returns a plain object, which will be merged into the component's props * @memberof HubContainers */ -const mapStateToProps = state => Object.assign({}, state.home, state.account); +const mapStateToProps = state => ({ ...state.home, ...state.account }); /** * Bind the component's action creators using Redux's bindActionCreators. @@ -34,7 +34,7 @@ const mapStateToProps = state => Object.assign({}, state.home, state.account); * @memberof SetupContainers */ const mapDispatchToProps = dispatch => ({ - actions: bindActionCreators(Object.assign({}, HomeViewActions, { getUser }), dispatch), + actions: bindActionCreators({ ...HomeViewActions, getUser }, dispatch), }); export const reducer = HomeViewReducer; diff --git a/app/hub/Views/LogInView/LogInViewContainer.jsx b/app/hub/Views/LogInView/LogInViewContainer.jsx index fb9cd1289..00e711b2c 100644 --- a/app/hub/Views/LogInView/LogInViewContainer.jsx +++ b/app/hub/Views/LogInView/LogInViewContainer.jsx @@ -32,7 +32,8 @@ class LogInViewContainer extends Component { validateInput: false, }; - this.props.actions.setToast({ + const { actions } = this.props; + actions.setToast({ toastMessage: '', toastClass: '', }); @@ -46,7 +47,8 @@ class LogInViewContainer extends Component { const { name, value } = event.target; this.setState({ [name]: value }); - if (!this.state.validateInput) { + const { validateInput } = this.state; + if (!validateInput) { return; } @@ -87,28 +89,29 @@ class LogInViewContainer extends Component { return; } - this.props.actions.setToast({ + const { actions, history } = this.props; + actions.setToast({ toastMessage: '', toastClass: '' }); - this.props.actions.login(email, password).then((success) => { + actions.login(email, password).then((success) => { if (success) { const { origin, pathname, hash } = window.location; window.history.pushState({}, '', `${origin}${pathname}${hash}`); - this.props.actions.getUser(); - this.props.actions.getUserSettings() + actions.getUser(); + actions.getUserSettings() .then((settings) => { const { current_theme } = settings; - return this.props.actions.getTheme(current_theme); + return actions.getTheme(current_theme); }); - this.props.actions.setToast({ + actions.setToast({ toastMessage: t('hub_login_toast_success'), toastClass: 'success' }); - this.props.history.push('/'); + history.push('/'); } else { - this.props.actions.setToast({ + actions.setToast({ toastMessage: t('no_such_email_password_combo'), toastClass: 'alert' }); @@ -128,22 +131,18 @@ class LogInViewContainer extends Component { emailError, passwordError, } = this.state; - const logInChildProps = { - email, - password, - emailError, - passwordError, - handleInputChange: this._handleInputChange, - handleSubmit: this._handleLoginAttempt, - }; - const signedInChildProps = { - email: user && user.email || 'email', - }; return loggedIn ? ( - + ) : ( - + ); } } diff --git a/app/hub/Views/LogInView/index.js b/app/hub/Views/LogInView/index.js index e53caf771..ebcd60244 100644 --- a/app/hub/Views/LogInView/index.js +++ b/app/hub/Views/LogInView/index.js @@ -25,7 +25,7 @@ import { setToast } from '../AppView/AppViewActions'; * @return {function} this function returns a plain object, which will be merged into the component's props * @memberof HubContainers */ -const mapStateToProps = state => Object.assign({}, state.account); +const mapStateToProps = state => ({ ...state.account }); /** * Bind the component's action creators using Redux's bindActionCreators. @@ -34,13 +34,13 @@ const mapStateToProps = state => Object.assign({}, state.account); * @memberof SetupContainers */ const mapDispatchToProps = dispatch => ({ - actions: bindActionCreators(Object.assign({}, { + actions: bindActionCreators({ setToast, login, getUser, getUserSettings, - getTheme, - }), dispatch), + getTheme + }, dispatch), }); export default connect(mapStateToProps, mapDispatchToProps)(LogInViewContainer); diff --git a/app/hub/Views/PlusView/PlusViewContainer.jsx b/app/hub/Views/PlusView/PlusViewContainer.jsx index 2737380ec..beae50a19 100644 --- a/app/hub/Views/PlusView/PlusViewContainer.jsx +++ b/app/hub/Views/PlusView/PlusViewContainer.jsx @@ -35,7 +35,8 @@ class PlusViewContainer extends Component { * Sends the necessary ping to background */ _sendPlusPing = () => { - this.props.actions.sendPing({ type: 'plus_cta_hub' }); + const { actions } = this.props; + actions.sendPing({ type: 'plus_cta_hub' }); } /** @@ -44,12 +45,12 @@ class PlusViewContainer extends Component { */ render() { const { user } = this.props; - const childProps = { - isPlus: user && user.plusAccess || false, - onPlusClick: this._sendPlusPing, - }; - - return ; + return ( + + ); } } diff --git a/app/hub/Views/PlusView/index.js b/app/hub/Views/PlusView/index.js index ee753c74b..cd19404b6 100644 --- a/app/hub/Views/PlusView/index.js +++ b/app/hub/Views/PlusView/index.js @@ -24,7 +24,7 @@ import { getUser } from '../../../Account/AccountActions'; * @return {function} this function returns a plain object, which will be merged into the component's props * @memberof HubContainers */ -const mapStateToProps = state => Object.assign({}, state.account); +const mapStateToProps = state => ({ ...state.account }); /** * Bind the component's action creators using Redux's bindActionCreators. @@ -33,10 +33,10 @@ const mapStateToProps = state => Object.assign({}, state.account); * @memberof TutorialContainers */ const mapDispatchToProps = dispatch => ({ - actions: bindActionCreators(Object.assign({}, { + actions: bindActionCreators({ sendPing, - getUser, - }), dispatch), + getUser + }, dispatch), }); export default connect(mapStateToProps, mapDispatchToProps)(PlusViewContainer); diff --git a/app/hub/Views/ProductsView/ProductsView.jsx b/app/hub/Views/ProductsView/ProductsView.jsx index 64caa889f..699612982 100644 --- a/app/hub/Views/ProductsView/ProductsView.jsx +++ b/app/hub/Views/ProductsView/ProductsView.jsx @@ -20,7 +20,7 @@ import PropTypes from 'prop-types'; * @return {JSX} JSX for rendering the Products View * @memberof HubComponents */ -const ProductsView = props => ( +const ProductsView = ({ onAndroidClick, onIosClick, onLiteClick }) => (
@@ -44,13 +44,13 @@ const ProductsView = props => ( {t('hub_products_main_promo_description')}
- + { this.props.actions.sendPing({ type: 'products_cta_android' }); }} - onIosClick={() => { this.props.actions.sendPing({ type: 'products_cta_ios' }); }} - onLiteClick={() => { this.props.actions.sendPing({ type: 'products_cta_lite' }); }} + onAndroidClick={() => { actions.sendPing({ type: 'products_cta_android' }); }} + onIosClick={() => { actions.sendPing({ type: 'products_cta_ios' }); }} + onLiteClick={() => { actions.sendPing({ type: 'products_cta_lite' }); }} /> ); } diff --git a/app/hub/Views/ProductsView/index.js b/app/hub/Views/ProductsView/index.js index 977e4bf28..955600e4c 100644 --- a/app/hub/Views/ProductsView/index.js +++ b/app/hub/Views/ProductsView/index.js @@ -24,7 +24,7 @@ import { sendPing } from '../AppView/AppViewActions'; * @memberof TutorialContainers */ const mapDispatchToProps = dispatch => ({ - actions: bindActionCreators(Object.assign({}, { sendPing }), dispatch), + actions: bindActionCreators({ sendPing }, dispatch), }); export default connect(null, mapDispatchToProps)(ProductsViewContainer); diff --git a/app/hub/Views/SetupView/SetupView.jsx b/app/hub/Views/SetupView/SetupView.jsx index 690d2b475..8db394a37 100644 --- a/app/hub/Views/SetupView/SetupView.jsx +++ b/app/hub/Views/SetupView/SetupView.jsx @@ -36,7 +36,7 @@ const SetupView = (props) => { path={step.path} render={() => (
- +
)} diff --git a/app/hub/Views/SetupView/SetupViewContainer.jsx b/app/hub/Views/SetupView/SetupViewContainer.jsx index 0902c1ae7..a025a1fec 100644 --- a/app/hub/Views/SetupView/SetupViewContainer.jsx +++ b/app/hub/Views/SetupView/SetupViewContainer.jsx @@ -42,16 +42,19 @@ class SetupViewContainer extends Component { sendMountActions: false, showModal: false, }; + + const { history } = this.props; if (!props.preventRedirect) { - this.props.history.push('/setup/1'); + history.push('/setup/1'); } const title = t('hub_setup_page_title'); window.document.title = title; - this.props.actions.setSetupStep({ setup_step: 7 }); - this.props.actions.initSetupProps(this.props.setup); - this.props.actions.getSetupShowWarningOverride().then((data) => { + const { actions, setup } = this.props; + actions.setSetupStep({ setup_step: 7 }); + actions.initSetupProps(setup); + actions.getSetupShowWarningOverride().then((data) => { const { setup_show_warning_override } = data; const { justInstalled } = QueryString.parse(window.location.search); const { user } = props; @@ -88,8 +91,9 @@ class SetupViewContainer extends Component { * Function to toggle the Ask Again Checkbox */ _toggleCheckbox = () => { - const { setup_show_warning_override } = this.props.setup; - this.props.actions.setSetupShowWarningOverride({ + const { actions, setup } = this.props; + const { setup_show_warning_override } = setup; + actions.setSetupShowWarningOverride({ setup_show_warning_override: !setup_show_warning_override, }); } @@ -99,13 +103,14 @@ class SetupViewContainer extends Component { */ _setDefaultSettings() { this.setState({ sendMountActions: true }); - this.props.actions.setSetupStep({ setup_step: 8 }); - this.props.actions.setBlockingPolicy({ blockingPolicy: BLOCKING_POLICY_RECOMMENDED }); - this.props.actions.setAntiTracking({ enable_anti_tracking: true }); - this.props.actions.setAdBlock({ enable_ad_block: true }); - this.props.actions.setSmartBlocking({ enable_smart_block: true }); - this.props.actions.setGhosteryRewards({ enable_ghostery_rewards: !IS_FIREFOX }); - this.props.actions.setHumanWeb({ enable_human_web: !IS_FIREFOX }); + const { actions } = this.props; + actions.setSetupStep({ setup_step: 8 }); + actions.setBlockingPolicy({ blockingPolicy: BLOCKING_POLICY_RECOMMENDED }); + actions.setAntiTracking({ enable_anti_tracking: true }); + actions.setAdBlock({ enable_ad_block: true }); + actions.setSmartBlocking({ enable_smart_block: true }); + actions.setGhosteryRewards({ enable_ghostery_rewards: !IS_FIREFOX }); + actions.setHumanWeb({ enable_human_web: !IS_FIREFOX }); } /** @@ -113,7 +118,8 @@ class SetupViewContainer extends Component { * @return {JSX} JSX of the Setup Modal's Children */ _renderModalChildren() { - const { setup_show_warning_override } = this.props.setup; + const { setup } = this.props; + const { setup_show_warning_override } = setup; return (
diff --git a/app/hub/Views/SetupView/SetupViewReducer.js b/app/hub/Views/SetupView/SetupViewReducer.js index e17dcf514..46c5c51a1 100644 --- a/app/hub/Views/SetupView/SetupViewReducer.js +++ b/app/hub/Views/SetupView/SetupViewReducer.js @@ -32,9 +32,7 @@ function SetupViewReducer(state = initialState, action) { case GET_SETUP_SHOW_WARNING_OVERRIDE: // Same as SET_SETUP_SHOW_WARNING_OVERRIDE case SET_SETUP_SHOW_WARNING_OVERRIDE: { const { setup_show_warning_override } = action.data; - return Object.assign({}, state, { - setup: Object.assign({}, state.setup, { setup_show_warning_override }), - }); + return { ...state, setup: { ...state.setup, setup_show_warning_override } }; } case INIT_SETUP_PROPS: { const { @@ -56,7 +54,8 @@ function SetupViewReducer(state = initialState, action) { textNext, textDone, } = navigation; - return Object.assign({}, state, { + return { + ...state, setup: { navigation: { activeIndex, @@ -74,8 +73,8 @@ function SetupViewReducer(state = initialState, action) { enable_smart_block, enable_ghostery_rewards, enable_human_web, - }, - }); + } + }; } case SET_SETUP_NAVIGATION: { const { @@ -87,8 +86,10 @@ function SetupViewReducer(state = initialState, action) { textNext, textDone, } = action.data; - return Object.assign({}, state, { - setup: Object.assign({}, state.setup, { + return { + ...state, + setup: { + ...state.setup, navigation: { activeIndex, hrefPrev, @@ -97,51 +98,39 @@ function SetupViewReducer(state = initialState, action) { textPrev, textNext, textDone, - }, - }), - }); + } + } + }; } // Setup Blocking View case SET_BLOCKING_POLICY: { const { blockingPolicy } = action.data; - return Object.assign({}, state, { - setup: Object.assign({}, state.setup, { blockingPolicy }), - }); + return { ...state, setup: { ...state.setup, blockingPolicy } }; } // Setup Anti-Suite View case SET_ANTI_TRACKING: { const { enable_anti_tracking } = action.data; - return Object.assign({}, state, { - setup: Object.assign({}, state.setup, { enable_anti_tracking }), - }); + return { ...state, setup: { ...state.setup, enable_anti_tracking } }; } case SET_AD_BLOCK: { const { enable_ad_block } = action.data; - return Object.assign({}, state, { - setup: Object.assign({}, state.setup, { enable_ad_block }), - }); + return { ...state, setup: { ...state.setup, enable_ad_block } }; } case SET_SMART_BLOCK: { const { enable_smart_block } = action.data; - return Object.assign({}, state, { - setup: Object.assign({}, state.setup, { enable_smart_block }), - }); + return { ...state, setup: { ...state.setup, enable_smart_block } }; } case SET_GHOSTERY_REWARDS: { const { enable_ghostery_rewards } = action.data; - return Object.assign({}, state, { - setup: Object.assign({}, state.setup, { enable_ghostery_rewards }), - }); + return { ...state, setup: { ...state.setup, enable_ghostery_rewards } }; } // Setup Human Web View case SET_HUMAN_WEB: { const { enable_human_web } = action.data; - return Object.assign({}, state, { - setup: Object.assign({}, state.setup, { enable_human_web }), - }); + return { ...state, setup: { ...state.setup, enable_human_web } }; } default: return state; diff --git a/app/hub/Views/SetupView/index.js b/app/hub/Views/SetupView/index.js index ab86ba273..5bd10681d 100644 --- a/app/hub/Views/SetupView/index.js +++ b/app/hub/Views/SetupView/index.js @@ -18,15 +18,15 @@ import { withRouter } from 'react-router-dom'; import SetupViewContainer from './SetupViewContainer'; import SetupViewReducer from './SetupViewReducer'; import * as SetupViewActions from './SetupViewActions'; -import { setBlockingPolicy } from '../SetupViews/SetupBlockingView/SetupBlockingViewActions'; +import setBlockingPolicy from '../SetupViews/SetupBlockingView/SetupBlockingViewActions'; import { setAntiTracking, setAdBlock, setSmartBlocking, setGhosteryRewards } from '../SetupViews/SetupAntiSuiteView/SetupAntiSuiteViewActions'; -import { setHumanWeb } from '../SetupViews/SetupHumanWebView/SetupHumanWebViewActions'; -import { setSetupComplete } from '../SetupViews/SetupDoneView/SetupDoneViewActions'; +import setHumanWeb from '../SetupViews/SetupHumanWebView/SetupHumanWebViewActions'; +import setSetupComplete from '../SetupViews/SetupDoneView/SetupDoneViewActions'; /** * Map redux store state properties to the component's own properties. @@ -34,7 +34,7 @@ import { setSetupComplete } from '../SetupViews/SetupDoneView/SetupDoneViewActio * @return {function} this function returns a plain object, which will be merged into the component's props * @memberof HubContainers */ -const mapStateToProps = state => Object.assign({}, state.setup, state.account); +const mapStateToProps = state => ({ ...state.setup, ...state.account }); /** * Bind the component's action creators using Redux's bindActionCreators. @@ -43,15 +43,16 @@ const mapStateToProps = state => Object.assign({}, state.setup, state.account); * @memberof SetupContainers */ const mapDispatchToProps = dispatch => ({ - actions: bindActionCreators(Object.assign({}, SetupViewActions, { + actions: bindActionCreators({ + ...SetupViewActions, setBlockingPolicy, setAntiTracking, setAdBlock, setSmartBlocking, setGhosteryRewards, setHumanWeb, - setSetupComplete, - }), dispatch), + setSetupComplete + }, dispatch), }); export const reducer = SetupViewReducer; diff --git a/app/hub/Views/SetupViews/SetupAntiSuiteView/SetupAntiSuiteView.jsx b/app/hub/Views/SetupViews/SetupAntiSuiteView/SetupAntiSuiteView.jsx index 530d74dff..8143950d2 100644 --- a/app/hub/Views/SetupViews/SetupAntiSuiteView/SetupAntiSuiteView.jsx +++ b/app/hub/Views/SetupViews/SetupAntiSuiteView/SetupAntiSuiteView.jsx @@ -21,10 +21,10 @@ import { ToggleSwitch } from '../../../../shared-components'; * @return {JSX} JSX for rendering the Setup Anti-Suite View of the Hub app * @memberof HubComponents */ -const SetupAntiSuiteView = props => ( +const SetupAntiSuiteView = ({ features }) => (
- {props.features.map((feature) => { + {features.map((feature) => { const iconClassNames = ClassNames(feature.id, { SetupAntiSuite__icon: true, active: feature.enabled, diff --git a/app/hub/Views/SetupViews/SetupAntiSuiteView/SetupAntiSuiteViewContainer.jsx b/app/hub/Views/SetupViews/SetupAntiSuiteView/SetupAntiSuiteViewContainer.jsx index b4c25379b..f0ed52027 100644 --- a/app/hub/Views/SetupViews/SetupAntiSuiteView/SetupAntiSuiteViewContainer.jsx +++ b/app/hub/Views/SetupViews/SetupAntiSuiteView/SetupAntiSuiteViewContainer.jsx @@ -62,25 +62,26 @@ class SetupAntiSuiteViewContainer extends Component { * @param {Object} featureName the name of the feature being toggled */ _handleToggle = (featureName) => { + const { actions, setup } = this.props; switch (featureName) { case 'anti-tracking': { - const enable_anti_tracking = !this.props.setup.enable_anti_tracking; - this.props.actions.setAntiTracking({ enable_anti_tracking }); + const enable_anti_tracking = !setup.enable_anti_tracking; + actions.setAntiTracking({ enable_anti_tracking }); break; } case 'ad-block': { - const enable_ad_block = !this.props.setup.enable_ad_block; - this.props.actions.setAdBlock({ enable_ad_block }); + const enable_ad_block = !setup.enable_ad_block; + actions.setAdBlock({ enable_ad_block }); break; } case 'smart-blocking': { - const enable_smart_block = !this.props.setup.enable_smart_block; - this.props.actions.setSmartBlocking({ enable_smart_block }); + const enable_smart_block = !setup.enable_smart_block; + actions.setSmartBlocking({ enable_smart_block }); break; } case 'ghostery-rewards': { - const enable_ghostery_rewards = !this.props.setup.enable_ghostery_rewards; - this.props.actions.setGhosteryRewards({ enable_ghostery_rewards }); + const enable_ghostery_rewards = !setup.enable_ghostery_rewards; + actions.setGhosteryRewards({ enable_ghostery_rewards }); break; } default: break; @@ -92,12 +93,13 @@ class SetupAntiSuiteViewContainer extends Component { * @return {JSX} JSX for rendering the Setup Anti-Suite View of the Hub app */ render() { + const { setup } = this.props; const { enable_anti_tracking, enable_ad_block, enable_smart_block, enable_ghostery_rewards, - } = this.props.setup; + } = setup; const anti_tracking_enabled = IS_CLIQZ ? false : enable_anti_tracking; const ad_block_enabled = IS_CLIQZ ? false : enable_ad_block; diff --git a/app/hub/Views/SetupViews/SetupAntiSuiteView/index.js b/app/hub/Views/SetupViews/SetupAntiSuiteView/index.js index d07fd0ecc..9d5dfcf5d 100644 --- a/app/hub/Views/SetupViews/SetupAntiSuiteView/index.js +++ b/app/hub/Views/SetupViews/SetupAntiSuiteView/index.js @@ -24,7 +24,7 @@ import { setSetupStep, setSetupNavigation } from '../../SetupView/SetupViewActio * @return {function} this function returns a plain object, which will be merged into the component's props * @memberof HubContainers */ -const mapStateToProps = state => Object.assign({}, state.setup); +const mapStateToProps = state => ({ ...state.setup }); /** * Bind the component's action creators using Redux's bindActionCreators. @@ -33,10 +33,11 @@ const mapStateToProps = state => Object.assign({}, state.setup); * @memberof SetupContainers */ const mapDispatchToProps = dispatch => ({ - actions: bindActionCreators(Object.assign({}, SetupAntiSuiteViewActions, { + actions: bindActionCreators({ + ...SetupAntiSuiteViewActions, setSetupStep, - setSetupNavigation, - }), dispatch), + setSetupNavigation + }, dispatch), }); export default connect(mapStateToProps, mapDispatchToProps)(SetupAntiSuiteViewContainer); diff --git a/app/hub/Views/SetupViews/SetupBlockingDropdown/SetupBlockingDropdown.jsx b/app/hub/Views/SetupViews/SetupBlockingDropdown/SetupBlockingDropdown.jsx index 1944171e1..3b352e432 100644 --- a/app/hub/Views/SetupViews/SetupBlockingDropdown/SetupBlockingDropdown.jsx +++ b/app/hub/Views/SetupViews/SetupBlockingDropdown/SetupBlockingDropdown.jsx @@ -23,6 +23,11 @@ import { ToastMessage } from '../../../../shared-components'; * @memberof HubComponents */ class SetupBlockingDropdown extends Component { + /** + * Debounce the hide alert function after 3 seconds + */ + _hideToastDebounce = debounce(this._hideToast, 3000) + constructor(props) { super(props); this.state = { @@ -59,11 +64,6 @@ class SetupBlockingDropdown extends Component { }); } - /** - * Debounce the hide alert function after 3 seconds - */ - _hideToastDebounce = debounce(this._hideToast, 3000) // eslint-disable-line react/sort-comp - /** * React's required render function. Returns JSX * @return {JSX} JSX for rendering the Blocking Dropdown Component diff --git a/app/hub/Views/SetupViews/SetupBlockingDropdown/SetupBlockingDropdownContainer.jsx b/app/hub/Views/SetupViews/SetupBlockingDropdown/SetupBlockingDropdownContainer.jsx index 3da70ea20..16424cceb 100644 --- a/app/hub/Views/SetupViews/SetupBlockingDropdown/SetupBlockingDropdownContainer.jsx +++ b/app/hub/Views/SetupViews/SetupBlockingDropdown/SetupBlockingDropdownContainer.jsx @@ -35,7 +35,8 @@ class SetupBlockingDropdownContainer extends Component { * Function to handle navigating back to the Blocking route */ _closeModal = () => { - this.props.history.push('/setup/1'); + const { history } = this.props; + history.push('/setup/1'); } /** @@ -43,9 +44,10 @@ class SetupBlockingDropdownContainer extends Component { * @return {JSX} JSX for rendering the Blocking Dropdown */ render() { + const { actions } = this.props; return ( - + ); } diff --git a/app/hub/Views/SetupViews/SetupBlockingDropdown/index.js b/app/hub/Views/SetupViews/SetupBlockingDropdown/index.js index 3eedd4039..2c9066551 100644 --- a/app/hub/Views/SetupViews/SetupBlockingDropdown/index.js +++ b/app/hub/Views/SetupViews/SetupBlockingDropdown/index.js @@ -24,7 +24,7 @@ import * as SettingsActions from '../../../../panel/actions/SettingsActions'; * @return {function} this function returns a plain object, which will be merged into the component's props * @memberof HubContainers */ -const mapStateToProps = state => Object.assign({}, state.settings); +const mapStateToProps = state => ({ ...state.settings }); /** * Bind the component's action creators using Redux's bindActionCreators. @@ -33,7 +33,7 @@ const mapStateToProps = state => Object.assign({}, state.settings); * @memberof SetupContainers */ const mapDispatchToProps = dispatch => ({ - actions: bindActionCreators(Object.assign({}, SettingsActions), dispatch), + actions: bindActionCreators({ ...SettingsActions }, dispatch), }); export default withRouter(connect(mapStateToProps, mapDispatchToProps)(SetupBlockingDropdownContainer)); diff --git a/app/hub/Views/SetupViews/SetupBlockingView/SetupBlockingView.jsx b/app/hub/Views/SetupViews/SetupBlockingView/SetupBlockingView.jsx index 073c6d3d8..5a9e2000e 100644 --- a/app/hub/Views/SetupViews/SetupBlockingView/SetupBlockingView.jsx +++ b/app/hub/Views/SetupViews/SetupBlockingView/SetupBlockingView.jsx @@ -20,13 +20,18 @@ import ClassNames from 'classnames'; * @return {JSX} JSX for rendering the Setup Blocking View of the Hub app * @memberof HubComponents */ -const SetupBlockingView = props => ( +const SetupBlockingView = ({ + blockingPolicy, + handleSelection, + handleCustomClick, + choices +}) => (
- {props.choices.map((choice) => { - const choiceSelected = choice.name === props.blockingPolicy; + {choices.map((choice) => { + const choiceSelected = choice.name === blockingPolicy; const bigCheckSrc = '/app/images/hub/setup/block-selected.svg'; const choiceBoxClassNames = ClassNames('clickable', 'flex-container', 'flex-dir-column', { SetupBlocking__choiceBox: true, @@ -41,7 +46,7 @@ const SetupBlockingView = props => ( className={choiceBoxClassNames} onClick={() => { if (choice.name === 'BLOCKING_POLICY_CUSTOM') { - props.handleCustomClick(); + handleCustomClick(); } }} > @@ -60,8 +65,8 @@ const SetupBlockingView = props => ( name={choice.name} value={choice.name} id={`input-block-${choice.name}`} - checked={props.blockingPolicy === choice.name} - onChange={props.handleSelection} + checked={blockingPolicy === choice.name} + onChange={handleSelection} />
); @@ -76,6 +81,7 @@ const SetupBlockingView = props => ( SetupBlockingView.propTypes = { blockingPolicy: PropTypes.string.isRequired, handleSelection: PropTypes.func.isRequired, + handleCustomClick: PropTypes.func.isRequired, choices: PropTypes.arrayOf(PropTypes.shape({ name: PropTypes.string.isRequired, image: PropTypes.string.isRequired, diff --git a/app/hub/Views/SetupViews/SetupBlockingView/SetupBlockingViewActions.js b/app/hub/Views/SetupViews/SetupBlockingView/SetupBlockingViewActions.js index ce9eb31b9..de4b436ed 100644 --- a/app/hub/Views/SetupViews/SetupBlockingView/SetupBlockingViewActions.js +++ b/app/hub/Views/SetupViews/SetupBlockingView/SetupBlockingViewActions.js @@ -14,7 +14,7 @@ import { log, sendMessageInPromise } from '../../../utils'; import { SET_BLOCKING_POLICY } from '../../SetupView/SetupViewConstants'; -export function setBlockingPolicy(actionData) { +export default function setBlockingPolicy(actionData) { return function(dispatch) { return sendMessageInPromise(SET_BLOCKING_POLICY, actionData).then((data) => { dispatch({ diff --git a/app/hub/Views/SetupViews/SetupBlockingView/SetupBlockingViewContainer.jsx b/app/hub/Views/SetupViews/SetupBlockingView/SetupBlockingViewContainer.jsx index e1b7ac71c..b50fa624f 100644 --- a/app/hub/Views/SetupViews/SetupBlockingView/SetupBlockingViewContainer.jsx +++ b/app/hub/Views/SetupViews/SetupBlockingView/SetupBlockingViewContainer.jsx @@ -57,14 +57,16 @@ class SetupBlockingViewContainer extends Component { */ _handleChange = (event) => { const blockingPolicy = event.target.value; - this.props.actions.setBlockingPolicy({ blockingPolicy }); + const { actions } = this.props; + actions.setBlockingPolicy({ blockingPolicy }); } /** * Function to handle switching to the Custom Blocking route */ _handleCustomClick = () => { - this.props.history.push('/setup/1/custom'); + const { history } = this.props; + history.push('/setup/1/custom'); } /** @@ -72,7 +74,8 @@ class SetupBlockingViewContainer extends Component { * @return {JSX} JSX for rendering the Setup Blocking View of the Hub app */ render() { - const { blockingPolicy } = this.props.setup; + const { setup } = this.props; + const { blockingPolicy } = setup; const choices = [ { name: BLOCKING_POLICY_RECOMMENDED, diff --git a/app/hub/Views/SetupViews/SetupBlockingView/__tests__/SetupBlockingView.test.jsx b/app/hub/Views/SetupViews/SetupBlockingView/__tests__/SetupBlockingView.test.jsx index ae581b658..fa76c3e6f 100644 --- a/app/hub/Views/SetupViews/SetupBlockingView/__tests__/SetupBlockingView.test.jsx +++ b/app/hub/Views/SetupViews/SetupBlockingView/__tests__/SetupBlockingView.test.jsx @@ -36,6 +36,7 @@ describe('app/hub/Views/SetupViews/SetupBlockingView component', () => { }, ], handleSelection: () => {}, + handleCustomClick: () => {}, }; const component = renderer.create( @@ -51,6 +52,7 @@ describe('app/hub/Views/SetupViews/SetupBlockingView component', () => { blockingPolicy: 'test', choices: [], handleSelection: () => {}, + handleCustomClick: () => {}, }; const component = renderer.create( @@ -79,6 +81,7 @@ describe('app/hub/Views/SetupViews/SetupBlockingView component', () => { }, ], handleSelection: () => {}, + handleCustomClick: () => {}, }; const component = shallow(); @@ -94,6 +97,7 @@ describe('app/hub/Views/SetupViews/SetupBlockingView component', () => { blockingPolicy: 'test', choices: [], handleSelection: () => {}, + handleCustomClick: () => {}, }; const component = shallow(); diff --git a/app/hub/Views/SetupViews/SetupBlockingView/__tests__/SetupBlockingViewActions.test.js b/app/hub/Views/SetupViews/SetupBlockingView/__tests__/SetupBlockingViewActions.test.js index 23504c3db..cfa80c6f0 100644 --- a/app/hub/Views/SetupViews/SetupBlockingView/__tests__/SetupBlockingViewActions.test.js +++ b/app/hub/Views/SetupViews/SetupBlockingView/__tests__/SetupBlockingViewActions.test.js @@ -14,7 +14,7 @@ import configureStore from 'redux-mock-store'; import thunk from 'redux-thunk'; import * as utils from '../../../../utils'; -import * as SetupBlockingViewActions from '../SetupBlockingViewActions'; +import setBlockingPolicy from '../SetupBlockingViewActions'; import { SET_BLOCKING_POLICY } from '../../../SetupView/SetupViewConstants'; const middlewares = [thunk]; @@ -39,7 +39,7 @@ describe('app/hub/Views/SetupViews/SetupBlockingView actions', () => { const data = testData; const expectedPayload = { data, type: SET_BLOCKING_POLICY }; - return store.dispatch(SetupBlockingViewActions.setBlockingPolicy(data)).then(() => { + return store.dispatch(setBlockingPolicy(data)).then(() => { const actions = store.getActions(); expect(actions).toEqual([expectedPayload]); }); diff --git a/app/hub/Views/SetupViews/SetupBlockingView/index.js b/app/hub/Views/SetupViews/SetupBlockingView/index.js index 2c4e76a68..383bda7ff 100644 --- a/app/hub/Views/SetupViews/SetupBlockingView/index.js +++ b/app/hub/Views/SetupViews/SetupBlockingView/index.js @@ -16,7 +16,7 @@ import { bindActionCreators } from 'redux'; import { withRouter } from 'react-router-dom'; import SetupBlockingViewContainer from './SetupBlockingViewContainer'; -import * as SetupBlockingViewActions from './SetupBlockingViewActions'; +import setBlockingPolicy from './SetupBlockingViewActions'; import { setSetupStep, setSetupNavigation } from '../../SetupView/SetupViewActions'; /** @@ -25,7 +25,7 @@ import { setSetupStep, setSetupNavigation } from '../../SetupView/SetupViewActio * @return {function} this function returns a plain object, which will be merged into the component's props * @memberof HubContainers */ -const mapStateToProps = state => Object.assign({}, state.setup); +const mapStateToProps = state => ({ ...state.setup }); /** * Bind the component's action creators using Redux's bindActionCreators. @@ -34,10 +34,11 @@ const mapStateToProps = state => Object.assign({}, state.setup); * @memberof SetupContainers */ const mapDispatchToProps = dispatch => ({ - actions: bindActionCreators(Object.assign({}, SetupBlockingViewActions, { + actions: bindActionCreators({ + setBlockingPolicy, setSetupStep, - setSetupNavigation, - }), dispatch), + setSetupNavigation + }, dispatch), }); export default withRouter(connect(mapStateToProps, mapDispatchToProps)(SetupBlockingViewContainer)); diff --git a/app/hub/Views/SetupViews/SetupDoneView/SetupDoneView.jsx b/app/hub/Views/SetupViews/SetupDoneView/SetupDoneView.jsx index 062edaf23..ca29cded4 100644 --- a/app/hub/Views/SetupViews/SetupDoneView/SetupDoneView.jsx +++ b/app/hub/Views/SetupViews/SetupDoneView/SetupDoneView.jsx @@ -20,7 +20,7 @@ import { NavLink } from 'react-router-dom'; * @return {JSX} JSX for rendering the Setup Done View of the Hub app * @memberof HubComponents */ -const SetupDoneView = props => ( +const SetupDoneView = ({ features }) => (
@@ -33,7 +33,7 @@ const SetupDoneView = props => (
- {props.features.map((feature) => { + {features.map((feature) => { const iconClassNames = `SetupDone__featureIcon feature-${feature.id}`; return ( diff --git a/app/hub/Views/SetupViews/SetupDoneView/SetupDoneViewActions.js b/app/hub/Views/SetupViews/SetupDoneView/SetupDoneViewActions.js index 10ce3e7b4..8c11c0d6e 100644 --- a/app/hub/Views/SetupViews/SetupDoneView/SetupDoneViewActions.js +++ b/app/hub/Views/SetupViews/SetupDoneView/SetupDoneViewActions.js @@ -14,7 +14,7 @@ import { log, sendMessageInPromise } from '../../../utils'; import { SET_SETUP_COMPLETE } from '../../SetupView/SetupViewConstants'; -export function setSetupComplete(actionData) { +export default function setSetupComplete(actionData) { return function(dispatch) { return sendMessageInPromise(SET_SETUP_COMPLETE, actionData).then((data) => { dispatch({ diff --git a/app/hub/Views/SetupViews/SetupDoneView/__tests__/SetupDoneViewActions.test.js b/app/hub/Views/SetupViews/SetupDoneView/__tests__/SetupDoneViewActions.test.js index 5c66ecd65..1e8a99a74 100644 --- a/app/hub/Views/SetupViews/SetupDoneView/__tests__/SetupDoneViewActions.test.js +++ b/app/hub/Views/SetupViews/SetupDoneView/__tests__/SetupDoneViewActions.test.js @@ -14,7 +14,7 @@ import configureStore from 'redux-mock-store'; import thunk from 'redux-thunk'; import * as utils from '../../../../utils'; -import * as SetupDoneViewActions from '../SetupDoneViewActions'; +import setSetupComplete from '../SetupDoneViewActions'; import { SET_SETUP_COMPLETE } from '../../../SetupView/SetupViewConstants'; const middlewares = [thunk]; @@ -39,7 +39,7 @@ describe('app/hub/Views/SetupViews/SetupDoneView actions', () => { const data = testData; const expectedPayload = { data, type: SET_SETUP_COMPLETE }; - return store.dispatch(SetupDoneViewActions.setSetupComplete(data)).then(() => { + return store.dispatch(setSetupComplete(data)).then(() => { const actions = store.getActions(); expect(actions).toEqual([expectedPayload]); }); diff --git a/app/hub/Views/SetupViews/SetupDoneView/index.js b/app/hub/Views/SetupViews/SetupDoneView/index.js index bcce6c53d..47199b305 100644 --- a/app/hub/Views/SetupViews/SetupDoneView/index.js +++ b/app/hub/Views/SetupViews/SetupDoneView/index.js @@ -15,7 +15,7 @@ import { connect } from 'react-redux'; import { bindActionCreators } from 'redux'; import SetupDoneViewContainer from './SetupDoneViewContainer'; -import * as SetupDoneViewActions from './SetupDoneViewActions'; +import setSetupComplete from './SetupDoneViewActions'; import { setSetupStep, setSetupNavigation } from '../../SetupView/SetupViewActions'; /** @@ -24,7 +24,7 @@ import { setSetupStep, setSetupNavigation } from '../../SetupView/SetupViewActio * @return {function} this function returns a plain object, which will be merged into the component's props * @memberof HubContainers */ -const mapStateToProps = state => Object.assign({}, state.setup); +const mapStateToProps = state => ({ ...state.setup }); /** * Bind the component's action creators using Redux's bindActionCreators. @@ -33,10 +33,11 @@ const mapStateToProps = state => Object.assign({}, state.setup); * @memberof SetupContainers */ const mapDispatchToProps = dispatch => ({ - actions: bindActionCreators(Object.assign({}, SetupDoneViewActions, { + actions: bindActionCreators({ + setSetupComplete, setSetupStep, - setSetupNavigation, - }), dispatch), + setSetupNavigation + }, dispatch), }); export default connect(mapStateToProps, mapDispatchToProps)(SetupDoneViewContainer); diff --git a/app/hub/Views/SetupViews/SetupHeader/SetupHeader.jsx b/app/hub/Views/SetupViews/SetupHeader/SetupHeader.jsx index 97f5c2984..02738b5da 100644 --- a/app/hub/Views/SetupViews/SetupHeader/SetupHeader.jsx +++ b/app/hub/Views/SetupViews/SetupHeader/SetupHeader.jsx @@ -19,13 +19,13 @@ import PropTypes from 'prop-types'; * @return {JSX} JSX for rendering the Setup Header View of the Hub app * @memberof HubComponents */ -const SetupHeader = props => ( +const SetupHeader = ({ title, titleImage }) => (
- +
-

+

diff --git a/app/hub/Views/SetupViews/SetupHumanWebView/SetupHumanWebView.jsx b/app/hub/Views/SetupViews/SetupHumanWebView/SetupHumanWebView.jsx index fee183740..700ce3f04 100644 --- a/app/hub/Views/SetupViews/SetupHumanWebView/SetupHumanWebView.jsx +++ b/app/hub/Views/SetupViews/SetupHumanWebView/SetupHumanWebView.jsx @@ -20,17 +20,17 @@ import { ToggleCheckbox } from '../../../../shared-components'; * @return {JSX} JSX for rendering the Setup Human Web View of the Hub app * @memberof HubComponents */ -const SetupHumanWebView = props => ( +const SetupHumanWebView = ({ enableHumanWeb, changeHumanWeb }) => (
- + { t('hub_setup_humanweb_label') }
diff --git a/app/hub/Views/SetupViews/SetupHumanWebView/SetupHumanWebViewActions.js b/app/hub/Views/SetupViews/SetupHumanWebView/SetupHumanWebViewActions.js index 16cf28b1a..b18500b8a 100644 --- a/app/hub/Views/SetupViews/SetupHumanWebView/SetupHumanWebViewActions.js +++ b/app/hub/Views/SetupViews/SetupHumanWebView/SetupHumanWebViewActions.js @@ -14,7 +14,7 @@ import { log, sendMessageInPromise } from '../../../utils'; import { SET_HUMAN_WEB } from '../../SetupView/SetupViewConstants'; -export function setHumanWeb(actionData) { +export default function setHumanWeb(actionData) { return function(dispatch) { return sendMessageInPromise(SET_HUMAN_WEB, actionData).then((data) => { dispatch({ diff --git a/app/hub/Views/SetupViews/SetupHumanWebView/SetupHumanWebViewContainer.jsx b/app/hub/Views/SetupViews/SetupHumanWebView/SetupHumanWebViewContainer.jsx index 3e6415082..9657fc595 100644 --- a/app/hub/Views/SetupViews/SetupHumanWebView/SetupHumanWebViewContainer.jsx +++ b/app/hub/Views/SetupViews/SetupHumanWebView/SetupHumanWebViewContainer.jsx @@ -49,8 +49,9 @@ class SetupHumanWebViewContainer extends Component { * Function to handle toggling Human Web Opt-In */ _handleToggle = () => { - const enable_human_web = !this.props.setup.enable_human_web; - this.props.actions.setHumanWeb({ enable_human_web }); + const { actions, setup } = this.props; + const enable_human_web = !setup.enable_human_web; + actions.setHumanWeb({ enable_human_web }); } /** @@ -58,11 +59,13 @@ class SetupHumanWebViewContainer extends Component { * @return {JSX} JSX for rendering the Setup Human Web View of the Hub app */ render() { - const childProps = { - enableHumanWeb: this.props.setup.enable_human_web, - changeHumanWeb: this._handleToggle, - }; - return ; + const { setup } = this.props; + return ( + + ); } } diff --git a/app/hub/Views/SetupViews/SetupHumanWebView/__tests__/SetupHumanWebViewActions.test.js b/app/hub/Views/SetupViews/SetupHumanWebView/__tests__/SetupHumanWebViewActions.test.js index e00a40c89..3b21c84be 100644 --- a/app/hub/Views/SetupViews/SetupHumanWebView/__tests__/SetupHumanWebViewActions.test.js +++ b/app/hub/Views/SetupViews/SetupHumanWebView/__tests__/SetupHumanWebViewActions.test.js @@ -14,7 +14,7 @@ import configureStore from 'redux-mock-store'; import thunk from 'redux-thunk'; import * as utils from '../../../../utils'; -import * as SetupHumanWebViewActions from '../SetupHumanWebViewActions'; +import setHumanWeb from '../SetupHumanWebViewActions'; import { SET_HUMAN_WEB } from '../../../SetupView/SetupViewConstants'; const middlewares = [thunk]; @@ -39,7 +39,7 @@ describe('app/hub/Views/SetupViews/SetupHumanWebView actions', () => { const data = testData; const expectedPayload = { data, type: SET_HUMAN_WEB }; - return store.dispatch(SetupHumanWebViewActions.setHumanWeb(data)).then(() => { + return store.dispatch(setHumanWeb(data)).then(() => { const actions = store.getActions(); expect(actions).toEqual([expectedPayload]); }); diff --git a/app/hub/Views/SetupViews/SetupHumanWebView/index.js b/app/hub/Views/SetupViews/SetupHumanWebView/index.js index 9b207c564..745d9904e 100644 --- a/app/hub/Views/SetupViews/SetupHumanWebView/index.js +++ b/app/hub/Views/SetupViews/SetupHumanWebView/index.js @@ -15,7 +15,7 @@ import { connect } from 'react-redux'; import { bindActionCreators } from 'redux'; import SetupHumanWebViewContainer from './SetupHumanWebViewContainer'; -import * as SetupHumanWebViewActions from './SetupHumanWebViewActions'; +import setHumanWeb from './SetupHumanWebViewActions'; import { setSetupStep, setSetupNavigation } from '../../SetupView/SetupViewActions'; /** @@ -24,7 +24,7 @@ import { setSetupStep, setSetupNavigation } from '../../SetupView/SetupViewActio * @return {function} this function returns a plain object, which will be merged into the component's props * @memberof HubContainers */ -const mapStateToProps = state => Object.assign({}, state.setup); +const mapStateToProps = state => ({ ...state.setup }); /** * Bind the component's action creators using Redux's bindActionCreators. @@ -33,10 +33,11 @@ const mapStateToProps = state => Object.assign({}, state.setup); * @memberof SetupContainers */ const mapDispatchToProps = dispatch => ({ - actions: bindActionCreators(Object.assign({}, SetupHumanWebViewActions, { + actions: bindActionCreators({ + setHumanWeb, setSetupStep, setSetupNavigation - }), dispatch), + }, dispatch), }); export default connect(mapStateToProps, mapDispatchToProps)(SetupHumanWebViewContainer); diff --git a/app/hub/Views/SetupViews/SetupNavigation/SetupNavigationContainer.jsx b/app/hub/Views/SetupViews/SetupNavigation/SetupNavigationContainer.jsx index 3a55f163a..072ba9d07 100644 --- a/app/hub/Views/SetupViews/SetupNavigation/SetupNavigationContainer.jsx +++ b/app/hub/Views/SetupViews/SetupNavigation/SetupNavigationContainer.jsx @@ -22,12 +22,19 @@ import { SteppedNavigation } from '../../../../shared-components'; */ const SetupNavigationContainer = (props) => { const { totalSteps, setup } = props; - const childProps = { - totalSteps, - ...setup.navigation, - }; - return ; + return ( + + ); }; // PropTypes ensure we pass required props of the correct type diff --git a/app/hub/Views/SetupViews/SetupNavigation/index.js b/app/hub/Views/SetupViews/SetupNavigation/index.js index 9f40ac618..cc9ae5f59 100644 --- a/app/hub/Views/SetupViews/SetupNavigation/index.js +++ b/app/hub/Views/SetupViews/SetupNavigation/index.js @@ -20,6 +20,6 @@ import SetupNavigationContainer from './SetupNavigationContainer'; * @return {function} this function returns a plain object, which will be merged into the component's props * @memberof HubContainers */ -const mapStateToProps = state => Object.assign({}, state.setup); +const mapStateToProps = state => ({ ...state.setup }); export default connect(mapStateToProps)(SetupNavigationContainer); diff --git a/app/hub/Views/SideNavigationView/SideNavigationViewContainer.jsx b/app/hub/Views/SideNavigationView/SideNavigationViewContainer.jsx index 1388a5ea7..77492fdcf 100644 --- a/app/hub/Views/SideNavigationView/SideNavigationViewContainer.jsx +++ b/app/hub/Views/SideNavigationView/SideNavigationViewContainer.jsx @@ -33,11 +33,12 @@ class SideNavigationViewContainer extends Component { * Function to handle clicking Log Out */ _handleLogoutClick = () => { - this.props.actions.setToast({ + const { actions } = this.props; + actions.setToast({ toastMessage: '', toastClass: '', }); - this.props.actions.logout(); + actions.logout(); } /** @@ -68,13 +69,14 @@ class SideNavigationViewContainer extends Component { icon: 'profile', }, ]; - const childProps = { - menuItems, - bottomItems, - disableNav: disableRegEx.test(location.pathname), - }; - return ; + return ( + + ); } } diff --git a/app/hub/Views/SideNavigationView/index.js b/app/hub/Views/SideNavigationView/index.js index adf9d60dc..da287bf7d 100644 --- a/app/hub/Views/SideNavigationView/index.js +++ b/app/hub/Views/SideNavigationView/index.js @@ -25,7 +25,7 @@ import { setToast } from '../AppView/AppViewActions'; * @return {function} this function returns a plain object, which will be merged into the component's props * @memberof HubContainers */ -const mapStateToProps = state => Object.assign({}, state.account); +const mapStateToProps = state => ({ ...state.account }); /** * Bind the component's action creators using Redux's bindActionCreators. @@ -34,11 +34,11 @@ const mapStateToProps = state => Object.assign({}, state.account); * @memberof SetupContainers */ const mapDispatchToProps = dispatch => ({ - actions: bindActionCreators(Object.assign({}, { + actions: bindActionCreators({ setToast, getUser, - logout, - }), dispatch), + logout + }, dispatch), }); export default withRouter(connect(mapStateToProps, mapDispatchToProps)(SideNavigationViewContainer)); diff --git a/app/hub/Views/SignedInView/SignedInView.jsx b/app/hub/Views/SignedInView/SignedInView.jsx index a1057d938..22dc1c4aa 100644 --- a/app/hub/Views/SignedInView/SignedInView.jsx +++ b/app/hub/Views/SignedInView/SignedInView.jsx @@ -20,7 +20,7 @@ import { ExitButton } from '../../../shared-components'; * @return {JSX} JSX for rendering the Login View of the Hub app * @memberof HubComponents */ -const SignedInView = (props) => { +const SignedInView = ({ email }) => { const signedInAsString = t('hub_signedin_as_email'); return ( @@ -41,7 +41,7 @@ const SignedInView = (props) => {

- {`${signedInAsString} ${props.email}`} + {`${signedInAsString} ${email}`}

diff --git a/app/hub/Views/TutorialView/TutorialViewContainer.jsx b/app/hub/Views/TutorialView/TutorialViewContainer.jsx index 97af3c48c..b60f30ab2 100644 --- a/app/hub/Views/TutorialView/TutorialViewContainer.jsx +++ b/app/hub/Views/TutorialView/TutorialViewContainer.jsx @@ -35,16 +35,17 @@ class TutorialViewContainer extends Component { sendMountActions: false, }; + const { actions, history, tutorial } = this.props; if (!props.preventRedirect) { - this.props.history.push('/tutorial/1'); + history.push('/tutorial/1'); } const title = t('hub_tutorial_page_title'); window.document.title = title; - this.props.actions.initTutorialProps(this.props.tutorial).then(() => { + actions.initTutorialProps(tutorial).then(() => { this.setState({ sendMountActions: true }); - this.props.actions.sendPing({ type: 'tutorial_start' }); + actions.sendPing({ type: 'tutorial_start' }); }); } diff --git a/app/hub/Views/TutorialView/TutorialViewReducer.js b/app/hub/Views/TutorialView/TutorialViewReducer.js index 3a4fc9016..cbbf8bed1 100644 --- a/app/hub/Views/TutorialView/TutorialViewReducer.js +++ b/app/hub/Views/TutorialView/TutorialViewReducer.js @@ -27,7 +27,8 @@ function TutorialViewReducer(state = initialState, action) { textNext, textDone, } = action.data.navigation; - return Object.assign({}, state, { + return { + ...state, tutorial: { navigation: { activeIndex, @@ -38,8 +39,8 @@ function TutorialViewReducer(state = initialState, action) { textNext, textDone, } - }, - }); + } + }; } case SET_TUTORIAL_NAVIGATION: { const { @@ -51,8 +52,10 @@ function TutorialViewReducer(state = initialState, action) { textNext, textDone, } = action.data; - return Object.assign({}, state, { - tutorial: Object.assign({}, state.tutorial, { + return { + ...state, + tutorial: { + ...state.tutorial, navigation: { activeIndex, hrefPrev, @@ -61,9 +64,9 @@ function TutorialViewReducer(state = initialState, action) { textPrev, textNext, textDone, - }, - }), - }); + } + } + }; } default: return state; diff --git a/app/hub/Views/TutorialView/index.js b/app/hub/Views/TutorialView/index.js index f9c1a0157..1b2d90d3b 100644 --- a/app/hub/Views/TutorialView/index.js +++ b/app/hub/Views/TutorialView/index.js @@ -26,7 +26,7 @@ import { sendPing } from '../AppView/AppViewActions'; * @return {function} this function returns a plain object, which will be merged into the component's props * @memberof HubContainers */ -const mapStateToProps = state => Object.assign({}, state.tutorial); +const mapStateToProps = state => ({ ...state.tutorial }); /** * Bind the component's action creators using Redux's bindActionCreators. @@ -35,7 +35,7 @@ const mapStateToProps = state => Object.assign({}, state.tutorial); * @memberof SetupContainers */ const mapDispatchToProps = dispatch => ({ - actions: bindActionCreators(Object.assign({}, TutorialViewActions, { sendPing }), dispatch), + actions: bindActionCreators({ ...TutorialViewActions, sendPing }, dispatch), }); export const reducer = TutorialViewReducer; diff --git a/app/hub/Views/TutorialViews/TutorialAntiSuiteView/TutorialAntiSuiteViewActions.js b/app/hub/Views/TutorialViews/TutorialAntiSuiteView/TutorialAntiSuiteViewActions.js index 019754ba7..ddf87b787 100644 --- a/app/hub/Views/TutorialViews/TutorialAntiSuiteView/TutorialAntiSuiteViewActions.js +++ b/app/hub/Views/TutorialViews/TutorialAntiSuiteView/TutorialAntiSuiteViewActions.js @@ -14,7 +14,7 @@ import { log, sendMessageInPromise } from '../../../utils'; import { SET_TUTORIAL_COMPLETE } from '../../TutorialView/TutorialViewConstants'; -export function setTutorialComplete(actionData) { +export default function setTutorialComplete(actionData) { return function(dispatch) { return sendMessageInPromise(SET_TUTORIAL_COMPLETE, actionData).then((data) => { dispatch({ diff --git a/app/hub/Views/TutorialViews/TutorialAntiSuiteView/TutorialAntiSuiteViewContainer.jsx b/app/hub/Views/TutorialViews/TutorialAntiSuiteView/TutorialAntiSuiteViewContainer.jsx index a08f8708c..fccaca98e 100644 --- a/app/hub/Views/TutorialViews/TutorialAntiSuiteView/TutorialAntiSuiteViewContainer.jsx +++ b/app/hub/Views/TutorialViews/TutorialAntiSuiteView/TutorialAntiSuiteViewContainer.jsx @@ -39,7 +39,8 @@ class TutorialAntiSuiteViewContainer extends Component { }); if (sendMountActions) { - this.props.actions.setTutorialComplete({ + const { actions } = this.props; + actions.setTutorialComplete({ tutorial_complete: true, }); } diff --git a/app/hub/Views/TutorialViews/TutorialAntiSuiteView/__test__/TutorialAntiSuiteViewActions.test.js b/app/hub/Views/TutorialViews/TutorialAntiSuiteView/__test__/TutorialAntiSuiteViewActions.test.js index 7864a354a..d0866e007 100644 --- a/app/hub/Views/TutorialViews/TutorialAntiSuiteView/__test__/TutorialAntiSuiteViewActions.test.js +++ b/app/hub/Views/TutorialViews/TutorialAntiSuiteView/__test__/TutorialAntiSuiteViewActions.test.js @@ -14,7 +14,7 @@ import configureStore from 'redux-mock-store'; import thunk from 'redux-thunk'; import * as utils from '../../../../utils'; -import * as TutorialAntiSuiteViewActions from '../TutorialAntiSuiteViewActions'; +import setTutorialComplete from '../TutorialAntiSuiteViewActions'; import { SET_TUTORIAL_COMPLETE } from '../../../TutorialView/TutorialViewConstants'; const middlewares = [thunk]; @@ -39,7 +39,7 @@ describe('app/hub/Views/TutorialViews/TutorialAntiSuiteView actions', () => { const data = testData; const expectedPayload = { data, type: SET_TUTORIAL_COMPLETE }; - return store.dispatch(TutorialAntiSuiteViewActions.setTutorialComplete(data)).then(() => { + return store.dispatch(setTutorialComplete(data)).then(() => { const actions = store.getActions(); expect(actions).toEqual([expectedPayload]); }); diff --git a/app/hub/Views/TutorialViews/TutorialAntiSuiteView/index.js b/app/hub/Views/TutorialViews/TutorialAntiSuiteView/index.js index c0faf59dd..df5d858e3 100644 --- a/app/hub/Views/TutorialViews/TutorialAntiSuiteView/index.js +++ b/app/hub/Views/TutorialViews/TutorialAntiSuiteView/index.js @@ -15,7 +15,7 @@ import { connect } from 'react-redux'; import { bindActionCreators } from 'redux'; import TutorialAntiSuiteViewContainer from './TutorialAntiSuiteViewContainer'; -import * as TutorialAntiSuiteViewActions from './TutorialAntiSuiteViewActions'; +import setTutorialComplete from './TutorialAntiSuiteViewActions'; import { setTutorialNavigation } from '../../TutorialView/TutorialViewActions'; /** @@ -24,7 +24,7 @@ import { setTutorialNavigation } from '../../TutorialView/TutorialViewActions'; * @return {function} this function returns a plain object, which will be merged into the component's props * @memberof HubContainers */ -const mapStateToProps = state => Object.assign({}, state.tutorial); +const mapStateToProps = state => ({ ...state.tutorial }); /** * Bind the component's action creators using Redux's bindActionCreators. @@ -33,7 +33,7 @@ const mapStateToProps = state => Object.assign({}, state.tutorial); * @memberof TutorialContainers */ const mapDispatchToProps = dispatch => ({ - actions: bindActionCreators(Object.assign({}, TutorialAntiSuiteViewActions, { setTutorialNavigation }), dispatch), + actions: bindActionCreators({ setTutorialComplete, setTutorialNavigation }, dispatch), }); export default connect(mapStateToProps, mapDispatchToProps)(TutorialAntiSuiteViewContainer); diff --git a/app/hub/Views/TutorialViews/TutorialBlockingView/index.js b/app/hub/Views/TutorialViews/TutorialBlockingView/index.js index a2f19348a..9e8be0d15 100644 --- a/app/hub/Views/TutorialViews/TutorialBlockingView/index.js +++ b/app/hub/Views/TutorialViews/TutorialBlockingView/index.js @@ -23,7 +23,7 @@ import { setTutorialNavigation } from '../../TutorialView/TutorialViewActions'; * @return {function} this function returns a plain object, which will be merged into the component's props * @memberof HubContainers */ -const mapStateToProps = state => Object.assign({}, state.tutorial); +const mapStateToProps = state => ({ ...state.tutorial }); /** * Bind the component's action creators using Redux's bindActionCreators. @@ -32,7 +32,7 @@ const mapStateToProps = state => Object.assign({}, state.tutorial); * @memberof TutorialContainers */ const mapDispatchToProps = dispatch => ({ - actions: bindActionCreators(Object.assign({}, { setTutorialNavigation }), dispatch), + actions: bindActionCreators({ setTutorialNavigation }, dispatch), }); export default connect(mapStateToProps, mapDispatchToProps)(TutorialBlockingViewContainer); diff --git a/app/hub/Views/TutorialViews/TutorialLayoutView/index.js b/app/hub/Views/TutorialViews/TutorialLayoutView/index.js index 9929161b9..14f8e4bdf 100644 --- a/app/hub/Views/TutorialViews/TutorialLayoutView/index.js +++ b/app/hub/Views/TutorialViews/TutorialLayoutView/index.js @@ -23,7 +23,7 @@ import { setTutorialNavigation } from '../../TutorialView/TutorialViewActions'; * @return {function} this function returns a plain object, which will be merged into the component's props * @memberof HubContainers */ -const mapStateToProps = state => Object.assign({}, state.tutorial); +const mapStateToProps = state => ({ ...state.tutorial }); /** * Bind the component's action creators using Redux's bindActionCreators. @@ -32,7 +32,7 @@ const mapStateToProps = state => Object.assign({}, state.tutorial); * @memberof TutorialContainers */ const mapDispatchToProps = dispatch => ({ - actions: bindActionCreators(Object.assign({}, { setTutorialNavigation }), dispatch), + actions: bindActionCreators({ setTutorialNavigation }, dispatch), }); export default connect(mapStateToProps, mapDispatchToProps)(TutorialLayoutViewContainer); diff --git a/app/hub/Views/TutorialViews/TutorialNavigation/TutorialNavigationContainer.jsx b/app/hub/Views/TutorialViews/TutorialNavigation/TutorialNavigationContainer.jsx index f64c4f6d1..ed57d61eb 100644 --- a/app/hub/Views/TutorialViews/TutorialNavigation/TutorialNavigationContainer.jsx +++ b/app/hub/Views/TutorialViews/TutorialNavigation/TutorialNavigationContainer.jsx @@ -22,11 +22,19 @@ import { SteppedNavigation } from '../../../../shared-components'; */ const TutorialNavigationContainer = (props) => { const { totalSteps, tutorial } = props; - const childProps = { - totalSteps, - ...tutorial.navigation, - }; - return ; + + return ( + + ); }; // PropTypes ensure we pass required props of the correct type diff --git a/app/hub/Views/TutorialViews/TutorialNavigation/index.js b/app/hub/Views/TutorialViews/TutorialNavigation/index.js index c4e9ae922..f83a26627 100644 --- a/app/hub/Views/TutorialViews/TutorialNavigation/index.js +++ b/app/hub/Views/TutorialViews/TutorialNavigation/index.js @@ -20,6 +20,6 @@ import TutorialNavigationContainer from './TutorialNavigationContainer'; * @return {function} this function returns a plain object, which will be merged into the component's props * @memberof HubContainers */ -const mapStateToProps = state => Object.assign({}, state.tutorial); +const mapStateToProps = state => ({ ...state.tutorial }); export default connect(mapStateToProps)(TutorialNavigationContainer); diff --git a/app/hub/Views/TutorialViews/TutorialTrackerListView/index.js b/app/hub/Views/TutorialViews/TutorialTrackerListView/index.js index bc09a915a..677b18f4f 100644 --- a/app/hub/Views/TutorialViews/TutorialTrackerListView/index.js +++ b/app/hub/Views/TutorialViews/TutorialTrackerListView/index.js @@ -23,7 +23,7 @@ import { setTutorialNavigation } from '../../TutorialView/TutorialViewActions'; * @return {function} this function returns a plain object, which will be merged into the component's props * @memberof HubContainers */ -const mapStateToProps = state => Object.assign({}, state.tutorial); +const mapStateToProps = state => ({ ...state.tutorial }); /** * Bind the component's action creators using Redux's bindActionCreators. @@ -32,7 +32,7 @@ const mapStateToProps = state => Object.assign({}, state.tutorial); * @memberof TutorialContainers */ const mapDispatchToProps = dispatch => ({ - actions: bindActionCreators(Object.assign({}, { setTutorialNavigation }), dispatch), + actions: bindActionCreators({ setTutorialNavigation }, dispatch), }); export default connect(mapStateToProps, mapDispatchToProps)(TutorialTrackerListViewContainer); diff --git a/app/hub/Views/TutorialViews/TutorialTrustView/index.js b/app/hub/Views/TutorialViews/TutorialTrustView/index.js index 56ab74c4b..f839f8805 100644 --- a/app/hub/Views/TutorialViews/TutorialTrustView/index.js +++ b/app/hub/Views/TutorialViews/TutorialTrustView/index.js @@ -23,7 +23,7 @@ import { setTutorialNavigation } from '../../TutorialView/TutorialViewActions'; * @return {function} this function returns a plain object, which will be merged into the component's props * @memberof HubContainers */ -const mapStateToProps = state => Object.assign({}, state.tutorial); +const mapStateToProps = state => ({ ...state.tutorial }); /** * Bind the component's action creators using Redux's bindActionCreators. @@ -32,7 +32,7 @@ const mapStateToProps = state => Object.assign({}, state.tutorial); * @memberof TutorialContainers */ const mapDispatchToProps = dispatch => ({ - actions: bindActionCreators(Object.assign({}, { setTutorialNavigation }), dispatch), + actions: bindActionCreators({ setTutorialNavigation }, dispatch), }); export default connect(mapStateToProps, mapDispatchToProps)(TutorialTrustViewContainer); diff --git a/app/hub/Views/TutorialViews/TutorialVideoView/TutorialVideoView.jsx b/app/hub/Views/TutorialViews/TutorialVideoView/TutorialVideoView.jsx index 12c28a18e..954fc51fc 100644 --- a/app/hub/Views/TutorialViews/TutorialVideoView/TutorialVideoView.jsx +++ b/app/hub/Views/TutorialViews/TutorialVideoView/TutorialVideoView.jsx @@ -25,7 +25,7 @@ const TutorialVideoView = () => ( {t('hub_tutorial_video_title')}
-
{`${t('license_module')}: ${license.name}`}
@@ -56,7 +57,7 @@ class License extends React.Component {
{t('license_text')} { - this.state.expanded && ( + expanded && (
diff --git a/app/licenses/Licenses.jsx b/app/licenses/Licenses.jsx index cd9aaf339..fb083fc9e 100644 --- a/app/licenses/Licenses.jsx +++ b/app/licenses/Licenses.jsx @@ -31,7 +31,7 @@ class Licenses extends React.Component { * Wrapper function for dangerouslySetInnerHTML. Provides extra security * @return {Object} */ - createFooterMarkup() { + static createFooterMarkup() { return { __html: t('license_footer') }; } @@ -60,7 +60,7 @@ class Licenses extends React.Component {
{ list }