Skip to content

Commit

Permalink
Merge pull request #2669 from cozy/fix/593
Browse files Browse the repository at this point in the history
Fix: Focus of fields when installing a konnector
  • Loading branch information
Merkur39 authored Sep 1, 2023
2 parents 5bf116a + 4ea1b93 commit 94bc789
Show file tree
Hide file tree
Showing 6 changed files with 180 additions and 148 deletions.
57 changes: 32 additions & 25 deletions src/AppContainer.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import {
} from 'doctypes'
import { StoreURLProvider } from 'ducks/store/StoreContext'
import { JOBS_DOCTYPE } from './doctypes'
import { DisableEnforceFocusModalProvider } from 'ducks/transactions/TransactionModal/TransactionModal'
const jobsProviderOptions = t => ({
onSuccess: () => Alerter.success(t('JobsContext.alerter-success')),
onError: () => Alerter.error(t('JobsContext.alerter-errored'))
Expand Down Expand Up @@ -79,31 +80,37 @@ const AppContainer = ({ store, lang, client }) => {
lang={lang}
dictRequire={lang => require(`locales/${lang}`)}
>
<JobsProvider
client={client}
options={jobsProviderOptions(t)}
>
<BanksProvider client={client}>
<SelectionProvider>
<StoreURLProvider>
<MuiCozyTheme>
<CozyConfirmDialogProvider>
<RealTimeQueries doctype={TRIGGER_DOCTYPE} />
<RealTimeQueries doctype={ACCOUNT_DOCTYPE} />
<RealTimeQueries doctype={COZY_ACCOUNT_DOCTYPE} />
<RealTimeQueries doctype={TRANSACTION_DOCTYPE} />
<RealTimeQueries doctype={GROUP_DOCTYPE} />
<RealTimeQueries doctype={FILES_DOCTYPE} />
<RealTimeQueries doctype={JOBS_DOCTYPE} />
<Router>
<AppRoute />
</Router>
</CozyConfirmDialogProvider>
</MuiCozyTheme>
</StoreURLProvider>
</SelectionProvider>
</BanksProvider>
</JobsProvider>
<DisableEnforceFocusModalProvider>
<JobsProvider
client={client}
options={jobsProviderOptions(t)}
>
<BanksProvider client={client}>
<SelectionProvider>
<StoreURLProvider>
<MuiCozyTheme>
<CozyConfirmDialogProvider>
<RealTimeQueries doctype={TRIGGER_DOCTYPE} />
<RealTimeQueries doctype={ACCOUNT_DOCTYPE} />
<RealTimeQueries
doctype={COZY_ACCOUNT_DOCTYPE}
/>
<RealTimeQueries
doctype={TRANSACTION_DOCTYPE}
/>
<RealTimeQueries doctype={GROUP_DOCTYPE} />
<RealTimeQueries doctype={FILES_DOCTYPE} />
<RealTimeQueries doctype={JOBS_DOCTYPE} />
<Router>
<AppRoute />
</Router>
</CozyConfirmDialogProvider>
</MuiCozyTheme>
</StoreURLProvider>
</SelectionProvider>
</BanksProvider>
</JobsProvider>
</DisableEnforceFocusModalProvider>
</I18n>
</CozyProvider>
</StylesProvider>
Expand Down
8 changes: 6 additions & 2 deletions src/components/RawContentDialog.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,14 @@ import {
} from 'cozy-ui/transpiled/react/CozyDialogs'

const RawContentDialog = props => {
const { title, content, onClose } = props
const { title, content, onClose, disableEnforceFocus } = props
const { dialogProps, dialogTitleProps } = useCozyDialog(props)
return (
<Dialog {...dialogProps} onClose={onClose}>
<Dialog
{...dialogProps}
onClose={onClose}
disableEnforceFocus={disableEnforceFocus}
>
<DialogCloseButton onClick={onClose} />
<DialogTitle {...dialogTitleProps}>{title}</DialogTitle>
{content}
Expand Down
26 changes: 26 additions & 0 deletions src/ducks/context/DisableEnforceFocusModalContext.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import React, { createContext, useState, useContext } from 'react'

const DisableEnforceFocusModalContext = createContext(false)

export const DisableEnforceFocusModalProvider = ({ children }) => {
const [disableEnforceFocus, setDisableEnforceFocus] = useState(false)
return (
<DisableEnforceFocusModalContext.Provider
value={{ disableEnforceFocus, setDisableEnforceFocus }}
>
{children}
</DisableEnforceFocusModalContext.Provider>
)
}

export const useDisableEnforceFocusModal = () => {
const disableEnforceFocusModalContext = useContext(
DisableEnforceFocusModalContext
)
if (!disableEnforceFocusModalContext) {
throw new Error(
'useDisableEnforceFocusModal must be used within a EnforceFocusModalProvider'
)
}
return disableEnforceFocusModalContext
}
3 changes: 3 additions & 0 deletions src/ducks/transactions/TransactionModal/TransactionModal.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,12 @@ import {
import useDocument from 'components/useDocument'
import RawContentDialog from 'components/RawContentDialog'
import TransactionModalInfoContent from 'ducks/transactions/TransactionModal/TransactionModalInfoContent'
import { useDisableEnforceFocusModal } from 'ducks/context/DisableEnforceFocusModalContext'

const TransactionModal = ({ requestClose, transactionId, ...props }) => {
const transaction = useDocument(TRANSACTION_DOCTYPE, transactionId)
const location = useLocation()
const { disableEnforceFocus } = useDisableEnforceFocusModal()

useTrackPage(lastTracked => {
// We cannot simply add ":depense" to the last tracked page because
Expand Down Expand Up @@ -57,6 +59,7 @@ const TransactionModal = ({ requestClose, transactionId, ...props }) => {
size="medium"
open
onClose={handleClose}
disableEnforceFocus={disableEnforceFocus}
title={
<div className="u-ta-center">
<Figure
Expand Down
197 changes: 93 additions & 104 deletions src/ducks/transactions/actions/KonnectorAction/index.jsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import React from 'react'
import React, { useState } from 'react'
import PropTypes from 'prop-types'
import compose from 'lodash/flowRight'

import flag from 'cozy-flags'
import { translate } from 'cozy-ui/transpiled/react/I18n'
import { translate, useI18n } from 'cozy-ui/transpiled/react/I18n'
import Icon from 'cozy-ui/transpiled/react/Icon'
import IconPlus from 'cozy-ui/transpiled/react/Icons/Plus'
import ListItem from 'cozy-ui/transpiled/react/MuiCozyTheme/ListItem'
Expand All @@ -19,121 +19,110 @@ import match from 'ducks/transactions/actions/KonnectorAction/match'
import { KonnectorChip } from 'components/KonnectorChip'
import { findMatchingBrandWithoutTrigger } from 'ducks/brandDictionary/selectors'
import { connect } from 'react-redux'
import { useDisableEnforceFocusModal } from 'ducks/context/DisableEnforceFocusModalContext'

const name = 'konnector'

const transactionDialogListItemStyle = { color: palette.dodgerBlue }
class Component extends React.Component {
state = {
showInformativeDialog: false,
showIntentModal: false
}

showInformativeDialog = ev => {
ev && ev.preventDefault()
this.setState({
showInformativeDialog: true
})
}
const ModalItem = ({ label, onClick }) => {
return (
<ListItem
divider
button
style={transactionDialogListItemStyle}
onClick={onClick}
>
<ListItemIcon>
<Icon icon={IconPlus} />
</ListItemIcon>
<ListItemText>{label}</ListItemText>
</ListItem>
)
}

hideInformativeDialog = ev => {
ev && ev.preventDefault()
this.setState({
showInformativeDialog: false
})
}
const TransactionRow = ({ brand, onClick }) => {
return flag('hide.healthTheme.enabled') && brand.health ? null : (
<KonnectorChip
onClick={onClick}
konnectorType={brand.health ? 'health' : 'generic'}
/>
)
}

showIntentModal = ev => {
ev && ev.preventDefault()
this.setState({
showIntentModal: true
})
}
const Component = ({ fetchTriggers, isModalItem, brand }) => {
const { t } = useI18n()
const { setDisableEnforceFocus } = useDisableEnforceFocusModal()

hideIntentModal = ev => {
ev && ev.preventDefault()
this.setState({
showIntentModal: false
})
}
const [showInformativeDialogState, setShowInformativeDialogState] =
useState(false)
const [showIntentModalState, setShowIntentModalState] = useState(false)

onInformativeDialogConfirm = async () => {
this.hideInformativeDialog()
this.showIntentModal()
const showInformativeDialog = ev => {
ev?.preventDefault()
setShowInformativeDialogState(true)
}

onIntentComplete = () => {
this.props.fetchTriggers()
this.hideIntentModal()
const hideInformativeDialog = ev => {
ev?.preventDefault()
setShowInformativeDialogState(false)
}

renderModalItem(label) {
return (
<ListItem
divider
button
style={transactionDialogListItemStyle}
onClick={this.showInformativeDialog}
>
<ListItemIcon>
<Icon icon={IconPlus} />
</ListItemIcon>
<ListItemText>{label}</ListItemText>
</ListItem>
)
const showIntentModal = ev => {
ev?.preventDefault()
setShowIntentModalState(true)
}

renderTransactionRow(label, brand) {
return flag('hide.healthTheme.enabled') && brand.health ? null : (
<KonnectorChip
onClick={this.showInformativeDialog}
konnectorType={brand.health ? 'health' : 'generic'}
/>
)
const hideIntentModal = ev => {
ev?.preventDefault()
setDisableEnforceFocus?.(false)
setShowIntentModalState(false)
}

render() {
const { t, isModalItem } = this.props

const brand = this.props.brand
if (!brand) return

const healthOrGeneric = brand.health ? 'health' : 'generic'
const label = t(`Transactions.actions.konnector.${healthOrGeneric}`)

return (
<>
{isModalItem
? this.renderModalItem(label)
: this.renderTransactionRow(label, brand)}
{this.state.showInformativeDialog && (
<InformativeDialog
onCancel={this.hideInformativeDialog}
onConfirm={this.onInformativeDialogConfirm}
title={t(
`Transactions.actions.informativeModal.${healthOrGeneric}.title`
)}
description={t(
`Transactions.actions.informativeModal.${healthOrGeneric}.description`,
{
brandName: brand.name
}
)}
caption={t('Transactions.actions.informativeModal.caption')}
cancelText={t('Transactions.actions.informativeModal.cancel')}
confirmText={t('Transactions.actions.informativeModal.confirm')}
/>
)}
{this.state.showIntentModal && (
<ConfigurationModal
dismissAction={this.hideIntentModal}
onComplete={this.onIntentComplete}
slug={brand.konnectorSlug}
/>
)}
</>
)
const onInformativeDialogConfirm = () => {
setDisableEnforceFocus?.(true)
hideInformativeDialog()
showIntentModal()
}
const onIntentComplete = () => {
fetchTriggers()
hideIntentModal()
}

if (!brand) return null

const healthOrGeneric = brand.health ? 'health' : 'generic'
const label = t(`Transactions.actions.konnector.${healthOrGeneric}`)

return (
<>
{isModalItem ? (
<ModalItem label={label} onClick={showInformativeDialog} />
) : (
<TransactionRow brand={brand} onClick={showInformativeDialog} />
)}
{showInformativeDialogState && (
<InformativeDialog
onCancel={hideInformativeDialog}
onConfirm={onInformativeDialogConfirm}
title={t(
`Transactions.actions.informativeModal.${healthOrGeneric}.title`
)}
description={t(
`Transactions.actions.informativeModal.${healthOrGeneric}.description`,
{
brandName: brand.name
}
)}
caption={t('Transactions.actions.informativeModal.caption')}
cancelText={t('Transactions.actions.informativeModal.cancel')}
confirmText={t('Transactions.actions.informativeModal.confirm')}
/>
)}
{showIntentModalState && (
<ConfigurationModal
dismissAction={hideIntentModal}
onComplete={onIntentComplete}
slug={brand.konnectorSlug}
/>
)}
</>
)
}

Component.propTypes = {
Expand Down
Loading

0 comments on commit 94bc789

Please sign in to comment.