diff --git a/.github/workflows/windows_e2e_tests.yml b/.github/workflows/windows_e2e_tests.yml
index c5d6c001..44379f3e 100644
--- a/.github/workflows/windows_e2e_tests.yml
+++ b/.github/workflows/windows_e2e_tests.yml
@@ -52,7 +52,24 @@ jobs:
shell: powershell
run: |
Import-Module Appx
- .\TransactionProcessor.Mobile/bin/Release\net10.0-windows10.0.19041.0\win-x64\AppPackages\TransactionProcessor.Mobile_1.0.0.1_Test\Install.ps1 -Force
+ $candidatePaths = @(
+ (Join-Path $env:GITHUB_WORKSPACE "TransactionProcessor.Mobile\AppPackages"),
+ (Join-Path $env:GITHUB_WORKSPACE "TransactionProcessor.Mobile\bin\Release\net10.0-windows10.0.19041.0\win-x64\AppPackages")
+ )
+ $appPackagesPath = $candidatePaths | Where-Object { Test-Path $_ } | Select-Object -First 1
+ if ($null -eq $appPackagesPath) {
+ throw "Unable to find AppPackages under: $($candidatePaths -join ', ')"
+ }
+ $installScript = Get-ChildItem -Path $appPackagesPath -Recurse -Filter Install.ps1 | Select-Object -First 1
+ if ($null -ne $installScript) {
+ & $installScript.FullName -Force
+ } else {
+ $msixPackage = Get-ChildItem -Path $appPackagesPath -Recurse -Filter *.msix | Select-Object -First 1
+ if ($null -eq $msixPackage) {
+ throw "Unable to find Install.ps1 or .msix package under $appPackagesPath."
+ }
+ Add-AppxPackage -Path $msixPackage.FullName -ForceApplicationShutdown
+ }
- name: Run Windows End To End Tests
run: dotnet test TransactionProcessor.Mobile.UiTests/TransactionProcessor.Mobile.UiTests.csproj --filter "Category=PRTest&Category=Windows" --no-restore
diff --git a/.github/workflows/windows_navigation_tests.yml b/.github/workflows/windows_navigation_tests.yml
index ec29481f..eece6866 100644
--- a/.github/workflows/windows_navigation_tests.yml
+++ b/.github/workflows/windows_navigation_tests.yml
@@ -48,11 +48,43 @@ jobs:
run: |
dotnet publish TransactionProcessor.Mobile/TransactionProcessor.Mobile.csproj -c Release -f net10.0-windows10.0.19041.0 /p:AppxPackageSigningEnabled=true /p:PackageCertificateThumbprint="${{ secrets.WINDOWSSIGNINGCERTTHUMBPRINT }}"
+ - name: Debug AppPackages contents
+ shell: powershell
+ run: |
+ $candidatePaths = @(
+ (Join-Path $env:GITHUB_WORKSPACE "TransactionProcessor.Mobile\AppPackages"),
+ (Join-Path $env:GITHUB_WORKSPACE "TransactionProcessor.Mobile\bin\Release\net10.0-windows10.0.19041.0\win-x64\AppPackages")
+ )
+ $appPackagesPath = $candidatePaths | Where-Object { Test-Path $_ } | Select-Object -First 1
+ if ($null -eq $appPackagesPath) {
+ Write-Error "Unable to find AppPackages under: $($candidatePaths -join ', ')"
+ exit 1
+ }
+ Write-Host "Listing AppPackages from $appPackagesPath"
+ Get-ChildItem -Path $appPackagesPath -Recurse | Format-List FullName, Length, Mode
+
- name: Install App
shell: powershell
run: |
Import-Module Appx
- .\TransactionProcessor.Mobile/bin/Release\net10.0-windows10.0.19041.0\win-x64\AppPackages\TransactionProcessor.Mobile_1.0.0.1_Test\Install.ps1 -Force
+ $candidatePaths = @(
+ (Join-Path $env:GITHUB_WORKSPACE "TransactionProcessor.Mobile\AppPackages"),
+ (Join-Path $env:GITHUB_WORKSPACE "TransactionProcessor.Mobile\bin\Release\net10.0-windows10.0.19041.0\win-x64\AppPackages")
+ )
+ $appPackagesPath = $candidatePaths | Where-Object { Test-Path $_ } | Select-Object -First 1
+ if ($null -eq $appPackagesPath) {
+ throw "Unable to find AppPackages under: $($candidatePaths -join ', ')"
+ }
+ $installScript = Get-ChildItem -Path $appPackagesPath -Recurse -Filter Install.ps1 | Select-Object -First 1
+ if ($null -ne $installScript) {
+ & $installScript.FullName -Force
+ } else {
+ $msixPackage = Get-ChildItem -Path $appPackagesPath -Recurse -Filter *.msix | Select-Object -First 1
+ if ($null -eq $msixPackage) {
+ throw "Unable to find Install.ps1 or .msix package under $appPackagesPath."
+ }
+ Add-AppxPackage -Path $msixPackage.FullName -ForceApplicationShutdown
+ }
- name: Run Windows Navigation Tests
run: dotnet test TransactionProcessor.Mobile.UiTests/TransactionProcessor.Mobile.UiTests.csproj --filter "(Category=PRNavTest)&(Category=Windows)" --no-restore
diff --git a/Directory.Packages.props b/Directory.Packages.props
new file mode 100644
index 00000000..0b5a68e8
--- /dev/null
+++ b/Directory.Packages.props
@@ -0,0 +1,51 @@
+
+
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/TestCategoryLister/TestCategoryLister.csproj b/TestCategoryLister/TestCategoryLister.csproj
index a5958a54..72df9878 100644
--- a/TestCategoryLister/TestCategoryLister.csproj
+++ b/TestCategoryLister/TestCategoryLister.csproj
@@ -4,6 +4,6 @@
net10.0
-
+
\ No newline at end of file
diff --git a/TransactionProcessor.Mobile.BusinessLogic.Tests/TransactionProcessor.Mobile.BusinessLogic.Tests.csproj b/TransactionProcessor.Mobile.BusinessLogic.Tests/TransactionProcessor.Mobile.BusinessLogic.Tests.csproj
index 9eb9e129..b8eb45e5 100644
--- a/TransactionProcessor.Mobile.BusinessLogic.Tests/TransactionProcessor.Mobile.BusinessLogic.Tests.csproj
+++ b/TransactionProcessor.Mobile.BusinessLogic.Tests/TransactionProcessor.Mobile.BusinessLogic.Tests.csproj
@@ -9,23 +9,23 @@
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
runtime; build; native; contentfiles; analyzers; buildtransitive
all
-
+
runtime; build; native; contentfiles; analyzers; buildtransitive
all
-
+
all
diff --git a/TransactionProcessor.Mobile.BusinessLogic/TransactionProcessor.Mobile.BusinessLogic.csproj b/TransactionProcessor.Mobile.BusinessLogic/TransactionProcessor.Mobile.BusinessLogic.csproj
index f5dc5427..8b5ecaf4 100644
--- a/TransactionProcessor.Mobile.BusinessLogic/TransactionProcessor.Mobile.BusinessLogic.csproj
+++ b/TransactionProcessor.Mobile.BusinessLogic/TransactionProcessor.Mobile.BusinessLogic.csproj
@@ -6,20 +6,20 @@
enable
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
all
-
-
-
+
+
+
diff --git a/TransactionProcessor.Mobile.BusinessLogic/ViewModels/Reports/ReportsSalesAnalysisPageViewModel.cs b/TransactionProcessor.Mobile.BusinessLogic/ViewModels/Reports/ReportsSalesAnalysisPageViewModel.cs
index b08b9a8d..fd59621b 100644
--- a/TransactionProcessor.Mobile.BusinessLogic/ViewModels/Reports/ReportsSalesAnalysisPageViewModel.cs
+++ b/TransactionProcessor.Mobile.BusinessLogic/ViewModels/Reports/ReportsSalesAnalysisPageViewModel.cs
@@ -134,8 +134,8 @@ public override async Task Initialise(CancellationToken cancellationToken)
},
Fill = null,
Name = "Balance",
- TooltipLabelFormatter =
- (chartPoint) => $"{chartPoint.Context.Series.Name}: {chartPoint.PrimaryValue}"
+ YToolTipLabelFormatter =
+ (chartPoint) => $"{chartPoint.Context.Series.Name}: {chartPoint.StackedValue}"
}
};
}
diff --git a/TransactionProcessor.Mobile.UITests/TransactionProcessor.Mobile.UITests.csproj b/TransactionProcessor.Mobile.UITests/TransactionProcessor.Mobile.UITests.csproj
index 8379eacf..2ef862ac 100644
--- a/TransactionProcessor.Mobile.UITests/TransactionProcessor.Mobile.UITests.csproj
+++ b/TransactionProcessor.Mobile.UITests/TransactionProcessor.Mobile.UITests.csproj
@@ -9,31 +9,31 @@
-
+
runtime; build; native; contentfiles; analyzers; buildtransitive
all
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
diff --git a/TransactionProcessor.Mobile/Pages/Reports/ReportsBalanceAnalysisPage.xaml b/TransactionProcessor.Mobile/Pages/Reports/ReportsBalanceAnalysisPage.xaml
index 26080b07..ff8e8e6d 100644
--- a/TransactionProcessor.Mobile/Pages/Reports/ReportsBalanceAnalysisPage.xaml
+++ b/TransactionProcessor.Mobile/Pages/Reports/ReportsBalanceAnalysisPage.xaml
@@ -22,12 +22,11 @@
Series="{Binding Series}"
YAxes="{Binding YAxes}"
XAxes="{Binding XAxes}"
- TooltipFindingStrategy="{Binding TooltipFindingStrategy}"
TooltipPosition="{Binding TooltipPosition}"
HeightRequest="260"
HorizontalOptions="FillAndExpand" />
-
+
diff --git a/TransactionProcessor.Mobile/Platforms/Android/MainActivity.cs b/TransactionProcessor.Mobile/Platforms/Android/MainActivity.cs
index 145eab11..6b39aca6 100644
--- a/TransactionProcessor.Mobile/Platforms/Android/MainActivity.cs
+++ b/TransactionProcessor.Mobile/Platforms/Android/MainActivity.cs
@@ -1,11 +1,111 @@
using Android.App;
using Android.Content.PM;
using Android.OS;
+using System.Reflection;
+using AndroidX.Activity;
+using Microsoft.Maui.Controls;
+using TransactionProcessor.Mobile.BusinessLogic.ViewModels;
+using Android.Window;
namespace TransactionProcessor.Mobile
{
[Activity(Theme = "@style/Maui.SplashTheme", MainLauncher = true, LaunchMode = LaunchMode.SingleTop, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode | ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize | ConfigChanges.Density)]
public class MainActivity : MauiAppCompatActivity
{
+ private OnBackPressedCallback backPressedCallback;
+ private IOnBackInvokedCallback? backInvokedCallback;
+
+ protected override void OnCreate(Bundle savedInstanceState)
+ {
+ base.OnCreate(savedInstanceState);
+
+ this.backPressedCallback = new BackPressedHandler(this);
+ this.OnBackPressedDispatcher.AddCallback(this, this.backPressedCallback);
+
+ if (Build.VERSION.SdkInt >= BuildVersionCodes.Tiramisu)
+ {
+ this.backInvokedCallback = new BackInvokedHandler(this);
+ this.OnBackInvokedDispatcher.RegisterOnBackInvokedCallback(0, this.backInvokedCallback);
+ }
+ }
+
+ private void HandleBackPressed()
+ {
+ Shell currentPage = ResolveCurrentShellPage();
+
+ if (currentPage.CurrentPage?.BindingContext is ExtendedBaseViewModel viewModel)
+ {
+ viewModel.BackButtonCommand.Execute(null);
+ return;
+ }
+
+
+ Finish();
+ }
+
+ private static Shell ResolveCurrentShellPage() => Shell.Current is Shell shell ? ResolveShellPage(shell) : null;
+
+ private static Shell ResolveShellPage(Shell shell)
+ {
+ object current = shell;
+
+ for (Int32 i = 0; i < 4 && current != null; i++)
+ {
+ if (current is Shell shellPage)
+ {
+ return shellPage;
+ }
+
+ object next = GetPropertyValue(current, "CurrentPage")
+ ?? GetPropertyValue(current, "CurrentItem")
+ ?? GetPropertyValue(current, "Content");
+
+ if (next == null || ReferenceEquals(next, current))
+ {
+ break;
+ }
+
+ current = next;
+ }
+
+ return null;
+ }
+
+ private static object GetPropertyValue(object instance, String propertyName)
+ {
+ PropertyInfo property = instance.GetType().GetProperty(propertyName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
+ return property?.GetValue(instance);
+ }
+
+ private sealed class BackPressedHandler : OnBackPressedCallback
+ {
+ private readonly MainActivity activity;
+
+ public BackPressedHandler(MainActivity activity)
+ : base(true)
+ {
+ this.activity = activity;
+ }
+
+ public override void HandleOnBackPressed()
+ {
+ this.activity.HandleBackPressed();
+ }
+ }
+
+ private sealed class BackInvokedHandler : Java.Lang.Object, IOnBackInvokedCallback
+ {
+ private readonly MainActivity activity;
+
+ public BackInvokedHandler(MainActivity activity)
+ {
+ this.activity = activity;
+ }
+
+ public void OnBackInvoked()
+ {
+ this.activity.HandleBackPressed();
+ }
+ }
}
}
diff --git a/TransactionProcessor.Mobile/TransactionProcessor.Mobile.csproj b/TransactionProcessor.Mobile/TransactionProcessor.Mobile.csproj
index eab23a0c..16a9921b 100644
--- a/TransactionProcessor.Mobile/TransactionProcessor.Mobile.csproj
+++ b/TransactionProcessor.Mobile/TransactionProcessor.Mobile.csproj
@@ -151,15 +151,15 @@
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+