REX refacto CTAs sur la page de détails d'un compte sur Banks pour faciliter la surcharge

Chaque CTA a une fonction `match` qui dit si celui-ci doit s'afficher ou non, en fonction de certains paramètres...

// ...

const match = (transaction, { brands, urls }) => {
  if (!hasUrls(urls)) {
    return false
  }

  const matchingBrand = findMatchingBrandWithoutTrigger(transaction, brands)

  return matchingBrand
}

... et c'est le composant `TransactionsPage` qui récupère ces paramètres et les passe à ses enfants

Et ça fonctionnait... jusqu'à ce qu'on ait besoin d'ajouter les io.cozy.konnectors aux paramètres passés aux actions dans une customization

Quel est le problème ?

TransactionsPage

TransactionsWithSelection

Transactions

Row

TransactionsActions

Action

Surcharger `TransactionsPage` pour chopper les bons paramètres, et les « spreader » sur tous les niveaux intermédiaires

  • Pas très envie de surcharger `TransactionsPage` (ça aurait nécessité un refacto pour être fait efficacement de toutes façons)
  • Pas fan de spreader des props sur n niveaux : ça rend difficile de suivre le flow

TransactionsPage

TransactionsWithSelection

Transactions

Row

TransactionsActions

Action

TransactionActionsContext

TransactionsActions

Action

TransactionActionsContext

render() {
    // ...

    return (
      <TransactionActionsProvider>
        {/* children */}
      </TransactionActionsProvider>
    )
  }
}

TransactionsPage.jsx

100% générique, rien à surcharger

import React from 'react'
import { omit } from 'lodash'

export const TransactionActionsContext = React.createContext()

export class DumbTransactionActionsProvider extends React.Component {
  render() {
    const value = omit(this.props, 'children')

    return (
      <TransactionActionsContext.Provider value={value}>
        {this.props.children}
      </TransactionActionsContext.Provider>
    )
  }
}

TransactionActionsContext.jsx

100% générique, rien à surcharger


import { flowRight as compose } from 'lodash'
import withAppsUrls from 'ducks/apps/withAppsUrls'
import withBrands from 'ducks/brandDictionary/withBrands'
import { DumbTransactionActionsProvider } from 'ducks/transactions/TransactionActionsContext'

const TransactionActionsProvider = compose(
  withAppsUrls,
  withBrands
)(DumbTransactionActionsProvider)

export default TransactionActionsProvider

TransactionActionsProvider.jsx

à surcharger pour donner les bons paramètres au contexte

// ...
import { TransactionActionsContext } from 'ducks/transactions/TransactionActionsContext'

class TransactionActions extends Component {
  static contextType = TransactionActionsContext

  // ...

  async findMatchingActions() {
    const { transaction } = this.props
    if (transaction) {
      const { bill } = this.props
      const actionProps = {
        bill,
        ...this.context
      }
      const actions = await findMatchingActions(transaction, actionProps)
      
      // ...
    }
  }
}

TransactionActions.jsx

passe la valeur du contexte à chaque action pour savoir si elle doit être affichée ou non; rien à surcharger

Il faut ensuite évidemment surcharger la fonction `match` de chaque action qui a un critère d'affichage différent de l'app Banks originale

Questions / remarques ?

REX refacto CTAs Banks

By Cyrille Perois

REX refacto CTAs Banks

  • 495