postit: add mapsui location picker to rdv form
This commit is contained in:
parent
3488abc7fd
commit
2ede36cb8f
6 changed files with 114 additions and 1 deletions
|
|
@ -16,6 +16,8 @@
|
|||
<PackageVersion Include="Avalonia.Headless" Version="$(AvaloniaVersionBase)" />
|
||||
<PackageVersion Include="Avalonia.Headless.Xunit" Version="$(AvaloniaVersionBase)" />
|
||||
<PackageVersion Include="Avalonia.Fonts.Inter" Version="$(AvaloniaVersionBase)" />
|
||||
<PackageVersion Include="Mapsui" Version="5.1.0" />
|
||||
<PackageVersion Include="Mapsui.Avalonia12" Version="5.1.0" />
|
||||
|
||||
<PackageVersion Include="Material.Avalonia" Version="3.19.0" />
|
||||
<PackageVersion Include="AvaloniaUI.DiagnosticsSupport" Version="2.2.3" />
|
||||
|
|
|
|||
|
|
@ -115,6 +115,26 @@ public class BillingCommandPageViewModelTests
|
|||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ApplyLocationFromMap_sets_coordinates_and_updates_status()
|
||||
{
|
||||
var api = new RecordingApi();
|
||||
var client = new BillingApiClient(api, "https://business.example/api/v1/");
|
||||
var vm =
|
||||
new CommandFormSummary { Id = 12, ActionName = "Rdv", Title = "Rendez-vous" }
|
||||
.CreateCommandPageViewModel(
|
||||
new ActivityInfo { Code = "dev", Name = "Développement" },
|
||||
new ActivityUserDisplayItem { PerformerId = "perf-1", UserName = "Alice" },
|
||||
client) as RdvViewModel;
|
||||
|
||||
vm!.Address = string.Empty;
|
||||
vm.ApplyLocationFromMap(48.85661234, 2.35224567);
|
||||
|
||||
Assert.Equal(48.856612, vm.Latitude);
|
||||
Assert.Equal(2.352246, vm.Longitude);
|
||||
Assert.Contains("Position sélectionnée", vm.StatusMessage, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task InitializeAsync_loads_prestations_for_brush_and_submit_posts_selected_prestation()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -29,6 +29,8 @@
|
|||
<IncludeAssets Condition="'$(Configuration)' != 'Debug'">None</IncludeAssets>
|
||||
<PrivateAssets Condition="'$(Configuration)' != 'Debug'">All</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Mapsui" />
|
||||
<PackageReference Include="Mapsui.Avalonia12" />
|
||||
<PackageReference Include="CommunityToolkit.Mvvm" />
|
||||
<PackageReference Include="IdentityModel.OidcClient" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" />
|
||||
|
|
|
|||
|
|
@ -113,6 +113,20 @@ public partial class RdvViewModel : BillingCommandPageViewModel
|
|||
};
|
||||
}
|
||||
|
||||
public void ApplyLocationFromMap(double latitude, double longitude)
|
||||
{
|
||||
Latitude = Math.Round(latitude, 6);
|
||||
Longitude = Math.Round(longitude, 6);
|
||||
|
||||
if (string.IsNullOrWhiteSpace(Address))
|
||||
{
|
||||
this.SetInfoStatus("Position sélectionnée sur la carte. Complétez l'adresse puis envoyez la commande.");
|
||||
return;
|
||||
}
|
||||
|
||||
this.SetInfoStatus("Position sélectionnée sur la carte.");
|
||||
}
|
||||
|
||||
|
||||
protected override async Task SubmitAsync()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,12 +1,13 @@
|
|||
<ContentPage xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:cvm="using:PostIt.ViewModels.Commands"
|
||||
xmlns:mapsui="using:Mapsui.UI.Avalonia"
|
||||
xmlns:postitControls="using:PostIt.Controls"
|
||||
x:Class="PostIt.Views.Commands.RdvPage"
|
||||
x:DataType="cvm:RdvViewModel"
|
||||
Header="Commande billing">
|
||||
<ScrollViewer>
|
||||
<Grid RowDefinitions="Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto" ColumnDefinitions="Auto,*" Margin="12">
|
||||
<Grid RowDefinitions="Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto" ColumnDefinitions="Auto,*" Margin="12">
|
||||
<TextBlock Grid.Row="0" Grid.ColumnSpan="2"
|
||||
Text="{Binding Title}"
|
||||
FontSize="18"
|
||||
|
|
@ -52,6 +53,15 @@
|
|||
<TextBlock Grid.Row="9" Text="Longitude" VerticalAlignment="Center" Margin="0,0,12,8" />
|
||||
<TextBox Grid.Row="9" Grid.Column="1" Text="{Binding Longitude, Mode=TwoWay}" PlaceholderText="Optionnel" Margin="0,0,0,8" />
|
||||
|
||||
<TextBlock Grid.Row="10" Grid.ColumnSpan="2"
|
||||
Text="Carte: cliquez pour positionner le rendez-vous"
|
||||
Margin="0,0,0,8"
|
||||
Opacity="0.85" />
|
||||
<mapsui:MapControl Grid.Row="11"
|
||||
Grid.ColumnSpan="2"
|
||||
x:Name="LocationMap"
|
||||
Height="260"
|
||||
Margin="0,0,0,8" />
|
||||
|
||||
<TextBlock Grid.Row="12"
|
||||
Text="Informations"
|
||||
|
|
|
|||
|
|
@ -1,17 +1,82 @@
|
|||
using Avalonia.Controls;
|
||||
using Avalonia.Markup.Xaml;
|
||||
using Mapsui;
|
||||
using Mapsui.Projections;
|
||||
using Mapsui.Tiling;
|
||||
using Mapsui.UI.Avalonia;
|
||||
using PostIt.ViewModels.Commands;
|
||||
|
||||
namespace PostIt.Views.Commands;
|
||||
|
||||
public partial class RdvPage : ContentPage
|
||||
{
|
||||
private MapControl? _locationMap;
|
||||
|
||||
public RdvPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
InitializeMap();
|
||||
}
|
||||
|
||||
private void InitializeComponent()
|
||||
{
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
}
|
||||
|
||||
private void InitializeMap()
|
||||
{
|
||||
_locationMap = this.FindControl<MapControl>("LocationMap");
|
||||
if (_locationMap is null)
|
||||
return;
|
||||
|
||||
var map = new Map();
|
||||
map.Layers.Add(OpenStreetMap.CreateTileLayer());
|
||||
_locationMap.Map = map;
|
||||
_locationMap.MapTapped += OnMapTapped;
|
||||
|
||||
DataContextChanged += OnDataContextChanged;
|
||||
CenterFromViewModel();
|
||||
}
|
||||
|
||||
private void OnDataContextChanged(object? sender, System.EventArgs e)
|
||||
{
|
||||
CenterFromViewModel();
|
||||
}
|
||||
|
||||
private void OnMapTapped(object? sender, MapEventArgs e)
|
||||
{
|
||||
if (DataContext is not RdvViewModel vm)
|
||||
return;
|
||||
|
||||
var (longitude, latitude) = SphericalMercator.ToLonLat(e.WorldPosition.X, e.WorldPosition.Y);
|
||||
vm.ApplyLocationFromMap(latitude, longitude);
|
||||
CenterMap(latitude, longitude, zoomLevel: 13);
|
||||
}
|
||||
|
||||
private void CenterFromViewModel()
|
||||
{
|
||||
if (DataContext is not RdvViewModel vm)
|
||||
{
|
||||
CenterMap(48.8566, 2.3522, zoomLevel: 4);
|
||||
return;
|
||||
}
|
||||
|
||||
if (vm.Latitude.HasValue && vm.Longitude.HasValue)
|
||||
{
|
||||
CenterMap(vm.Latitude.Value, vm.Longitude.Value, zoomLevel: 13);
|
||||
return;
|
||||
}
|
||||
|
||||
CenterMap(48.8566, 2.3522, zoomLevel: 4);
|
||||
}
|
||||
|
||||
private void CenterMap(double latitude, double longitude, int zoomLevel)
|
||||
{
|
||||
if (_locationMap?.Map is null)
|
||||
return;
|
||||
|
||||
var (x, y) = SphericalMercator.FromLonLat(longitude, latitude);
|
||||
_locationMap.Map.Navigator.CenterOn(x, y);
|
||||
_locationMap.Map.Navigator.ZoomToLevel(zoomLevel);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue