From 1df7acdca771ec4cad8998d5001e128387bbf237 Mon Sep 17 00:00:00 2001
From: Matiss Janis Aboltins <matiss@mja.lv>
Date: Sat, 18 Mar 2023 20:30:01 +0000
Subject: [PATCH] :recycle:  refactor Nordigen and Category autocomplete usage
 (#784)

The final `Autocomplete` refactors. After this is merged what's
remaining is to do extensive testing and address the bugs in
https://github.com/actualbudget/actual/issues/773

This PR moves `Nordigen` autocomplete to the new one without using a
feature flag. IMO this is a safe change given the simple nature of the
Nordigen autocomplete component.
---
 .../desktop-client/src/components/Modals.js   |   1 +
 .../components/accounts/TransactionsTable.js  |   6 +-
 .../src/components/util/GenericInput.js       |   6 +-
 .../src/components/CategoryAutocomplete.js    |  91 +++++++++++++
 .../src/components/budget/index.js            |   9 +-
 .../budget/rollover/BudgetSummary.js          |  22 +++-
 .../budget/rollover/TransferTooltip.js        |   8 +-
 .../budget/rollover/rollover-components.js    |  20 ++-
 .../src/components/modals/EditField.js        |   7 +-
 .../components/modals/NordigenExternalMsg.js  |  73 ++---------
 .../src/components/modals/countries.js        | 124 +++++++++---------
 upcoming-release-notes/784.md                 |   6 +
 12 files changed, 238 insertions(+), 135 deletions(-)
 create mode 100644 packages/loot-design/src/components/CategoryAutocomplete.js
 create mode 100644 upcoming-release-notes/784.md

diff --git a/packages/desktop-client/src/components/Modals.js b/packages/desktop-client/src/components/Modals.js
index 894c34077..eae0f072c 100644
--- a/packages/desktop-client/src/components/Modals.js
+++ b/packages/desktop-client/src/components/Modals.js
@@ -288,6 +288,7 @@ function Modals({
             modalProps={modalProps}
             month={options.month}
             actions={actions}
+            isNewAutocompleteEnabled={isNewAutocompleteEnabled}
             isGoalTemplatesEnabled={isGoalTemplatesEnabled}
           />
         </Route>
diff --git a/packages/desktop-client/src/components/accounts/TransactionsTable.js b/packages/desktop-client/src/components/accounts/TransactionsTable.js
index 9a8980c8e..ee6f85fe2 100644
--- a/packages/desktop-client/src/components/accounts/TransactionsTable.js
+++ b/packages/desktop-client/src/components/accounts/TransactionsTable.js
@@ -37,7 +37,8 @@ import {
   titleFirst,
 } from 'loot-core/src/shared/util';
 import LegacyAccountAutocomplete from 'loot-design/src/components/AccountAutocomplete';
-import CategoryAutocomplete from 'loot-design/src/components/CategorySelect';
+import NewCategoryAutocomplete from 'loot-design/src/components/CategoryAutocomplete';
+import LegacyCategoryAutocomplete from 'loot-design/src/components/CategorySelect';
 import { View, Text, Tooltip, Button } from 'loot-design/src/components/common';
 import DateSelect from 'loot-design/src/components/DateSelect';
 import NewAccountAutocomplete from 'loot-design/src/components/NewAccountAutocomplete';
@@ -533,6 +534,9 @@ export const Transaction = React.memo(function Transaction(props) {
   const AccountAutocomplete = isNewAutocompleteEnabled
     ? NewAccountAutocomplete
     : LegacyAccountAutocomplete;
+  const CategoryAutocomplete = isNewAutocompleteEnabled
+    ? NewCategoryAutocomplete
+    : LegacyCategoryAutocomplete;
 
   let dispatchSelected = useSelectedDispatch();
 
diff --git a/packages/desktop-client/src/components/util/GenericInput.js b/packages/desktop-client/src/components/util/GenericInput.js
index a6f6d88f2..b167af4dc 100644
--- a/packages/desktop-client/src/components/util/GenericInput.js
+++ b/packages/desktop-client/src/components/util/GenericInput.js
@@ -4,7 +4,8 @@ import { useSelector } from 'react-redux';
 import { getMonthYearFormat } from 'loot-core/src/shared/months';
 import LegacyAccountAutocomplete from 'loot-design/src/components/AccountAutocomplete';
 import LegacyAutocomplete from 'loot-design/src/components/Autocomplete';
-import CategoryAutocomplete from 'loot-design/src/components/CategorySelect';
+import NewCategoryAutocomplete from 'loot-design/src/components/CategoryAutocomplete';
+import LegacyCategoryAutocomplete from 'loot-design/src/components/CategorySelect';
 import { View, Input } from 'loot-design/src/components/common';
 import DateSelect from 'loot-design/src/components/DateSelect';
 import { Checkbox } from 'loot-design/src/components/forms';
@@ -33,6 +34,9 @@ export default function GenericInput({
   const AccountAutocomplete = isNewAutocompleteEnabled
     ? NewAccountAutocomplete
     : LegacyAccountAutocomplete;
+  const CategoryAutocomplete = isNewAutocompleteEnabled
+    ? NewCategoryAutocomplete
+    : LegacyCategoryAutocomplete;
 
   let { payees, accounts, categoryGroups, dateFormat } = useSelector(state => {
     return {
diff --git a/packages/loot-design/src/components/CategoryAutocomplete.js b/packages/loot-design/src/components/CategoryAutocomplete.js
new file mode 100644
index 000000000..77c8a70e2
--- /dev/null
+++ b/packages/loot-design/src/components/CategoryAutocomplete.js
@@ -0,0 +1,91 @@
+import React, { useMemo } from 'react';
+import { components as SelectComponents } from 'react-select';
+
+import { colors } from '../style';
+import Split from '../svg/v0/Split';
+
+import { View } from './common';
+import Autocomplete from './NewAutocomplete';
+
+const SPLIT_TRANSACTION_KEY = 'split';
+
+export default function CategoryAutocomplete({
+  value,
+  categoryGroups,
+  showSplitOption = false,
+  multi = false,
+  onSplit,
+  ...props
+}) {
+  const options = useMemo(() => {
+    const suggestions = categoryGroups.map(group => ({
+      label: group.name,
+      options: group.categories.map(categ => ({
+        value: categ.id,
+        label: categ.name,
+      })),
+    }));
+
+    if (showSplitOption) {
+      suggestions.unshift({
+        value: SPLIT_TRANSACTION_KEY,
+        label: SPLIT_TRANSACTION_KEY,
+      });
+    }
+
+    return suggestions;
+  }, [categoryGroups, showSplitOption]);
+
+  const allOptions = useMemo(
+    () =>
+      options.reduce(
+        (carry, { options }) => [...carry, ...(options || [])],
+        [],
+      ),
+    [options],
+  );
+
+  return (
+    <Autocomplete
+      options={options}
+      value={
+        multi
+          ? allOptions.filter(item => value.includes(item.value))
+          : allOptions.find(item => item.value === value)
+      }
+      isMulti={multi}
+      components={{
+        Option,
+      }}
+      {...props}
+    />
+  );
+}
+
+function Option(props) {
+  if (props.value === SPLIT_TRANSACTION_KEY) {
+    return (
+      <SelectComponents.Option {...props}>
+        <View
+          style={{
+            flexDirection: 'row',
+            alignItems: 'center',
+            fontSize: 11,
+            color: colors.g8,
+            marginLeft: -12,
+            padding: '4px 0',
+          }}
+          data-testid="split-transaction-button"
+        >
+          <Split
+            width={10}
+            height={10}
+            style={{ marginRight: 5, color: 'inherit' }}
+          />
+          Split Transaction
+        </View>
+      </SelectComponents.Option>
+    );
+  }
+  return <SelectComponents.Option {...props} />;
+}
diff --git a/packages/loot-design/src/components/budget/index.js b/packages/loot-design/src/components/budget/index.js
index 76b6115d0..7bc0f7395 100644
--- a/packages/loot-design/src/components/budget/index.js
+++ b/packages/loot-design/src/components/budget/index.js
@@ -1,4 +1,5 @@
 import React, { useContext, useState, useMemo } from 'react';
+import { connect } from 'react-redux';
 
 import * as monthUtils from 'loot-core/src/shared/months';
 
@@ -729,7 +730,11 @@ function ExpenseGroup({
   );
 }
 
-function ExpenseCategory({
+const ExpenseCategory = connect(state => ({
+  isNewAutocompleteEnabled: state.prefs.local['flags.newAutocomplete'],
+}))(ExpenseCategoryInternal);
+
+function ExpenseCategoryInternal({
   cat,
   budgetArray,
   editingCell,
@@ -743,6 +748,7 @@ function ExpenseCategory({
   onShowActivity,
   onDragChange,
   onReorder,
+  isNewAutocompleteEnabled,
 }) {
   let dragging = dragState && dragState.item === cat;
 
@@ -801,6 +807,7 @@ function ExpenseCategory({
             onEdit: onEditMonth,
             onBudgetAction,
             onShowActivity,
+            isNewAutocompleteEnabled,
           }}
         />
       </View>
diff --git a/packages/loot-design/src/components/budget/rollover/BudgetSummary.js b/packages/loot-design/src/components/budget/rollover/BudgetSummary.js
index 2aa757e67..57a2408e0 100644
--- a/packages/loot-design/src/components/budget/rollover/BudgetSummary.js
+++ b/packages/loot-design/src/components/budget/rollover/BudgetSummary.js
@@ -134,7 +134,13 @@ function TotalsList({ prevMonthName, collapsed }) {
   );
 }
 
-function ToBudget({ month, prevMonthName, collapsed, onBudgetAction }) {
+function ToBudget({
+  month,
+  prevMonthName,
+  collapsed,
+  onBudgetAction,
+  isNewAutocompleteEnabled,
+}) {
   return (
     <SheetValue binding={rolloverBudget.toBudget} initialValue={0}>
       {node => {
@@ -231,6 +237,7 @@ function ToBudget({ month, prevMonthName, collapsed, onBudgetAction }) {
                           category,
                         });
                       }}
+                      isNewAutocompleteEnabled={isNewAutocompleteEnabled}
                     />
                   )}
                 </View>
@@ -243,7 +250,11 @@ function ToBudget({ month, prevMonthName, collapsed, onBudgetAction }) {
   );
 }
 
-export function BudgetSummary({ month, isGoalTemplatesEnabled }) {
+export function BudgetSummary({
+  month,
+  isGoalTemplatesEnabled,
+  isNewAutocompleteEnabled,
+}) {
   let {
     currentMonth,
     summaryCollapsed: collapsed,
@@ -405,13 +416,18 @@ export function BudgetSummary({ month, isGoalTemplatesEnabled }) {
               prevMonthName={prevMonthName}
               month={month}
               onBudgetAction={onBudgetAction}
+              isNewAutocompleteEnabled={isNewAutocompleteEnabled}
             />
           </View>
         ) : (
           <>
             <TotalsList prevMonthName={prevMonthName} />
             <View style={{ margin: '23px 0' }}>
-              <ToBudget month={month} onBudgetAction={onBudgetAction} />
+              <ToBudget
+                month={month}
+                onBudgetAction={onBudgetAction}
+                isNewAutocompleteEnabled={isNewAutocompleteEnabled}
+              />
             </View>
           </>
         )}
diff --git a/packages/loot-design/src/components/budget/rollover/TransferTooltip.js b/packages/loot-design/src/components/budget/rollover/TransferTooltip.js
index 897419b77..8a22460f7 100644
--- a/packages/loot-design/src/components/budget/rollover/TransferTooltip.js
+++ b/packages/loot-design/src/components/budget/rollover/TransferTooltip.js
@@ -3,7 +3,8 @@ import React, { useState, useContext, useEffect } from 'react';
 import evalArithmetic from 'loot-core/src/shared/arithmetic';
 import { integerToCurrency, amountToInteger } from 'loot-core/src/shared/util';
 
-import CategoryAutocomplete from '../../CategorySelect';
+import NewCategoryAutocomplete from '../../CategoryAutocomplete';
+import LegacyCategoryAutocomplete from '../../CategorySelect';
 import { View, Button, Tooltip, InitialFocus, Input } from '../../common';
 import NamespaceContext from '../../spreadsheet/NamespaceContext';
 import SpreadsheetContext from '../../spreadsheet/SpreadsheetContext';
@@ -16,7 +17,12 @@ export default function TransferTooltip({
   tooltipProps,
   onSubmit,
   onClose,
+  isNewAutocompleteEnabled,
 }) {
+  const CategoryAutocomplete = isNewAutocompleteEnabled
+    ? NewCategoryAutocomplete
+    : LegacyCategoryAutocomplete;
+
   let spreadsheet = useContext(SpreadsheetContext);
   let sheetName = useContext(NamespaceContext);
   let categoryGroups = useContext(CategoryGroupsContext);
diff --git a/packages/loot-design/src/components/budget/rollover/rollover-components.js b/packages/loot-design/src/components/budget/rollover/rollover-components.js
index 559bbf806..333f0ef55 100644
--- a/packages/loot-design/src/components/budget/rollover/rollover-components.js
+++ b/packages/loot-design/src/components/budget/rollover/rollover-components.js
@@ -5,7 +5,8 @@ import evalArithmetic from 'loot-core/src/shared/arithmetic';
 import { integerToCurrency, amountToInteger } from 'loot-core/src/shared/util';
 
 import { styles, colors } from '../../../style';
-import CategoryAutocomplete from '../../CategorySelect';
+import NewCategoryAutocomplete from '../../CategoryAutocomplete';
+import LegacyCategoryAutocomplete from '../../CategorySelect';
 import {
   View,
   Text,
@@ -37,6 +38,7 @@ function CoverTooltip({
   tooltipProps,
   onSubmit,
   onClose,
+  isNewAutocompleteEnabled,
 }) {
   let categoryGroups = useContext(CategoryGroupsContext);
   categoryGroups = addToBeBudgetedGroup(
@@ -51,6 +53,10 @@ function CoverTooltip({
     }
   }
 
+  const CategoryAutocomplete = isNewAutocompleteEnabled
+    ? NewCategoryAutocomplete
+    : LegacyCategoryAutocomplete;
+
   return (
     <Tooltip
       position="bottom-right"
@@ -102,7 +108,13 @@ function CoverTooltip({
   );
 }
 
-function BalanceTooltip({ categoryId, tooltip, monthIndex, onBudgetAction }) {
+function BalanceTooltip({
+  categoryId,
+  tooltip,
+  monthIndex,
+  onBudgetAction,
+  isNewAutocompleteEnabled,
+}) {
   let carryover = useSheetValue(rolloverBudget.catCarryover(categoryId));
   let balance = useSheetValue(rolloverBudget.catBalance(categoryId));
   let [menu, setMenu] = useState('menu');
@@ -160,6 +172,7 @@ function BalanceTooltip({ categoryId, tooltip, monthIndex, onBudgetAction }) {
               to: toCategory,
             });
           }}
+          isNewAutocompleteEnabled={isNewAutocompleteEnabled}
         />
       )}
 
@@ -173,6 +186,7 @@ function BalanceTooltip({ categoryId, tooltip, monthIndex, onBudgetAction }) {
               from: fromCategory,
             });
           }}
+          isNewAutocompleteEnabled={isNewAutocompleteEnabled}
         />
       )}
     </>
@@ -292,6 +306,7 @@ export const ExpenseCategoryMonth = React.memo(function ExpenseCategoryMonth({
   onEdit,
   onBudgetAction,
   onShowActivity,
+  isNewAutocompleteEnabled,
 }) {
   let borderColor = colors.border;
   let balanceTooltip = useTooltip();
@@ -385,6 +400,7 @@ export const ExpenseCategoryMonth = React.memo(function ExpenseCategoryMonth({
             tooltip={balanceTooltip}
             monthIndex={monthIndex}
             onBudgetAction={onBudgetAction}
+            isNewAutocompleteEnabled={isNewAutocompleteEnabled}
           />
         )}
       </Field>
diff --git a/packages/loot-design/src/components/modals/EditField.js b/packages/loot-design/src/components/modals/EditField.js
index 44d1ff40b..53a4f6aca 100644
--- a/packages/loot-design/src/components/modals/EditField.js
+++ b/packages/loot-design/src/components/modals/EditField.js
@@ -9,7 +9,8 @@ import { amountToInteger } from 'loot-core/src/shared/util';
 
 import { colors } from '../../style';
 import LegacyAccountAutocomplete from '../AccountAutocomplete';
-import CategoryAutocomplete from '../CategorySelect';
+import NewCategoryAutocomplete from '../CategoryAutocomplete';
+import LegacyCategoryAutocomplete from '../CategorySelect';
 import { View, Modal, Input } from '../common';
 import DateSelect from '../DateSelect';
 import { SectionLabel } from '../forms';
@@ -56,6 +57,10 @@ function EditField({
     ? NewAccountAutocomplete
     : LegacyAccountAutocomplete;
 
+  const CategoryAutocomplete = isNewAutocompleteEnabled
+    ? NewCategoryAutocomplete
+    : LegacyCategoryAutocomplete;
+
   switch (name) {
     case 'date': {
       let today = currentDay();
diff --git a/packages/loot-design/src/components/modals/NordigenExternalMsg.js b/packages/loot-design/src/components/modals/NordigenExternalMsg.js
index ae659b9bf..e71be87bb 100644
--- a/packages/loot-design/src/components/modals/NordigenExternalMsg.js
+++ b/packages/loot-design/src/components/modals/NordigenExternalMsg.js
@@ -5,9 +5,9 @@ import { send } from 'loot-core/src/platform/client/fetch';
 import { colors } from '../../style';
 import AnimatedLoading from '../../svg/AnimatedLoading';
 import { Error } from '../alerts';
-import Autocomplete from '../Autocomplete';
 import { View, Modal, Button, P } from '../common';
 import { FormField, FormLabel } from '../forms';
+import Autocomplete from '../NewAutocomplete';
 
 import { COUNTRY_OPTIONS } from './countries';
 
@@ -27,7 +27,7 @@ function useAvailableBanks(country) {
 
       const results = await send('nordigen-get-banks', country);
 
-      setBanks(results);
+      setBanks(results.map(bank => ({ value: bank.id, label: bank.name })));
       setIsLoading(false);
     }
 
@@ -124,22 +124,12 @@ export default function NordigenExternalMsg({
         <FormField style={{ marginBottom: 10 }}>
           <FormLabel title="Choose your country:" htmlFor="country-field" />
           <Autocomplete
-            strict
             disabled={isConfigurationLoading}
-            suggestions={COUNTRY_OPTIONS}
+            options={COUNTRY_OPTIONS}
             onSelect={setCountry}
-            value={country}
-            inputProps={{
-              id: 'country-field',
-              placeholder: '(please select)',
-            }}
-            renderItems={(items, getItemProps, highlightedIndex) => (
-              <ItemList
-                items={items}
-                getItemProps={getItemProps}
-                highlightedIndex={highlightedIndex}
-              />
-            )}
+            value={COUNTRY_OPTIONS.find(({ value }) => value === country)}
+            inputId="country-field"
+            placeholder="(please select)"
           />
         </FormField>
 
@@ -150,22 +140,12 @@ export default function NordigenExternalMsg({
             <FormField>
               <FormLabel title="Choose your bank:" htmlFor="bank-field" />
               <Autocomplete
-                strict
                 focused
-                suggestions={bankOptions}
+                options={bankOptions}
                 onSelect={setInstitutionId}
-                value={institutionId}
-                inputProps={{
-                  id: 'bank-field',
-                  placeholder: '(please select)',
-                }}
-                renderItems={(items, getItemProps, highlightedIndex) => (
-                  <ItemList
-                    items={items}
-                    getItemProps={getItemProps}
-                    highlightedIndex={highlightedIndex}
-                  />
-                )}
+                value={bankOptions.find(({ value }) => value === institutionId)}
+                inputId="bank-field"
+                placeholder="(please select)"
               />
             </FormField>
           ))}
@@ -255,36 +235,3 @@ export default function NordigenExternalMsg({
     </Modal>
   );
 }
-
-export function ItemList({ items, getItemProps, highlightedIndex }) {
-  return (
-    <View
-      style={[
-        {
-          overflow: 'auto',
-          padding: '5px 0',
-          maxHeight: 175,
-        },
-      ]}
-    >
-      {items.map((item, idx) => (
-        <div
-          key={item.id}
-          {...(getItemProps ? getItemProps({ item }) : null)}
-          style={{
-            backgroundColor:
-              highlightedIndex === idx ? colors.n4 : 'transparent',
-            padding: 4,
-            paddingLeft: 20,
-            borderRadius: 0,
-          }}
-          data-testid={
-            'item' + (highlightedIndex === idx ? '-highlighted' : '')
-          }
-        >
-          {item.name}
-        </div>
-      ))}
-    </View>
-  );
-}
diff --git a/packages/loot-design/src/components/modals/countries.js b/packages/loot-design/src/components/modals/countries.js
index 91de29306..9277ec95c 100644
--- a/packages/loot-design/src/components/modals/countries.js
+++ b/packages/loot-design/src/components/modals/countries.js
@@ -1,126 +1,126 @@
 export const COUNTRY_OPTIONS = [
   {
-    id: 'AT',
-    name: 'Austria',
+    value: 'AT',
+    label: 'Austria',
   },
   {
-    id: 'BE',
-    name: 'Belgium',
+    value: 'BE',
+    label: 'Belgium',
   },
   {
-    id: 'BG',
-    name: 'Bulgaria',
+    value: 'BG',
+    label: 'Bulgaria',
   },
   {
-    id: 'HR',
-    name: 'Croatia',
+    value: 'HR',
+    label: 'Croatia',
   },
   {
-    id: 'CY',
-    name: 'Cyprus',
+    value: 'CY',
+    label: 'Cyprus',
   },
   {
-    id: 'CZ',
-    name: 'Czechia',
+    value: 'CZ',
+    label: 'Czechia',
   },
   {
-    id: 'DK',
-    name: 'Denmark',
+    value: 'DK',
+    label: 'Denmark',
   },
   {
-    id: 'EE',
-    name: 'Estonia',
+    value: 'EE',
+    label: 'Estonia',
   },
   {
-    id: 'FI',
-    name: 'Finland',
+    value: 'FI',
+    label: 'Finland',
   },
   {
-    id: 'FR',
-    name: 'France',
+    value: 'FR',
+    label: 'France',
   },
   {
-    id: 'DE',
-    name: 'Germany',
+    value: 'DE',
+    label: 'Germany',
   },
   {
-    id: 'GR',
-    name: 'Greece',
+    value: 'GR',
+    label: 'Greece',
   },
   {
-    id: 'HU',
-    name: 'Hungary',
+    value: 'HU',
+    label: 'Hungary',
   },
   {
-    id: 'IS',
-    name: 'Iceland',
+    value: 'IS',
+    label: 'Iceland',
   },
   {
-    id: 'IE',
-    name: 'Ireland',
+    value: 'IE',
+    label: 'Ireland',
   },
   {
-    id: 'IT',
-    name: 'Italy',
+    value: 'IT',
+    label: 'Italy',
   },
   {
-    id: 'LV',
-    name: 'Latvia',
+    value: 'LV',
+    label: 'Latvia',
   },
   {
-    id: 'LI',
-    name: 'Liechtenstein',
+    value: 'LI',
+    label: 'Liechtenstein',
   },
   {
-    id: 'LT',
-    name: 'Lithuania',
+    value: 'LT',
+    label: 'Lithuania',
   },
   {
-    id: 'LU',
-    name: 'Luxembourg',
+    value: 'LU',
+    label: 'Luxembourg',
   },
   {
-    id: 'MT',
-    name: 'Malta',
+    value: 'MT',
+    label: 'Malta',
   },
   {
-    id: 'NL',
-    name: 'Netherlands',
+    value: 'NL',
+    label: 'Netherlands',
   },
   {
-    id: 'NO',
-    name: 'Norway',
+    value: 'NO',
+    label: 'Norway',
   },
   {
-    id: 'PL',
-    name: 'Poland',
+    value: 'PL',
+    label: 'Poland',
   },
   {
-    id: 'PT',
-    name: 'Portugal',
+    value: 'PT',
+    label: 'Portugal',
   },
   {
-    id: 'RO',
-    name: 'Romania',
+    value: 'RO',
+    label: 'Romania',
   },
   {
-    id: 'SK',
-    name: 'Slovakia',
+    value: 'SK',
+    label: 'Slovakia',
   },
   {
-    id: 'SI',
-    name: 'Slovenia',
+    value: 'SI',
+    label: 'Slovenia',
   },
   {
-    id: 'ES',
-    name: 'Spain',
+    value: 'ES',
+    label: 'Spain',
   },
   {
-    id: 'SE',
-    name: 'Sweden',
+    value: 'SE',
+    label: 'Sweden',
   },
   {
-    id: 'GB',
-    name: 'United Kingdom',
+    value: 'GB',
+    label: 'United Kingdom',
   },
 ];
diff --git a/upcoming-release-notes/784.md b/upcoming-release-notes/784.md
new file mode 100644
index 000000000..4446470b4
--- /dev/null
+++ b/upcoming-release-notes/784.md
@@ -0,0 +1,6 @@
+---
+category: Maintenance
+authors: [MatissJanis]
+---
+
+Reafctor `Nordigen` and category Autocomplete to the new react-select component
-- 
GitLab