From 1a15d2c03990a45a0560958ea066662dd4eb8c78 Mon Sep 17 00:00:00 2001 From: Matiss Janis Aboltins <matiss@mja.lv> Date: Sun, 3 Sep 2023 21:56:58 +0100 Subject: [PATCH] :recycle: use useCategories everywhere (#1597) --- .../src/components/ManageRules.js | 12 +++++- .../desktop-client/src/components/Modals.tsx | 4 +- .../src/components/accounts/Account.js | 7 ++- .../src/components/budget/MobileBudget.js | 4 +- .../src/components/budget/index.js | 3 +- .../src/components/modals/EditField.js | 3 +- .../components/payees/ManagePayeesWithData.js | 3 +- .../src/components/rules/Value.tsx | 43 ++++++++----------- .../transactions/MobileTransaction.js | 37 ++++++++++------ .../transactions/SimpleTransactionsTable.js | 5 ++- .../src/components/util/GenericInput.js | 13 +++--- upcoming-release-notes/1597.md | 6 +++ 12 files changed, 81 insertions(+), 59 deletions(-) create mode 100644 upcoming-release-notes/1597.md diff --git a/packages/desktop-client/src/components/ManageRules.js b/packages/desktop-client/src/components/ManageRules.js index 98b433d4f..11c9e3737 100644 --- a/packages/desktop-client/src/components/ManageRules.js +++ b/packages/desktop-client/src/components/ManageRules.js @@ -14,6 +14,7 @@ import * as undo from 'loot-core/src/platform/client/undo'; import { mapField, friendlyOp } from 'loot-core/src/shared/rules'; import { describeSchedule } from 'loot-core/src/shared/schedules'; +import useCategories from '../hooks/useCategories'; import useSelected, { SelectedProvider } from '../hooks/useSelected'; import { theme } from '../style'; @@ -88,12 +89,19 @@ function ManageRulesContent({ isModal, payeeId, setLoading }) { let dispatch = useDispatch(); let { data: schedules } = SchedulesQuery.useQuery(); - let filterData = useSelector(state => ({ + let { list: categories } = useCategories(); + let state = useSelector(state => ({ payees: state.queries.payees, - categories: state.queries.categories.list, accounts: state.queries.accounts, schedules, })); + let filterData = useMemo( + () => ({ + ...state, + categories, + }), + [state, categories], + ); let filteredRules = useMemo( () => diff --git a/packages/desktop-client/src/components/Modals.tsx b/packages/desktop-client/src/components/Modals.tsx index 7299f17ab..2dc2423bd 100644 --- a/packages/desktop-client/src/components/Modals.tsx +++ b/packages/desktop-client/src/components/Modals.tsx @@ -5,6 +5,7 @@ import { useLocation } from 'react-router-dom'; import { send } from 'loot-core/src/platform/client/fetch'; import { useActions } from '../hooks/useActions'; +import useCategories from '../hooks/useCategories'; import useSyncServerStatus from '../hooks/useSyncServerStatus'; import { type CommonModalProps } from '../types/modals'; @@ -34,8 +35,7 @@ export default function Modals() { const modalStack = useSelector(state => state.modals.modalStack); const isHidden = useSelector(state => state.modals.isHidden); const accounts = useSelector(state => state.queries.accounts); - const categoryGroups = useSelector(state => state.queries.categories.grouped); - const categories = useSelector(state => state.queries.categories.list); + const { grouped: categoryGroups, list: categories } = useCategories(); const budgetId = useSelector( state => state.prefs.local && state.prefs.local.id, ); diff --git a/packages/desktop-client/src/components/accounts/Account.js b/packages/desktop-client/src/components/accounts/Account.js index 796b97f15..da79a1fc5 100644 --- a/packages/desktop-client/src/components/accounts/Account.js +++ b/packages/desktop-client/src/components/accounts/Account.js @@ -26,6 +26,7 @@ import { import { applyChanges, groupById } from 'loot-core/src/shared/util'; import { authorizeBank } from '../../gocardless'; +import useCategories from '../../hooks/useCategories'; import { SelectedProviderWithItems } from '../../hooks/useSelected'; import { styles, theme } from '../../style'; import Button from '../common/Button'; @@ -272,9 +273,6 @@ class AccountInternal extends PureComponent { // Important that any async work happens last so that the // listeners are set up synchronously - if (this.props.categoryGroups.length === 0) { - await this.props.getCategories(); - } await this.props.initiallyLoadPayees(); await this.fetchTransactions(); @@ -1350,12 +1348,12 @@ export default function Account() { let params = useParams(); let location = useLocation(); + let { grouped: categoryGroups } = useCategories(); let state = useSelector(state => ({ newTransactions: state.queries.newTransactions, matchedTransactions: state.queries.matchedTransactions, accounts: state.queries.accounts, failedAccounts: state.account.failedAccounts, - categoryGroups: state.queries.categories.grouped, dateFormat: state.prefs.local.dateFormat || 'MM/dd/yyyy', hideFraction: state.prefs.local.hideFraction || false, expandSplits: state.prefs.local['expand-splits'], @@ -1408,6 +1406,7 @@ export default function Account() { > <AccountHack {...state} + categoryGroups={categoryGroups} {...actionCreators} modalShowing={state.modalShowing} accountId={params.id} diff --git a/packages/desktop-client/src/components/budget/MobileBudget.js b/packages/desktop-client/src/components/budget/MobileBudget.js index 0486a5b32..559d42f42 100644 --- a/packages/desktop-client/src/components/budget/MobileBudget.js +++ b/packages/desktop-client/src/components/budget/MobileBudget.js @@ -11,6 +11,7 @@ import { import * as monthUtils from 'loot-core/src/shared/months'; import { useActions } from '../../hooks/useActions'; +import useCategories from '../../hooks/useCategories'; import { useSetThemeColor } from '../../hooks/useSetThemeColor'; import AnimatedLoading from '../../icons/AnimatedLoading'; import { theme } from '../../style'; @@ -293,8 +294,7 @@ class Budget extends Component { } export default function BudgetWrapper() { - let categoryGroups = useSelector(state => state.queries.categories.grouped); - let categories = useSelector(state => state.queries.categories.list); + let { list: categories, grouped: categoryGroups } = useCategories(); let budgetType = useSelector( state => state.prefs.local.budgetType || 'rollover', ); diff --git a/packages/desktop-client/src/components/budget/index.js b/packages/desktop-client/src/components/budget/index.js index d5a0497c9..cbaa70ed4 100644 --- a/packages/desktop-client/src/components/budget/index.js +++ b/packages/desktop-client/src/components/budget/index.js @@ -24,6 +24,7 @@ import { import * as monthUtils from 'loot-core/src/shared/months'; import { useActions } from '../../hooks/useActions'; +import useCategories from '../../hooks/useCategories'; import useFeatureFlag from '../../hooks/useFeatureFlag'; import { styles } from '../../style'; import View from '../common/View'; @@ -468,7 +469,7 @@ export default function BudgetWrapper(props) { state => state.prefs.local.budgetType || 'rollover', ); let maxMonths = useSelector(state => state.prefs.global.maxMonths); - let categoryGroups = useSelector(state => state.queries.categories.grouped); + let { grouped: categoryGroups } = useCategories(); let actions = useActions(); let spreadsheet = useSpreadsheet(); diff --git a/packages/desktop-client/src/components/modals/EditField.js b/packages/desktop-client/src/components/modals/EditField.js index f4632dafe..eee4d0eb4 100644 --- a/packages/desktop-client/src/components/modals/EditField.js +++ b/packages/desktop-client/src/components/modals/EditField.js @@ -7,6 +7,7 @@ import { currentDay, dayFromDate } from 'loot-core/src/shared/months'; import { amountToInteger } from 'loot-core/src/shared/util'; import { useActions } from '../../hooks/useActions'; +import useCategories from '../../hooks/useCategories'; import { useResponsive } from '../../ResponsiveProvider'; import { colors } from '../../style'; import AccountAutocomplete from '../autocomplete/AccountAutocomplete'; @@ -22,7 +23,7 @@ export default function EditField({ modalProps, name, onSubmit }) { let dateFormat = useSelector( state => state.prefs.local.dateFormat || 'MM/dd/yyyy', ); - let categoryGroups = useSelector(state => state.queries.categories.grouped); + let { grouped: categoryGroups } = useCategories(); let accounts = useSelector(state => state.queries.accounts); let payees = useSelector(state => state.queries.payees); diff --git a/packages/desktop-client/src/components/payees/ManagePayeesWithData.js b/packages/desktop-client/src/components/payees/ManagePayeesWithData.js index 01cced13d..a99364df5 100644 --- a/packages/desktop-client/src/components/payees/ManagePayeesWithData.js +++ b/packages/desktop-client/src/components/payees/ManagePayeesWithData.js @@ -5,13 +5,14 @@ import { send, listen } from 'loot-core/src/platform/client/fetch'; import { applyChanges } from 'loot-core/src/shared/util'; import { useActions } from '../../hooks/useActions'; +import useCategories from '../../hooks/useCategories'; import { ManagePayees } from '.'; export default function ManagePayeesWithData({ initialSelectedIds }) { let initialPayees = useSelector(state => state.queries.payees); let lastUndoState = useSelector(state => state.app.lastUndoState); - let categoryGroups = useSelector(state => state.queries.categories.grouped); + let { grouped: categoryGroups } = useCategories(); let { initiallyLoadPayees, getPayees, setLastUndoState, pushModal } = useActions(); diff --git a/packages/desktop-client/src/components/rules/Value.tsx b/packages/desktop-client/src/components/rules/Value.tsx index e7d24448c..74474f1ec 100644 --- a/packages/desktop-client/src/components/rules/Value.tsx +++ b/packages/desktop-client/src/components/rules/Value.tsx @@ -7,6 +7,7 @@ import { getMonthYearFormat } from 'loot-core/src/shared/months'; import { getRecurringDescription } from 'loot-core/src/shared/schedules'; import { integerToCurrency } from 'loot-core/src/shared/util'; +import useCategories from '../../hooks/useCategories'; import { theme } from '../../style'; import LinkButton from '../common/LinkButton'; import Text from '../common/Text'; @@ -33,31 +34,23 @@ export default function Value<T>({ // @ts-expect-error fix this later describe = x => x.name, }: ValueProps<T>) { - let { data, dateFormat } = useSelector(state => { - let data; - if (dataProp) { - data = dataProp; - } else { - switch (field) { - case 'payee': - data = state.queries.payees; - break; - case 'category': - data = state.queries.categories.list; - break; - case 'account': - data = state.queries.accounts; - break; - default: - data = []; - } - } + let dateFormat = useSelector( + state => state.prefs.local.dateFormat || 'MM/dd/yyyy', + ); + let payees = useSelector(state => state.queries.payees); + let { list: categories } = useCategories(); + let accounts = useSelector(state => state.queries.accounts); + + let data = + dataProp || + (field === 'payee' + ? payees + : field === 'category' + ? categories + : field === 'account' + ? accounts + : []); - return { - data, - dateFormat: state.prefs.local.dateFormat || 'MM/dd/yyyy', - }; - }); let [expanded, setExpanded] = useState(false); function onExpand(e) { @@ -98,7 +91,7 @@ export default function Value<T>({ if (valueIsRaw) { return value; } - if (data && data.length) { + if (data && Array.isArray(data)) { let item = data.find(item => item.id === value); if (item) { return describe(item); diff --git a/packages/desktop-client/src/components/transactions/MobileTransaction.js b/packages/desktop-client/src/components/transactions/MobileTransaction.js index 26a9e6a78..97caeeec2 100644 --- a/packages/desktop-client/src/components/transactions/MobileTransaction.js +++ b/packages/desktop-client/src/components/transactions/MobileTransaction.js @@ -6,7 +6,7 @@ import React, { useState, useRef, } from 'react'; -import { connect } from 'react-redux'; +import { useSelector } from 'react-redux'; import { useNavigate, useParams, Link } from 'react-router-dom'; import { useFocusRing } from '@react-aria/focus'; @@ -23,7 +23,6 @@ import { import { css } from 'glamor'; import memoizeOne from 'memoize-one'; -import * as actions from 'loot-core/src/client/actions'; import q, { runQuery } from 'loot-core/src/client/query-helpers'; import { send } from 'loot-core/src/platform/client/fetch'; import * as monthUtils from 'loot-core/src/shared/months'; @@ -43,6 +42,8 @@ import { groupById, } from 'loot-core/src/shared/util'; +import { useActions } from '../../hooks/useActions'; +import useCategories from '../../hooks/useCategories'; import { useSetThemeColor } from '../../hooks/useSetThemeColor'; import SvgAdd from '../../icons/v1/Add'; import CheveronLeft from '../../icons/v1/CheveronLeft'; @@ -847,16 +848,28 @@ function TransactionEditUnconnected(props) { ); } -export const TransactionEdit = connect( - state => ({ - categories: state.queries.categories.list, - payees: state.queries.payees, - lastTransaction: state.queries.lastTransaction, - accounts: state.queries.accounts, - dateFormat: state.prefs.local.dateFormat || 'MM/dd/yyyy', - }), - actions, -)(TransactionEditUnconnected); +export const TransactionEdit = props => { + const { list: categories } = useCategories(); + const payees = useSelector(state => state.queries.payees); + const lastTransaction = useSelector(state => state.queries.lastTransaction); + const accounts = useSelector(state => state.queries.accounts); + const dateFormat = useSelector( + state => state.prefs.local.dateFormat || 'MM/dd/yyyy', + ); + const actions = useActions(); + + return ( + <TransactionEditUnconnected + {...props} + {...actions} + categories={categories} + payees={payees} + lastTransaction={lastTransaction} + accounts={accounts} + dateFormat={dateFormat} + /> + ); +}; class Transaction extends PureComponent { render() { diff --git a/packages/desktop-client/src/components/transactions/SimpleTransactionsTable.js b/packages/desktop-client/src/components/transactions/SimpleTransactionsTable.js index c171270bf..82165e158 100644 --- a/packages/desktop-client/src/components/transactions/SimpleTransactionsTable.js +++ b/packages/desktop-client/src/components/transactions/SimpleTransactionsTable.js @@ -13,6 +13,7 @@ import { } from 'loot-core/src/client/reducers/queries'; import { integerToCurrency } from 'loot-core/src/shared/util'; +import useCategories from '../../hooks/useCategories'; import { useSelectedItems, useSelectedDispatch } from '../../hooks/useSelected'; import ArrowsSynchronize from '../../icons/v2/ArrowsSynchronize'; import { theme, styles } from '../../style'; @@ -141,11 +142,11 @@ export default function SimpleTransactionsTable({ fields = ['date', 'payee', 'amount'], style, }) { - let { payees, categories, accounts, dateFormat } = useSelector(state => { + let { grouped: categories } = useCategories(); + let { payees, accounts, dateFormat } = useSelector(state => { return { payees: state.queries.payees, accounts: state.queries.accounts, - categories: state.queries.categories.grouped, dateFormat: state.prefs.local.dateFormat || 'MM/dd/yyyy', }; }); diff --git a/packages/desktop-client/src/components/util/GenericInput.js b/packages/desktop-client/src/components/util/GenericInput.js index 15e0120c7..bbc7b8d3d 100644 --- a/packages/desktop-client/src/components/util/GenericInput.js +++ b/packages/desktop-client/src/components/util/GenericInput.js @@ -3,6 +3,7 @@ import { useSelector } from 'react-redux'; import { getMonthYearFormat } from 'loot-core/src/shared/months'; +import useCategories from '../../hooks/useCategories'; import AccountAutocomplete from '../autocomplete/AccountAutocomplete'; import Autocomplete from '../autocomplete/Autocomplete'; import CategoryAutocomplete from '../autocomplete/CategoryAutocomplete'; @@ -24,13 +25,11 @@ export default function GenericInput({ style, onChange, }) { - let { saved, categoryGroups, dateFormat } = useSelector(state => { - return { - saved: state.queries.saved, - categoryGroups: state.queries.categories.grouped, - dateFormat: state.prefs.local.dateFormat || 'MM/dd/yyyy', - }; - }); + let { grouped: categoryGroups } = useCategories(); + let saved = useSelector(state => state.queries.saved); + let dateFormat = useSelector( + state => state.prefs.local.dateFormat || 'MM/dd/yyyy', + ); // This makes the UI more resilient in case of faulty data if (multi && !Array.isArray(value)) { diff --git a/upcoming-release-notes/1597.md b/upcoming-release-notes/1597.md new file mode 100644 index 000000000..ca53dc34b --- /dev/null +++ b/upcoming-release-notes/1597.md @@ -0,0 +1,6 @@ +--- +category: Maintenance +authors: [MatissJanis] +--- + +Use `useCategories` hook everywhere categories are accessed. -- GitLab