fix(postit): repair Circles bindings + align UserSearchApi route
All checks were successful
Dotnet build and test / build (pull_request) Successful in 12m51s
All checks were successful
Dotnet build and test / build (pull_request) Successful in 12m51s
- CirclesPage: drop VisualRoot/MainWindow hack, switch to App.PushPageAsync(vm) - CirclesPageViewModel: make OpenAddMemberAsync public so Avalonia XAML trampoline can call it - AddCircleMemberDialog: bind SearchAsync/Add (drop Command suffix) - UserSearchApiController: route under Constants.APIPrefix (= api/v1/user-search), matching the rest of Yavsc.Blogs controllers and the PostIt client's BlogsApiUrl default
This commit is contained in:
parent
e75993ea36
commit
bd6ca9d11f
7 changed files with 17 additions and 71 deletions
|
|
@ -183,7 +183,6 @@ public partial class App : Application
|
||||||
// here — the parametrised ctors stay for direct test wiring.
|
// here — the parametrised ctors stay for direct test wiring.
|
||||||
services.AddTransient<PostAclDialog>();
|
services.AddTransient<PostAclDialog>();
|
||||||
services.AddTransient<AddCircleMemberDialog>();
|
services.AddTransient<AddCircleMemberDialog>();
|
||||||
|
|
||||||
// ViewModels
|
// ViewModels
|
||||||
services.AddSingleton(settings);
|
services.AddSingleton(settings);
|
||||||
services.AddSingleton<YavscApiClient>(api);
|
services.AddSingleton<YavscApiClient>(api);
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,10 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
using System.Linq;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Avalonia;
|
||||||
using CommunityToolkit.Mvvm.ComponentModel;
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
using CommunityToolkit.Mvvm.Input;
|
using CommunityToolkit.Mvvm.Input;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using PostIt.Services;
|
using PostIt.Services;
|
||||||
using Yavsc.Api.Client;
|
using Yavsc.Api.Client;
|
||||||
using Yavsc.Api.Client.Dtos;
|
using Yavsc.Api.Client.Dtos;
|
||||||
|
|
@ -63,12 +64,6 @@ public partial class CirclesPageViewModel : ViewModelBase
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
public partial string StatusMessage { get; set; } = string.Empty;
|
public partial string StatusMessage { get; set; } = string.Empty;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Raised when the user wants to add a member to the
|
|
||||||
/// currently selected circle. The view listens to this
|
|
||||||
/// event and opens <c>AddCircleMemberDialog</c>.
|
|
||||||
/// </summary>
|
|
||||||
public event EventHandler? AddMemberRequested;
|
|
||||||
|
|
||||||
public CirclesPageViewModel(CircleApiClient client)
|
public CirclesPageViewModel(CircleApiClient client)
|
||||||
{
|
{
|
||||||
|
|
@ -116,6 +111,16 @@ public partial class CirclesPageViewModel : ViewModelBase
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[RelayCommand]
|
||||||
|
internal async Task OpenAddMemberAsync()
|
||||||
|
{
|
||||||
|
var app = Application.Current as App;
|
||||||
|
var services = app?.ServiceProvider;
|
||||||
|
var directory = services.GetRequiredService<IUserDirectory>();
|
||||||
|
AddCircleMemberDialogViewModel model =
|
||||||
|
new AddCircleMemberDialogViewModel(directory);
|
||||||
|
await app.PushPageAsync(model);
|
||||||
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Load the members of one of the caller's circles. The
|
/// Load the members of one of the caller's circles. The
|
||||||
/// server scopes the endpoint with a 404 when the circle
|
/// server scopes the endpoint with a 404 when the circle
|
||||||
|
|
@ -231,22 +236,6 @@ public partial class CirclesPageViewModel : ViewModelBase
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Fire the <see cref="AddMemberRequested"/> event so
|
|
||||||
/// the view opens <c>AddCircleMemberDialog</c>. The view
|
|
||||||
/// forwards the dialog's <c>Confirmed</c> event back to
|
|
||||||
/// <see cref="OnAddMemberConfirmedAsync"/>.
|
|
||||||
/// </summary>
|
|
||||||
[RelayCommand]
|
|
||||||
public void OpenAddMember()
|
|
||||||
{
|
|
||||||
if (SelectedCircle is null)
|
|
||||||
{
|
|
||||||
StatusMessage = "Sélectionnez d'abord un cercle";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
AddMemberRequested?.Invoke(this, EventArgs.Empty);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Called by the view when the dialog confirms a
|
/// Called by the view when the dialog confirms a
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
PlaceholderText="Nom ou email d'un utilisateur Yavsc..."
|
PlaceholderText="Nom ou email d'un utilisateur Yavsc..."
|
||||||
HorizontalAlignment="Stretch"/>
|
HorizontalAlignment="Stretch"/>
|
||||||
<Button Grid.Column="1" Content="Rechercher"
|
<Button Grid.Column="1" Content="Rechercher"
|
||||||
Command="{Binding SearchCommand}"
|
Command="{Binding SearchAsync}"
|
||||||
Margin="8,0,0,0"/>
|
Margin="8,0,0,0"/>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
|
|
@ -47,7 +47,7 @@
|
||||||
<TextBlock Grid.Column="0" Text="{Binding StatusMessage}"
|
<TextBlock Grid.Column="0" Text="{Binding StatusMessage}"
|
||||||
VerticalAlignment="Center"/>
|
VerticalAlignment="Center"/>
|
||||||
<Button Grid.Column="1" Content="Ajouter"
|
<Button Grid.Column="1" Content="Ajouter"
|
||||||
Command="{Binding AddCommand}"
|
Command="{Binding Add}"
|
||||||
IsEnabled="{Binding Selected, Converter={x:Static ObjectConverters.IsNotNull}}"
|
IsEnabled="{Binding Selected, Converter={x:Static ObjectConverters.IsNotNull}}"
|
||||||
Margin="0,0,8,0"/>
|
Margin="0,0,8,0"/>
|
||||||
<Button Grid.Column="2" Content="Fermer"
|
<Button Grid.Column="2" Content="Fermer"
|
||||||
|
|
|
||||||
|
|
@ -25,12 +25,6 @@ public partial class AddCircleMemberDialog : ContentPage
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
}
|
}
|
||||||
|
|
||||||
public AddCircleMemberDialog(IUserDirectory directory)
|
|
||||||
{
|
|
||||||
InitializeComponent();
|
|
||||||
DataContext = new AddCircleMemberDialogViewModel(directory);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void InitializeComponent()
|
private void InitializeComponent()
|
||||||
{
|
{
|
||||||
AvaloniaXamlLoader.Load(this);
|
AvaloniaXamlLoader.Load(this);
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,7 @@
|
||||||
FontWeight="Bold"
|
FontWeight="Bold"
|
||||||
VerticalAlignment="Center"/>
|
VerticalAlignment="Center"/>
|
||||||
<Button Content="Ajouter un membre"
|
<Button Content="Ajouter un membre"
|
||||||
Command="{Binding OpenAddMemberCommand}"/>
|
Command="{Binding OpenAddMemberAsync}"/>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
<ListBox Grid.Row="1"
|
<ListBox Grid.Row="1"
|
||||||
ItemsSource="{Binding Members}">
|
ItemsSource="{Binding Members}">
|
||||||
|
|
|
||||||
|
|
@ -10,46 +10,10 @@ namespace PostIt.Views;
|
||||||
|
|
||||||
public partial class CirclesPage : ContentPage
|
public partial class CirclesPage : ContentPage
|
||||||
{
|
{
|
||||||
private CirclesPageViewModel? _vm;
|
|
||||||
|
|
||||||
public CirclesPage()
|
public CirclesPage()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
DataContextChanged += OnDataContextChanged;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnDataContextChanged(object? sender, EventArgs e)
|
|
||||||
{
|
|
||||||
// Unsubscribe from the previous VM to avoid leaking
|
|
||||||
// handlers across navigation pushes / DataContext resets.
|
|
||||||
if (_vm is not null)
|
|
||||||
_vm.AddMemberRequested -= OnAddMemberRequested;
|
|
||||||
|
|
||||||
_vm = DataContext as CirclesPageViewModel;
|
|
||||||
if (_vm is not null)
|
|
||||||
_vm.AddMemberRequested += OnAddMemberRequested;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnAddMemberRequested(object? sender, EventArgs e)
|
|
||||||
{
|
|
||||||
var app = Application.Current as App;
|
|
||||||
var services = app?.ServiceProvider;
|
|
||||||
if (services is null || _vm is null) return;
|
|
||||||
|
|
||||||
// Resolve the directory via DI. The dialog raises its
|
|
||||||
// own Confirmed event; the VM subscribes via the method
|
|
||||||
// below — we pass the VM in so the closure can call
|
|
||||||
// back into it without the dialog needing to know the
|
|
||||||
// type of its caller. EventHandler<UserSummary> wants a
|
|
||||||
// void return, so wrap the async VM method in a fire-
|
|
||||||
// and-forget helper.
|
|
||||||
var directory = services.GetRequiredService<IUserDirectory>();
|
|
||||||
var dialog = new AddCircleMemberDialog(directory);
|
|
||||||
dialog.ViewModel!.Confirmed += async (sender, picked) =>
|
|
||||||
await _vm.OnAddMemberConfirmedAsync(sender, picked);
|
|
||||||
|
|
||||||
if (this.VisualRoot is MainWindow window)
|
|
||||||
_ = window.NavRoot.PushAsync(dialog);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void InitializeComponent()
|
private void InitializeComponent()
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ namespace Yavsc.Blogs.Controllers
|
||||||
/// exposing it.</para>
|
/// exposing it.</para>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Produces("application/json")]
|
[Produces("application/json")]
|
||||||
[Route("api/user-search")]
|
[Route( Constants.APIPrefix + "/user-search")]
|
||||||
[Authorize]
|
[Authorize]
|
||||||
public class UserSearchApiController : Controller
|
public class UserSearchApiController : Controller
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue