Skip to content

Commit

Permalink
Merge pull request #128 from TheAxelander/124_import_page_dialogs
Browse files Browse the repository at this point in the history
Merge changes for version 1.6.3
  • Loading branch information
TheAxelander authored Jan 27, 2023
2 parents 16e8bb6 + 7890233 commit e7f1152
Show file tree
Hide file tree
Showing 5 changed files with 124 additions and 44 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
### 1.6.3 (2023-01-27)

* [Add] Several Confirmation Dialogs for Import Profile handling [#124](https://github.com/TheAxelander/OpenBudgeteer/issues/124)
* [Fixed] Proper reset of values after deleting an Import Profile [#125](https://github.com/TheAxelander/OpenBudgeteer/issues/125)
* [Fixed] Overall improved and fixed error handling on Import Page

### 1.6.2 (2023-01-11)

* [Fixed] Due to implemented fix for [#114](https://github.com/TheAxelander/OpenBudgeteer/issues/114) Column mapping on Import Page was not working properly [#121](https://github.com/TheAxelander/OpenBudgeteer/issues/121) [#122](https://github.com/TheAxelander/OpenBudgeteer/issues/122)
Expand Down
93 changes: 66 additions & 27 deletions OpenBudgeteer.Blazor/Pages/Import.razor
Original file line number Diff line number Diff line change
Expand Up @@ -50,20 +50,20 @@
<div class="mb-3">
@if (_step4Enabled)
{
<button class="btn btn-sm btn-primary header-action-button" @onclick=@(() => HandleResult(_dataContext.CreateProfile()))>Create Profile</button>
<button class="btn btn-sm btn-primary header-action-button" @onclick=@(() => HandleResult(_dataContext.CreateProfile(), "Profile has been created."))>Create Profile</button>
}
@if (_dataContext.SelectedImportProfile != null && _dataContext.SelectedImportProfile.ImportProfileId != 0)
@if (_dataContext.SelectedImportProfile is {ImportProfileId: > 0 })
{
<button class="btn btn-sm btn-primary header-action-button" @onclick=@(() => HandleResult(_dataContext.SaveProfile()))>Save Profile</button>
<button class="btn btn-sm btn-danger header-action-button" @onclick=@(() => HandleResult(_dataContext.DeleteProfile()))>Delete Profile</button>
<button class="btn btn-sm btn-primary header-action-button" @onclick=@(() => HandleResult(_dataContext.SaveProfile(), "Changes for Profile have been saved."))>Save Profile</button>
<button class="btn btn-sm btn-danger header-action-button" @onclick=@(() => _isDeleteConfirmationDialogVisible = true)>Delete Profile</button>
}
</div>
<div class="row mb-3">
<div class="col">
<label class="form-label">Import Profile:</label>
<ObjectSelect
GetSelectedItemIdHandler="@(e => e.ImportProfileId.ToString())"
SetSelectedItemHandler="@(e => _dataContext.AvailableImportProfiles.FirstOrDefault(i => i.ImportProfileId == Convert.ToInt32(e), dummyImportProfile))"
SetSelectedItemHandler="@(e => _dataContext.AvailableImportProfiles.FirstOrDefault(i => i.ImportProfileId == Convert.ToInt32(e), _dummyImportProfile))"
@bind-SelectedItem="@_dataContext.SelectedImportProfile"
AvailableItems="@_dataContext.AvailableImportProfiles"
OnSelectedItemChanged="@ImportProfile_SelectionChanged"
Expand All @@ -81,7 +81,7 @@
<label class="form-label">Target Account:</label>
<ObjectSelect
GetSelectedItemIdHandler="@(e => e.AccountId.ToString())"
SetSelectedItemHandler="@(e => _dataContext.AvailableAccounts.FirstOrDefault(i => i.AccountId == Convert.ToInt32(e), dummyAccount))"
SetSelectedItemHandler="@(e => _dataContext.AvailableAccounts.FirstOrDefault(i => i.AccountId == Convert.ToInt32(e), _dummyAccount))"
@bind-SelectedItem="@_dataContext.SelectedAccount"
AvailableItems="@_dataContext.AvailableAccounts"
OnSelectedItemChanged="@TargetAccount_SelectionChanged"
Expand Down Expand Up @@ -452,6 +452,21 @@
<div class="modal-backdrop fade show"></div>
}

<InfoDialog
Title="Import"
Message="@_infoDialogMessage"
IsDialogVisible="@_isInfoDialogVisible"
OnCloseClickCallback="@(() => _isInfoDialogVisible = false)"
/>

<DeleteConfirmationDialog
Title="Delete Import Profile"
Message="Do you really want to delete the selected Import Profile?"
IsDialogVisible="@_isDeleteConfirmationDialogVisible"
OnDeleteClickCallback="@DeleteProfile"
OnCancelClickCallback="@(() => _isDeleteConfirmationDialogVisible = false)"
/>

<ErrorMessageDialog
Title="Import"
Message="@_errorModalDialogMessage"
Expand All @@ -464,20 +479,22 @@
ElementReference _inputElement;
ElementReference _step1AccordionButtonElement;

readonly int _placeholderItemId = -1;
readonly string _placeholderItemValue = "___PlaceholderItem___";
const int PlaceholderItemId = -1;
const string PlaceholderItemValue = "___PlaceholderItem___";
const string DummyColumn = "---Select Column---";

ImportProfile dummyImportProfile = new ImportProfile()
readonly ImportProfile _dummyImportProfile = new()
{
ImportProfileId = -1,
ProfileName = "---Select Import Profile---"
ImportProfileId = PlaceholderItemId,
ProfileName = "---Select Import Profile---",
AccountId = PlaceholderItemId
};
OpenBudgeteer.Core.Models.Account dummyAccount = new OpenBudgeteer.Core.Models.Account()

readonly OpenBudgeteer.Core.Models.Account _dummyAccount = new()
{
AccountId = -1,
AccountId = PlaceholderItemId,
Name = "---Select Target Account---"
};
string dummyColumn = "---Select Column---";

bool _step2Enabled;
bool _step3Enabled;
Expand All @@ -492,6 +509,11 @@
bool _isConfirmationModalDialogVisible;
string _importConfirmationMessage;

bool _isInfoDialogVisible;
string _infoDialogMessage;

bool _isDeleteConfirmationDialogVisible;

bool _isErrorModalDialogVisible;
string _errorModalDialogMessage;

Expand All @@ -514,21 +536,21 @@
void LoadData()
{
HandleResult(_dataContext.LoadData());
_dataContext.AvailableImportProfiles.Insert(0, dummyImportProfile);
_dataContext.AvailableAccounts.Insert(0, dummyAccount);
_dataContext.SelectedImportProfile = dummyImportProfile;
_dataContext.IdentifiedColumns.Insert(0, dummyColumn);
_dataContext.SelectedAccount = dummyAccount;
_dataContext.AvailableImportProfiles.Insert(0, _dummyImportProfile);
_dataContext.AvailableAccounts.Insert(0, _dummyAccount);
_dataContext.SelectedImportProfile = _dummyImportProfile;
_dataContext.IdentifiedColumns.Insert(0, DummyColumn);
_dataContext.SelectedAccount = _dummyAccount;
}

async Task ReadFileAsync()
{
_step2Enabled = false;
_step3Enabled = false;
_step4Enabled = false;
_dataContext.SelectedImportProfile = dummyImportProfile;
_dataContext.IdentifiedColumns.Insert(0, dummyColumn);
_dataContext.SelectedAccount = dummyAccount;
_dataContext.SelectedImportProfile = _dummyImportProfile;
_dataContext.IdentifiedColumns.Insert(0, DummyColumn);
_dataContext.SelectedAccount = _dummyAccount;

var file = (await FileReaderService.CreateReference(_inputElement).EnumerateFilesAsync()).FirstOrDefault();
if (file == null) return;
Expand All @@ -541,7 +563,7 @@
var result = await _dataContext.LoadProfileAsync();
if (result.IsSuccessful)
{
_step3Enabled = _dataContext.SelectedImportProfile.ImportProfileId != 0;
_step3Enabled = _dataContext.SelectedImportProfile.ImportProfileId > 0;
CheckColumnMapping();
StateHasChanged();
}
Expand All @@ -551,6 +573,18 @@
}
}

void DeleteProfile()
{
_isDeleteConfirmationDialogVisible = false;
HandleResult(_dataContext.DeleteProfile());
if (_dataContext.SelectedImportProfile.ImportProfileId < 1)
{
_dataContext.SelectedImportProfile = _dummyImportProfile;
_dataContext.AvailableImportProfiles.Insert(0, _dummyImportProfile);
_dataContext.SelectedAccount = _dummyAccount;
}
}

void LoadHeaders()
{
var result = _dataContext.LoadHeaders();
Expand All @@ -568,13 +602,13 @@
{
_step4Enabled = false;
if (string.IsNullOrEmpty(_dataContext.SelectedImportProfile.TransactionDateColumnName) ||
_dataContext.SelectedImportProfile.TransactionDateColumnName == _placeholderItemValue) return;
_dataContext.SelectedImportProfile.TransactionDateColumnName == PlaceholderItemValue) return;
// Make Payee optional
//if (string.IsNullOrEmpty(_dataContext.PayeeColumn) || _dataContext.PayeeColumn == _placeholderItemValue) return;
if (string.IsNullOrEmpty(_dataContext.SelectedImportProfile.MemoColumnName) ||
_dataContext.SelectedImportProfile.MemoColumnName == _placeholderItemValue) return;
_dataContext.SelectedImportProfile.MemoColumnName == PlaceholderItemValue) return;
if (string.IsNullOrEmpty(_dataContext.SelectedImportProfile.AmountColumnName) ||
_dataContext.SelectedImportProfile.AmountColumnName == _placeholderItemValue) return;
_dataContext.SelectedImportProfile.AmountColumnName == PlaceholderItemValue) return;
_step4Enabled = true;
}

