From 239d1612dd102659ed28e12e5cc02548ad058713 Mon Sep 17 00:00:00 2001 From: Robert Goldmann <deadlocker@gmx.de> Date: Sun, 23 Apr 2023 18:25:00 +0200 Subject: [PATCH] #742 - avoid page reload on skip and undo skip --- .../TransactionImportController.java | 41 +++++++++++---- .../resources/static/js/transactionImport.js | 52 ++++++++++++++++++- .../resources/templates/helpers/header.ftl | 3 +- .../transactions/transactionImportMacros.ftl | 7 +-- .../transactions/transactionImportRow.ftl | 3 ++ 5 files changed, 92 insertions(+), 14 deletions(-) create mode 100644 BudgetMasterServer/src/main/resources/templates/transactions/transactionImportRow.ftl 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 2644ca87e..de5e23439 100644 --- a/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/transactions/TransactionImportController.java +++ b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/transactions/TransactionImportController.java @@ -5,6 +5,7 @@ import de.deadlocker8.budgetmaster.categories.CategoryService; import de.deadlocker8.budgetmaster.controller.BaseController; import de.deadlocker8.budgetmaster.transactions.csvimport.*; import de.deadlocker8.budgetmaster.utils.Mappings; +import de.deadlocker8.budgetmaster.utils.ResourceNotFoundException; import de.deadlocker8.budgetmaster.utils.WebRequestUtils; import de.deadlocker8.budgetmaster.utils.notification.Notification; import de.deadlocker8.budgetmaster.utils.notification.NotificationType; @@ -32,6 +33,8 @@ public class TransactionImportController extends BaseController public static final String ERROR = "error"; public static final String CATEGORIES = "categories"; public static final String CSV_IMPORT_SETTINGS = "csvImportSettings"; + public static final String CSV_TRANSACTION = "csvTransaction"; + public static final String CSV_TRANSACTION_INDEX = "csvTransactionIndex"; } private static class ReturnValues @@ -41,6 +44,7 @@ public class TransactionImportController extends BaseController public static final String REDIRECT_CANCEL = "redirect:/transactionImport/cancel"; public static final String NEW_TRANSACTION_NORMAL = "transactions/newTransactionNormal"; public static final String NEW_TRANSACTION_TRANSFER = "transactions/newTransactionTransfer"; + public static final String TRANSACTION_IMPORT_ROW = "transactions/transactionImportRow"; public static final String REDIRECT_TEMPLATES = "redirect:/templates"; } @@ -201,29 +205,41 @@ public class TransactionImportController extends BaseController } @GetMapping("/{index}/skip") - public String skip(WebRequest request, @PathVariable("index") Integer index) + public String skip(Model model, WebRequest request, @PathVariable("index") Integer index) { final Optional<CsvTransaction> transactionOptional = getTransactionByIndex(request, index); if(transactionOptional.isEmpty()) { - return ReturnValues.REDIRECT_IMPORT; + throw new ResourceNotFoundException(); } - transactionOptional.get().setStatus(CsvTransactionStatus.SKIPPED); - return ReturnValues.REDIRECT_IMPORT; + final CsvTransaction csvTransaction = transactionOptional.get(); + csvTransaction.setStatus(CsvTransactionStatus.SKIPPED); + + model.addAttribute(ModelAttributes.CATEGORIES, categoryService.getAllEntitiesAsc()); + model.addAttribute(TransactionModelAttributes.SUGGESTIONS_JSON, transactionService.getNameSuggestionsJson()); + model.addAttribute(ModelAttributes.CSV_TRANSACTION, csvTransaction); + model.addAttribute(ModelAttributes.CSV_TRANSACTION_INDEX, index); + return ReturnValues.TRANSACTION_IMPORT_ROW; } @GetMapping("/{index}/undoSkip") - public String undoSkip(WebRequest request, @PathVariable("index") Integer index) + public String undoSkip(Model model, WebRequest request, @PathVariable("index") Integer index) { final Optional<CsvTransaction> transactionOptional = getTransactionByIndex(request, index); if(transactionOptional.isEmpty()) { - return ReturnValues.REDIRECT_IMPORT; + throw new ResourceNotFoundException(); } - transactionOptional.get().setStatus(CsvTransactionStatus.PENDING); - return ReturnValues.REDIRECT_IMPORT; + final CsvTransaction csvTransaction = transactionOptional.get(); + csvTransaction.setStatus(CsvTransactionStatus.PENDING); + + model.addAttribute(ModelAttributes.CATEGORIES, categoryService.getAllEntitiesAsc()); + model.addAttribute(TransactionModelAttributes.SUGGESTIONS_JSON, transactionService.getNameSuggestionsJson()); + model.addAttribute(ModelAttributes.CSV_TRANSACTION, csvTransaction); + model.addAttribute(ModelAttributes.CSV_TRANSACTION_INDEX, index); + return ReturnValues.TRANSACTION_IMPORT_ROW; } @GetMapping("/{index}/newTransaction/{type}") @@ -309,6 +325,13 @@ public class TransactionImportController extends BaseController } final List<CsvTransaction> csvTransactions = (List<CsvTransaction>) attribute; - return Optional.of(csvTransactions.get(index)); + try + { + return Optional.of(csvTransactions.get(index)); + } + catch(IndexOutOfBoundsException e) + { + return Optional.empty(); + } } } \ No newline at end of file diff --git a/BudgetMasterServer/src/main/resources/static/js/transactionImport.js b/BudgetMasterServer/src/main/resources/static/js/transactionImport.js index 9dbca0238..e4c29c1ec 100644 --- a/BudgetMasterServer/src/main/resources/static/js/transactionImport.js +++ b/BudgetMasterServer/src/main/resources/static/js/transactionImport.js @@ -32,4 +32,54 @@ $(document).ready(function() autoCompleteInstances[i].dropdown.dropdownEl.tabIndex = -1; } } -}); \ No newline at end of file + + initCsvTransactionButtons(); +}); + +function initCsvTransactionButtons() +{ + const buttonsSkip = document.getElementsByClassName('button-request-transaction-import-skip'); + for(let i = 0; i < buttonsSkip.length; i++) + { + const button = buttonsSkip[i]; + button.addEventListener('click', function() + { + performCsvTransactionGetRequestWithoutReload(button, 'Error skipping transaction'); + }); + } + + const buttonsUndoSkip = document.getElementsByClassName('button-request-transaction-import-undo-skip'); + for(let i = 0; i < buttonsUndoSkip.length; i++) + { + const button = buttonsUndoSkip[i]; + button.addEventListener('click', function() + { + performCsvTransactionGetRequestWithoutReload(button, 'Error undo skip transaction'); + }); + } +} + +function performCsvTransactionGetRequestWithoutReload(button, errorMessage) +{ + const url = button.dataset.url; + const csvTransactionId = button.dataset.index; + + $.ajax({ + type: 'GET', + url: url, + data: {}, + success: function(data) + { + $('#transaction-import-row-' + csvTransactionId).replaceWith(data); + initCsvTransactionButtons(); + }, + error: function(response) + { + M.toast({ + html: errorMessage, + classes: 'red' + }); + console.error(response); + } + }); +} diff --git a/BudgetMasterServer/src/main/resources/templates/helpers/header.ftl b/BudgetMasterServer/src/main/resources/templates/helpers/header.ftl index b5bf1ddc7..094800aa0 100644 --- a/BudgetMasterServer/src/main/resources/templates/helpers/header.ftl +++ b/BudgetMasterServer/src/main/resources/templates/helpers/header.ftl @@ -136,9 +136,10 @@ </button> </#macro> -<#macro buttonFlat url icon localizationKey id="" classes="" isDataUrl=false noUrl=false iconClasses='' target=''> +<#macro buttonFlat url icon localizationKey id="" classes="" isDataUrl=false noUrl=false iconClasses='' target='' datasetIndex=''> <a <#if target?has_content>target="${target}"</#if> <#if !isDataUrl && !noUrl>href="<@s.url url/>"</#if> id="${id}" + <#if datasetIndex?has_content>data-index="${datasetIndex}"</#if> class="waves-effect waves-light btn-flat ${classes}" <#if isDataUrl>data-url="${url}"</#if>> <i class="material-icons left <#if !localizationKey?has_content>no-margin</#if> ${iconClasses}">${icon}</i><#if localizationKey?has_content><span>${locale.getString(localizationKey)}</span></#if> diff --git a/BudgetMasterServer/src/main/resources/templates/transactions/transactionImportMacros.ftl b/BudgetMasterServer/src/main/resources/templates/transactions/transactionImportMacros.ftl index a725ea86f..fae7d580a 100644 --- a/BudgetMasterServer/src/main/resources/templates/transactions/transactionImportMacros.ftl +++ b/BudgetMasterServer/src/main/resources/templates/transactions/transactionImportMacros.ftl @@ -1,4 +1,5 @@ <#import "../helpers/header.ftl" as header> +<@header.globals/> <#import "../helpers/validation.ftl" as validation> <#import "/spring.ftl" as s> @@ -187,7 +188,7 @@ </#macro> <#macro renderCsvTransaction csvTransaction index> - <tr class="transaction-import-row <#if csvTransaction.getStatus().name() == 'SKIPPED'>transaction-import-row-skipped</#if>"> + <tr class="transaction-import-row <#if csvTransaction.getStatus().name() == 'SKIPPED'>transaction-import-row-skipped</#if>" id="transaction-import-row-${index}"> <form name="NewTransactionInPlace" method="POST" action="<@s.url '/transactionImport/' + index + '/newTransactionInPlace'/>"> <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/> <td data-order="${locale.getString(csvTransaction.getStatus().getLocalizationKey())}" data-search="${locale.getString(csvTransaction.getStatus().getLocalizationKey())}"><@statusBanner csvTransaction.getStatus()/></td> @@ -208,7 +209,7 @@ <td data-order="${currencyService.getCurrencyString(csvTransaction.getAmount())}" data-search="${currencyService.getCurrencyString(csvTransaction.getAmount())}">${currencyService.getCurrencyString(csvTransaction.getAmount())}</td> <td> <#if csvTransaction.getStatus().name() == 'SKIPPED'> - <@header.buttonFlat url='/transactionImport/' + index + '/undoSkip' isDataUrl=true icon='do_disturb_off' localizationKey='' classes="no-padding text-default button-request-transaction-import-undo-skip"/> + <@header.buttonFlat url='/transactionImport/' + index + '/undoSkip' isDataUrl=true icon='do_disturb_off' localizationKey='' classes="no-padding text-default button-request-transaction-import-undo-skip" datasetIndex=index/> <#else> <@header.buttonSubmit name='action' icon='save' localizationKey='' classes='text-white'/> <div class="fixed-action-btn edit-transaction-button"> @@ -230,7 +231,7 @@ </li> </ul> </div> - <@header.buttonFlat url='/transactionImport/' + index + '/skip' isDataUrl=true icon='do_not_disturb_on' localizationKey='' classes="no-padding text-default button-request-transaction-import-skip"/> + <@header.buttonFlat url='/transactionImport/' + index + '/skip' isDataUrl=true icon='do_not_disturb_on' localizationKey='' classes="no-padding text-default button-request-transaction-import-skip" datasetIndex=index/> </#if> </td> </form> diff --git a/BudgetMasterServer/src/main/resources/templates/transactions/transactionImportRow.ftl b/BudgetMasterServer/src/main/resources/templates/transactions/transactionImportRow.ftl new file mode 100644 index 000000000..7b47dfbec --- /dev/null +++ b/BudgetMasterServer/src/main/resources/templates/transactions/transactionImportRow.ftl @@ -0,0 +1,3 @@ +<#import "transactionImportMacros.ftl" as transactionImportMacros> + +<@transactionImportMacros.renderCsvTransaction csvTransaction csvTransactionIndex/> \ No newline at end of file -- GitLab