From 518ae72926376ab17e8bf6559397002611aa981e Mon Sep 17 00:00:00 2001
From: Robert Goldmann <deadlocker@gmx.de>
Date: Sun, 26 Feb 2023 17:23:22 +0100
Subject: [PATCH] #733 - show transaction name suggestions in csv import table

---
 .../TransactionImportController.java             |  1 +
 .../transactions/TransactionService.java         |  6 +++++-
 .../resources/static/js/transactionImport.js     | 16 +++++++++++++++-
 .../transactions/newTransactionMacros.ftl        |  4 ++++
 .../templates/transactions/transactionImport.ftl |  9 ++++++---
 5 files changed, 31 insertions(+), 5 deletions(-)

diff --git a/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/transactions/TransactionImportController.java b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/transactions/TransactionImportController.java
index 59b29e411..e5c8749e9 100644
--- a/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/transactions/TransactionImportController.java
+++ b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/transactions/TransactionImportController.java
@@ -91,6 +91,7 @@ public class TransactionImportController extends BaseController
 		}
 
 		model.addAttribute(ModelAttributes.CATEGORIES, categoryService.getAllEntitiesAsc());
+		model.addAttribute(TransactionModelAttributes.SUGGESTIONS_JSON, transactionService.getNameSuggestionsJson());
 		model.addAttribute(ModelAttributes.CSV_IMPORT_SETTINGS, csvImportSettingsService.getCsvImportSettings());
 
 		return ReturnValues.TRANSACTION_IMPORT;
diff --git a/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/transactions/TransactionService.java b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/transactions/TransactionService.java
index 7580ed774..a54b1cdb1 100644
--- a/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/transactions/TransactionService.java
+++ b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/transactions/TransactionService.java
@@ -295,12 +295,16 @@ public class TransactionService implements Resettable
 		model.addAttribute(TransactionModelAttributes.CATEGORIES, categoryService.getAllEntitiesAsc());
 		model.addAttribute(TransactionModelAttributes.ACCOUNTS, accounts);
 		model.addAttribute(TransactionModelAttributes.TRANSACTION, item);
+		model.addAttribute(TransactionModelAttributes.SUGGESTIONS_JSON, getNameSuggestionsJson());
+	}
 
+	public String getNameSuggestionsJson()
+	{
 		final List<Transaction> allByOrderByDateDesc = getRepository().findAllByOrderByDateDesc();
 		final List<String> nameSuggestions = allByOrderByDateDesc.stream()
 				.map(Transaction::getName)
 				.distinct()
 				.toList();
-		model.addAttribute(TransactionModelAttributes.SUGGESTIONS_JSON, GSON.toJson(nameSuggestions));
+		return  GSON.toJson(nameSuggestions);
 	}
 }
diff --git a/BudgetMasterServer/src/main/resources/static/js/transactionImport.js b/BudgetMasterServer/src/main/resources/static/js/transactionImport.js
index 5c048b162..9dbca0238 100644
--- a/BudgetMasterServer/src/main/resources/static/js/transactionImport.js
+++ b/BudgetMasterServer/src/main/resources/static/js/transactionImport.js
@@ -12,10 +12,24 @@ $(document).ready(function()
         order: [[1, 'desc']],
         info: false,
         scrollX: true,
-        scrollY: true,
+        scrollY: false,
         columnDefs: [
             { orderable: false, targets:  5}
         ],
         language: { search: '' , searchPlaceholder: localizedSearch},
     });
+
+    if(transactionNameSuggestions !== undefined)
+    {
+        let nameElements = document.querySelectorAll('.autocomplete');
+        let autoCompleteInstances = M.Autocomplete.init(nameElements, {
+            data: transactionNameSuggestions,
+        });
+
+        // prevent tab traversal for dropdown (otherwise "tab" needs to be hit twice to jump from name input to amount input)
+        for(let i = 0; i < autoCompleteInstances.length; i++)
+        {
+            autoCompleteInstances[i].dropdown.dropdownEl.tabIndex = -1;
+        }
+    }
 });
\ No newline at end of file
diff --git a/BudgetMasterServer/src/main/resources/templates/transactions/newTransactionMacros.ftl b/BudgetMasterServer/src/main/resources/templates/transactions/newTransactionMacros.ftl
index a6bfaec7f..6e67af647 100644
--- a/BudgetMasterServer/src/main/resources/templates/transactions/newTransactionMacros.ftl
+++ b/BudgetMasterServer/src/main/resources/templates/transactions/newTransactionMacros.ftl
@@ -62,6 +62,10 @@
         </div>
     </div>
 
+    <@insertNameSuggestions/>
+</#macro>
+
+<#macro insertNameSuggestions>
     <script>
         transactionNameSuggestions = {};
         var nameSuggestions = ${suggestionsJSON};
diff --git a/BudgetMasterServer/src/main/resources/templates/transactions/transactionImport.ftl b/BudgetMasterServer/src/main/resources/templates/transactions/transactionImport.ftl
index f963b0f5b..7d9ee3d8c 100644
--- a/BudgetMasterServer/src/main/resources/templates/transactions/transactionImport.ftl
+++ b/BudgetMasterServer/src/main/resources/templates/transactions/transactionImport.ftl
@@ -15,6 +15,7 @@
         <@navbar.navbar "importCSV" settings/>
 
         <#import "transactionsMacros.ftl" as transactionMacros>
+        <#import "newTransactionMacros.ftl" as newTransactionMacros>
         <#import "../helpers/customSelectMacros.ftl" as customSelectMacros>
 
         <main>
@@ -246,14 +247,14 @@
 
             <tbody>
                 <#list csvTransactions as csvTransaction>
-                    <@renderCsvRow csvTransaction csvTransaction?index/>
+                    <@renderCsvTransaction csvTransaction csvTransaction?index/>
                 </#list>
             </tbody>
         </table>
     </div>
 </#macro>
 
-<#macro renderCsvRow csvTransaction index>
+<#macro renderCsvTransaction csvTransaction index>
     <tr class="transaction-import-row <#if csvTransaction.getStatus().name() == 'SKIPPED'>transaction-import-row-skipped</#if>">
         <form name="NewTransactionInPlace" method="POST" action="<@s.url '/transactionImport/' + index + '/newTransactionInPlace'/>">
             <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
@@ -264,7 +265,7 @@
             </td>
             <td data-order="${csvTransaction.getName()}" data-search="${csvTransaction.getName()}">
                 <div class="input-field no-margin-top no-margin-bottom">
-                    <input class="no-margin-bottom" type="text" name="name" required value="${csvTransaction.getName()}" <#if csvTransaction.getStatus().name() == 'SKIPPED'>disabled</#if>>
+                    <input class="no-margin-bottom autocomplete" type="text" name="name" autocomplete="off" required value="${csvTransaction.getName()}" <#if csvTransaction.getStatus().name() == 'SKIPPED'>disabled</#if>>
                 </div>
             </td>
             <td data-order="${csvTransaction.getDescription()}" data-search="${csvTransaction.getDescription()}">
@@ -302,6 +303,8 @@
             </td>
         </form>
     </tr>
+
+    <@newTransactionMacros.insertNameSuggestions/>
 </#macro>
 
 <#macro showColumnSettingsErrors>
-- 
GitLab