Expand Down Expand Up @@ -646,12 +680,17 @@
_dataContext.SelectedImportProfile.AdditionalSettingCreditValue = value;
}

void HandleResult(ViewModelOperationResult result)
void HandleResult(ViewModelOperationResult result, string successMessage = "")
{
if (!result.IsSuccessful)
{
_errorModalDialogMessage = result.Message;
_isErrorModalDialogVisible = true;
return;
}
if (string.IsNullOrEmpty(successMessage)) return;

_infoDialogMessage = successMessage;
_isInfoDialogVisible = true;
}
}
32 changes: 32 additions & 0 deletions OpenBudgeteer.Blazor/Shared/InfoDialog.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
@if (IsDialogVisible)
{
<div class="modal fade show" style="display: block;">
<div class="modal-dialog modal-dialog-scrollable">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">@Title</h4>
<button type="button" class="btn-close" data-dismiss="modal" @onclick="OnCloseClickCallback"></button>
</div>
<div class="modal-body">@Message</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" data-dismiss="modal" @onclick="OnCloseClickCallback">Ok</button>
</div>
</div>
</div>
</div>
<div class="modal-backdrop fade show"></div>
}

@code {
[Parameter]
public string Title { get; set; }

[Parameter]
public string Message { get; set; }

[Parameter]
public bool IsDialogVisible { get; set; }

[Parameter]
public EventCallback<MouseEventArgs> OnCloseClickCallback { get; set; }
}
2 changes: 1 addition & 1 deletion OpenBudgeteer.Blazor/Shared/NavMenu.razor
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@
<div class="col-md-auto">
<div class="navbar-text">
<span>
Version: 1.6.2 (<a href="https://github.com/TheAxelander/OpenBudgeteer/blob/master/CHANGELOG.md" target="_blank">Change Log</a>)
Version: 1.6.3 (<a href="https://github.com/TheAxelander/OpenBudgeteer/blob/master/CHANGELOG.md" target="_blank">Change Log</a>)
</span>
</div>
</div>
Expand Down
35 changes: 19 additions & 16 deletions OpenBudgeteer.Core/ViewModels/ImportDataViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ public ImportProfile SelectedImportProfile
{
// Load Headers already to prevent hiccups with other SelectedItem properties from Column Mappings
// as they depend on SelectedImportProfile
if (value != null) LoadHeaders(value);
if (value is { HeaderRow: > 0 }) LoadHeaders(value);
Set(ref _selectedImportProfile, value);
}
}
Expand Down Expand Up @@ -433,18 +433,12 @@ public ViewModelOperationResult LoadHeaders()
// If possible and necessary make initial selections after loading headers
if (IdentifiedColumns.Count == 0) return result;
var firstSelection = IdentifiedColumns.First();
if (string.IsNullOrEmpty(SelectedImportProfile.TransactionDateColumnName))
SelectedImportProfile.TransactionDateColumnName = firstSelection;
if (string.IsNullOrEmpty(SelectedImportProfile.PayeeColumnName))
SelectedImportProfile.PayeeColumnName = firstSelection;
if (string.IsNullOrEmpty(SelectedImportProfile.MemoColumnName))
SelectedImportProfile.MemoColumnName = firstSelection;
if (string.IsNullOrEmpty(SelectedImportProfile.AmountColumnName))
SelectedImportProfile.AmountColumnName = firstSelection;
if (string.IsNullOrEmpty(SelectedImportProfile.CreditColumnName))
SelectedImportProfile.CreditColumnName = firstSelection;
if (string.IsNullOrEmpty(SelectedImportProfile.CreditColumnIdentifierColumnName))
SelectedImportProfile.CreditColumnIdentifierColumnName = firstSelection;
SelectedImportProfile.TransactionDateColumnName = firstSelection;
SelectedImportProfile.PayeeColumnName = firstSelection;
SelectedImportProfile.MemoColumnName = firstSelection;
SelectedImportProfile.AmountColumnName = firstSelection;
SelectedImportProfile.CreditColumnName = firstSelection;
SelectedImportProfile.CreditColumnIdentifierColumnName = firstSelection;

