Skip to content

Commit

Permalink
feat(protocol-designer): allow user to re-enable dismissed hints (#2726)
Browse files Browse the repository at this point in the history
Closes #2652
  • Loading branch information
IanLondon authored Nov 29, 2018
1 parent dd0e739 commit af52d1e
Show file tree
Hide file tree
Showing 15 changed files with 68 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,48 @@
import React from 'react'
import {connect} from 'react-redux'
import i18n from '../../localization'
import {Card, ToggleButton} from '@opentrons/components'
import {Card, OutlineButton, ToggleButton} from '@opentrons/components'
import styles from './SettingsPage.css'
import {
actions as analyticsActions,
selectors as analyticsSelectors,
} from '../../analytics'
import {
actions as tutorialActions,
selectors as tutorialSelectors,
} from '../../tutorial'
import type {BaseState} from '../../types'

type Props = {
canClearHintDismissals: boolean,
hasOptedIn: boolean | null,
restoreHints: () => mixed,
toggleOptedIn: () => mixed,
}

type SP = {
canClearHintDismissals: $PropertyType<Props, 'canClearHintDismissals'>,
hasOptedIn: $PropertyType<Props, 'hasOptedIn'>,
}

function Privacy (props: Props) {
const {hasOptedIn, toggleOptedIn} = props
function SettingsApp (props: Props) {
const {canClearHintDismissals, hasOptedIn, restoreHints, toggleOptedIn} = props
return (
<div className={styles.card_wrapper}>
<Card title={i18n.t('card.title.hints')}>
<div className={styles.body_wrapper}>
<div className={styles.card_body}>
{i18n.t('card.body.restore_hints')}
<OutlineButton
className={styles.button}
disabled={!canClearHintDismissals}
onClick={restoreHints}
>
{canClearHintDismissals ? i18n.t('button.restore') : i18n.t('button.restored') }
</OutlineButton>
</div>
</div>
</Card>
<Card title={i18n.t('card.title.privacy')}>
<div className={styles.toggle_row}>
<p className={styles.toggle_label}>{i18n.t('card.toggle.share_session')}</p>
Expand All @@ -47,6 +68,7 @@ function Privacy (props: Props) {
function mapStateToProps (state: BaseState): SP {
return {
hasOptedIn: analyticsSelectors.getHasOptedIn(state),
canClearHintDismissals: tutorialSelectors.getCanClearHintDismissals(state),
}
}

Expand All @@ -60,7 +82,8 @@ function mergeProps (stateProps: SP, dispatchProps: {dispatch: Dispatch<*>}): Pr
return {
...stateProps,
toggleOptedIn: () => dispatch(_toggleOptedIn()),
restoreHints: () => dispatch(tutorialActions.clearAllHintDismissals()),
}
}

export default connect(mapStateToProps, null, mergeProps)(Privacy)
export default connect(mapStateToProps, null, mergeProps)(SettingsApp)
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,12 @@
}
}

.button {
float: right;
}

.body_wrapper {
margin: 0.375rem 0 0.625rem;
line-height: 1.5;
padding: 1rem;
padding: 2rem 1rem;
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ const SettingsSidebar = (props: SP & DP) => (
<SidePanel title={i18n.t('nav.tab_name.settings')}>
<PDTitledList
className={styles.sidebar_item}
selected={props.currentPage === 'settings-privacy'}
onClick={props.makeNavigateToPage('settings-privacy')}
title={i18n.t('nav.settings.privacy')}/>
selected={props.currentPage === 'settings-app'}
onClick={props.makeNavigateToPage('settings-app')}
title={i18n.t('nav.settings.app')}/>
{/* <PDTitledList
disabled
className={styles.sidebar_item}
Expand Down
6 changes: 3 additions & 3 deletions protocol-designer/src/components/SettingsPage/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {connect} from 'react-redux'

import type {BaseState} from '../../types'
import {selectors, type Page} from '../../navigation'
import Privacy from './Privacy'
import SettingsApp from './SettingsApp'

export {default as SettingsSidebar} from './SettingsSidebar'

Expand All @@ -16,9 +16,9 @@ const SettingsPage = (props: SP) => {
// TODO: BC 2018-09-01 when we have feature flags put them here
return <div>Feature Flags Coming Soon...</div>
}
case 'settings-privacy':
case 'settings-app':
default:
return <Privacy />
return <SettingsApp />
}
}

Expand Down
2 changes: 1 addition & 1 deletion protocol-designer/src/containers/ConnectedMainPanel.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ function MainPanel (props: Props) {
return <ConnectedFilePage />
case 'liquids':
return <LiquidsPage />
case 'settings-privacy':
case 'settings-app':
return <SettingsPage />
default:
return <ConnectedDeckSetup />
Expand Down
4 changes: 2 additions & 2 deletions protocol-designer/src/containers/ConnectedNav.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ function Nav (props: Props) {
<NavTab
iconName='settings'
title={i18n.t('nav.tab_name.settings')}
selected={props.currentPage === 'settings-privacy'}
onClick={props.handleClick('settings-privacy')} />
selected={props.currentPage === 'settings-app'}
onClick={props.handleClick('settings-app')} />
</React.Fragment>
}
/>
Expand Down
2 changes: 1 addition & 1 deletion protocol-designer/src/containers/ConnectedSidebar.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ function Sidebar (props: Props) {
case 'file-detail':
return <FileSidebar />
case 'settings-features':
case 'settings-privacy':
case 'settings-app':
return <SettingsSidebar />
}
return null
Expand Down
2 changes: 1 addition & 1 deletion protocol-designer/src/containers/ConnectedTitleBar.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ function mapStateToProps (state: BaseState): SP {
case 'file-splash':
case 'file-detail':
case 'settings-features':
case 'settings-privacy':
case 'settings-app':
return {
_page,
title: i18n.t([`nav.title.${_page}`, fileName]),
Expand Down
2 changes: 2 additions & 0 deletions protocol-designer/src/localization/en/button.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
"no": "no",
"ok": "ok",
"reset": "reset",
"restore": "restore",
"restored": "restored",
"save": "save",
"swap": "swap",
"yes": "yes"
Expand Down
9 changes: 5 additions & 4 deletions protocol-designer/src/localization/en/card.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@
"data_collected_is_internal": "We never share sessions outside of Opentrons",
"data_only_from_pd": "We don’t record or store anything happening outside of your open Protocol Designer tab",
"opt_out_of_data_collection": "You can choose to opt in or out in Settings > Privacy",
"reason_for_collecting_data": "We’re working to improve Protocol Designer. Part of the process involves watching real user sessions to understand which parts of the interface are working and which could use improvement."

"reason_for_collecting_data": "We’re working to improve Protocol Designer. Part of the process involves watching real user sessions to understand which parts of the interface are working and which could use improvement.",
"restore_hints": "Restore all hints and tips notifications"
},
"title": {
"privacy": "Privacy"
"privacy": "Privacy",
"hints": "Hints"
},
"toggle": {
"share_session": "Share sessions with the Opentrons Product Team"
}
}
}
7 changes: 4 additions & 3 deletions protocol-designer/src/localization/en/nav.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"settings": {
"app": "APP",
"privacy": "PRIVACY",
"feature_flags": "Feature Flags"
},
Expand All @@ -8,20 +9,20 @@
"file": "FILE",
"help": "HELP",
"liquids": "LIQUIDS",
"settings": "SETTINGS"
"settings": "Settings"
},
"terminal_item": {
"__initial_setup__": "Starting Deck State",
"__end__": "Final Deck State"
},
"title": {
"settings-features": "Opentrons Beta",
"settings-privacy": "Opentrons Beta",
"settings-app": "Opentrons Beta",
"file-splash": "Opentrons Beta"
},
"subtitle": {
"file-detail": "File Details",
"settings-privacy": "Privacy",
"settings-app": "App Settings",
"liquids": "Liquids"
}
}
2 changes: 1 addition & 1 deletion protocol-designer/src/navigation/types.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ export type Page =
'file-detail' |
'liquids' |
'steplist' |
'settings-privacy' |
'settings-app' |
'settings-features'
4 changes: 4 additions & 0 deletions protocol-designer/src/tutorial/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,7 @@ export const removeHint = (hintKey: HintKey, rememberDismissal: boolean): Remove
type: 'REMOVE_HINT',
payload: {hintKey, rememberDismissal},
})

export const clearAllHintDismissals = () => ({
type: 'CLEAR_ALL_HINT_DISMISSALS',
})
1 change: 1 addition & 0 deletions protocol-designer/src/tutorial/reducers.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ const dismissedHints = handleActions({
const {hintKey, rememberDismissal} = action.payload
return {...state, [hintKey]: {rememberDismissal}}
},
CLEAR_ALL_HINT_DISMISSALS: () => dismissedHintsInitialState,
}, dismissedHintsInitialState)

export function dismissedHintsPersist (state: DismissedHintReducerState) {
Expand Down
10 changes: 8 additions & 2 deletions protocol-designer/src/tutorial/selectors.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
// @flow
import {createSelector} from 'reselect'
import type {BaseState} from '../types'
import isEmpty from 'lodash/isEmpty'
import type {BaseState, Selector} from '../types'

const rootSelector = (state: BaseState) => state.tutorial

export const getHint = createSelector(
rootSelector,
tutorial => {
(tutorial) => {
const dismissedKeys = Object.keys(tutorial.dismissedHints)
const hints = tutorial.hints.filter(hintKey => !dismissedKeys.includes(hintKey))

Expand All @@ -15,3 +16,8 @@ export const getHint = createSelector(
return hints[0]
}
)

export const getCanClearHintDismissals: Selector<boolean> = createSelector(
rootSelector,
(tutorial) => !isEmpty(tutorial.dismissedHints)
)

0 comments on commit af52d1e

Please sign in to comment.