From 18ee9cf4655005f0859d2cf64aabd5d628aa924c Mon Sep 17 00:00:00 2001 From: Robert Dumitrescu Date: Sat, 2 Nov 2024 16:34:26 +0200 Subject: [PATCH] Autocomplete transaction information when selecting the description of a previous transaction --- src/components/Forms/TransactionSplitForm.tsx | 32 ++++++++++++++++--- .../Screens/ConfigurationScreen.tsx | 31 ++++++++++++++++-- src/i18n/locale/translations/en-US.ts | 3 ++ src/models/configuration.ts | 8 +++++ src/models/transactions.ts | 9 ++++++ 5 files changed, 77 insertions(+), 6 deletions(-) diff --git a/src/components/Forms/TransactionSplitForm.tsx b/src/components/Forms/TransactionSplitForm.tsx index 894ecce..eb5ceb0 100644 --- a/src/components/Forms/TransactionSplitForm.tsx +++ b/src/components/Forms/TransactionSplitForm.tsx @@ -32,6 +32,7 @@ export default function TransactionSplitForm({ }) { const [locale] = getLocales(); const displayForeignCurrency = useSelector((state: RootState) => state.configuration.displayForeignCurrency); + const autocompleteTransaction = useSelector((state: RootState) => state.configuration.autocompleteTransaction); const dispatch = useDispatch(); const { colorScheme, colors } = useThemeColors(); const [formData, setData] = useState({ @@ -73,6 +74,32 @@ export default function TransactionSplitForm({ }); }; + const handleAutocompleteDescription = async (autocomplete) => { + let updates: Partial = { + description: autocomplete.name, + }; + + if (autocompleteTransaction) { + const existingTransaction = await dispatch.transactions.getTransaction(autocomplete.transactionGroupId); + updates = { + ...updates, + sourceId: existingTransaction.attributes.transactions[0].sourceId, + sourceName: existingTransaction.attributes.transactions[0].sourceName, + currencyCode: existingTransaction.attributes.transactions[0].currencyCode, + currencySymbol: existingTransaction.attributes.transactions[0].currencySymbol, + destinationId: existingTransaction.attributes.transactions[0].destinationId, + destinationName: existingTransaction.attributes.transactions[0].destinationName, + categoryId: existingTransaction.attributes.transactions[0].categoryId, + categoryName: existingTransaction.attributes.transactions[0].categoryName, + }; + } + + setTransaction({ + ...formData, + ...updates, + }); + }; + const colorItemTypes = { withdrawal: colors.red, deposit: colors.green, @@ -298,10 +325,7 @@ export default function TransactionSplitForm({ description: value, }); }} - onSelectAutocomplete={(autocomplete) => setTransaction({ - ...formData, - description: autocomplete.name, - })} + onSelectAutocomplete={handleAutocompleteDescription} InputRightElement={deleteBtn(['description'])} routeApi="transactions" /> diff --git a/src/components/Screens/ConfigurationScreen.tsx b/src/components/Screens/ConfigurationScreen.tsx index 295dacf..5d2d1fa 100644 --- a/src/components/Screens/ConfigurationScreen.tsx +++ b/src/components/Screens/ConfigurationScreen.tsx @@ -33,6 +33,7 @@ import { export default function ConfigurationScreen({ navigation }: ScreenType) { const { colors } = useThemeColors(); const closeTransactionScreen = useSelector((state: RootState) => state.configuration.closeTransactionScreen); + const autocompleteAccounts = useSelector((state: RootState) => state.configuration.autocompleteTransaction); const safeAreaInsets = useSafeAreaInsets(); const backendURL = useSelector((state: RootState) => state.configuration.backendURL); const useBiometricAuth = useSelector((state: RootState) => state.configuration.useBiometricAuth); @@ -106,11 +107,16 @@ export default function ConfigurationScreen({ navigation }: ScreenType) { ); }; - const handleCheckBoxChange = async (bool: boolean) => { + const handleCloseFormCheckBoxChange = async (bool: boolean) => { dispatch.configuration.setCloseTransactionScreen(bool); return Promise.resolve(); }; + const handleAutocompleteAccountsCheckBoxChange = async (bool: boolean) => { + dispatch.configuration.setAutocompleteTransaction(bool); + return Promise.resolve(); + }; + const showLogoutAlert = () => Alert.alert( translate('configuration_clear_alert_title'), '', @@ -305,7 +311,28 @@ export default function ConfigurationScreen({ navigation }: ScreenType) { }} > {translate('close_after_transaction')} - + + + + + + {translate('configuration_autocomplete_transaction')} + diff --git a/src/i18n/locale/translations/en-US.ts b/src/i18n/locale/translations/en-US.ts index 985a45c..00bb725 100644 --- a/src/i18n/locale/translations/en-US.ts +++ b/src/i18n/locale/translations/en-US.ts @@ -165,4 +165,7 @@ export default { filters_screen_title: 'Filters', credentials_done_button: 'Done', credentials_edit_button: 'Edit', + + // from X.X.X + configuration_autocomplete_transaction: 'Autocomplete transaction information when selecting a previous description', // TODO: explain better }; diff --git a/src/models/configuration.ts b/src/models/configuration.ts index d15773d..0cc1e15 100644 --- a/src/models/configuration.ts +++ b/src/models/configuration.ts @@ -14,6 +14,7 @@ type ConfigurationStateType = { apiVersion: string serverVersion: string closeTransactionScreen: boolean + autocompleteTransaction: boolean selectedTheme: string selectedBrandStyle: string } @@ -52,6 +53,7 @@ const INITIAL_STATE = { apiVersion: '', serverVersion: '', closeTransactionScreen: false, + autocompleteTransaction: false, selectedTheme: 'gradientOrange', selectedBrandStyle: colors.brandStyleOrange, } as ConfigurationStateType; @@ -114,6 +116,12 @@ export default createModel()({ closeTransactionScreen, }; }, + setAutocompleteTransaction(state, autocompleteTransaction: boolean): ConfigurationStateType { + return { + ...state, + autocompleteTransaction, + }; + }, setSelectedTheme(state, selectedTheme: string): ConfigurationStateType { return { ...state, diff --git a/src/models/transactions.ts b/src/models/transactions.ts index 931ea21..a8b8afc 100644 --- a/src/models/transactions.ts +++ b/src/models/transactions.ts @@ -354,8 +354,17 @@ export default createModel()({ return response; }, + async deleteTransaction(id): Promise { return dispatch.configuration.apiDelete({ url: `/api/v1/transactions/${id}` }); }, + + async getTransaction(id): Promise { + const { data: transaction } = await dispatch.configuration.apiFetch({ url: `/api/v1/transactions/${id}` }) as { + data: TransactionType, + }; + + return transaction; + }, }), });