return result;
}
Expand All @@ -458,13 +452,16 @@ public ViewModelOperationResult LoadHeaders(ImportProfile importProfile)
{
try
{
if (importProfile.HeaderRow < 1 || importProfile.HeaderRow > _fileLines.Length)
throw new Exception("Cannot read headers with given header row.");

// Set ComboBox selection for Column Mapping
IdentifiedColumns.Clear();
var headerLine = _fileLines[importProfile.HeaderRow - 1];
var columns = headerLine.Split(importProfile.Delimiter);
foreach (var column in columns)
{
if (column != string.Empty)
if (!string.IsNullOrEmpty(column))
IdentifiedColumns.Add(column.Trim(importProfile.TextQualifier)); // Exclude TextQualifier
}

Expand Down Expand Up @@ -502,6 +499,11 @@ public async Task<ViewModelOperationResult> ValidateDataAsync()
{
try
{
// Run pre-checks
if (string.IsNullOrEmpty(SelectedImportProfile.NumberFormat)) throw new Exception("Missing Number Format");
if (string.IsNullOrEmpty(SelectedImportProfile.DateFormat)) throw new Exception("Missing Date Format");
if (SelectedImportProfile.AccountId < 1) throw new Exception("No target account selected");

// Pre-Load Data for verification
// Initialize CsvReader
var options = new Options(SelectedImportProfile.TextQualifier, '\\', SelectedImportProfile.Delimiter);
Expand Down Expand Up @@ -707,7 +709,7 @@ public ViewModelOperationResult SaveProfile()
}

/// <summary>
/// Deletes the <see cref="ImportProfile"/> in the database based on <see cref="SelectedImportProfile"/>
/// Deletes the <see cref="ImportProfile"/> from the database based on <see cref="SelectedImportProfile"/>
/// </summary>
/// <returns>Object which contains information and results of this method</returns>
public ViewModelOperationResult DeleteProfile()
Expand All @@ -718,7 +720,8 @@ public ViewModelOperationResult DeleteProfile()
{
dbContext.DeleteImportProfile(SelectedImportProfile);
}
ResetLoadedProfileData();
//ResetLoadedProfileData();
SelectedImportProfile = new();
LoadAvailableProfiles();

return new ViewModelOperationResult(true);
Expand Down

0 comments on commit e7f1152

Please sign in to comment.