Compare commits

...
Author SHA1 Message Date
7b842a9fe9
user the CommandBar
All checks were successful
Dotnet build and test / build (pull_request) Successful in 9m17s
2026-09-07 20:53:23 +01:00
b75d0add7d
db testing 2026-09-07 20:02:56 +01:00
4 changed files with 158 additions and 116 deletions

View file

@ -24,51 +24,65 @@
<RowDefinition Height="*" /> <RowDefinition Height="*" />
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
</Grid.RowDefinitions> </Grid.RowDefinitions>
<WrapPanel Grid.Row="0" HorizontalAlignment="Stretch">
<TextBlock Text="Blog Posts" FontSize="22" FontWeight="SemiBold" />
<TextBox Text="{Binding SearchText, Mode=TwoWay}" PlaceholderText="Filter by title or author..." />
<CommandBar IsDynamicOverflowEnabled="True">
<CommandBar.PrimaryCommands>
<Border Grid.Row="0" <CommandBarButton Label="Filter" Command="{Binding SearchAsync}">
HorizontalAlignment="Stretch" <CommandBarButton.Icon>
VerticalAlignment="Top" <PathIcon Data="{StaticResource FilterIcon}" />
Padding="0"> </CommandBarButton.Icon>
<WrapPanel Orientation="Horizontal"> </CommandBarButton>
<Button Command="{Binding RefreshAsync}" Content="🗘 Refresh" /> <CommandBarButton Label="Refresh" Command="{Binding RefreshAsync}">
<Button Command="{Binding SearchAsync}" Content="🔍 Filter" /> <CommandBarButton.Icon>
<Button Command="{Binding SaveAsync}" Content="Save" /> <PathIcon Data="{StaticResource RefreshIcon}" />
<Button Command="{Binding DeleteAsync}" Content="Delete" /> </CommandBarButton.Icon>
<Button x:Name="AddAttachmentButton" </CommandBarButton>
Content="Ajouter fichiers" <CommandBarButton Label="Save" Command="{Binding SaveAsync}">
Click="AddAttachment_Click" /> <CommandBarButton.Icon>
<Button x:Name="ManageAclButton" <PathIcon Data="{StaticResource SaveIcon}" />
Command="{Binding ManageAclAsync}" </CommandBarButton.Icon>
Content="ACL" /> </CommandBarButton>
<Button x:Name="OpenCirclesButton" <CommandBarButton Label="Delete" Command="{Binding DeleteAsync}">
Command="{Binding OpenCirclesAsync}" <CommandBarButton.Icon>
Content="Mes cercles" /> <PathIcon Data="{StaticResource DeleteIcon}" />
<!-- Publication toggle: a CheckBox wired to </CommandBarButton.Icon>
DraftIsPublished. Clicking it fires </CommandBarButton>
TogglePublishCommand, which pushes the <CommandBarButton Label="Ajouter fichiers" Click="AddAttachment_Click"
new state to /api/blog/{id}/publish. x:Name="AddAttachmentButton">
The CheckBox is the canonical <CommandBarButton.Icon>
AvaloniaXaml 'toggle' surface; binding <PathIcon Data="{StaticResource AddIcon}" />
IsChecked TwoWay keeps the visual state </CommandBarButton.Icon>
and the buffer in sync. --> </CommandBarButton>
<CheckBox Content="Publié" <CommandBarButton x:Name="ManageAclButton"
IsChecked="{Binding DraftIsPublished, Mode=TwoWay}" Label="ACL" Command="{Binding ManageAclAsync}">
Command="{Binding TogglePublishAsync}" <CommandBarButton.Icon>
VerticalAlignment="Center"/> <PathIcon Data="{StaticResource AclIcon}" />
<!-- </CommandBarButton.Icon>
DEV ONLY: temporary shortcut to open the signature </CommandBarButton>
capture page. Production entry point is a SignalR <CommandBarButton x:Name="OpenCirclesButton"
push from Yavsc.Org ("devis received, sign here"). Label="Mes cercles" Command="{Binding OpenCirclesAsync}">
Remove this button and its Click handler in <CommandBarButton.Icon>
MainPage.axaml.cs once the SignalR handler lands. <PathIcon Data="{StaticResource CircleIcon}" />
--> </CommandBarButton.Icon>
<Button x:Name="OpenSignatureDevButton" </CommandBarButton>
Command="{Binding OpenSignatureDevAsync}" <CommandBarToggleButton Label="Publié"
Content="[DEV] Signature" IsChecked="{Binding DraftIsPublished, Mode=TwoWay}">
ToolTip.Tip="DEV ONLY — to remove when SignalR handler lands" /> <CommandBarToggleButton.Icon>
<PathIcon Data="{StaticResource PublishedIcon}" />
</CommandBarToggleButton.Icon>
</CommandBarToggleButton>
<CommandBarButton x:Name="OpenSignatureDevButton"
Label="[DEV] Signature" Command="{Binding OpenSignatureDevAsync}">
<CommandBarButton.Icon>
<PathIcon Data="{StaticResource SignIcon}" />
</CommandBarButton.Icon>
</CommandBarButton>
</CommandBar.PrimaryCommands>
</CommandBar>
</WrapPanel> </WrapPanel>
</Border>
<Border Grid.Row="1" BorderBrush="Gray" BorderThickness="1" Padding="8"> <Border Grid.Row="1" BorderBrush="Gray" BorderThickness="1" Padding="8">
<ListBox ItemsSource="{Binding FilteredPosts}" SelectedItem="{Binding SelectedPost, Mode=TwoWay}" <ListBox ItemsSource="{Binding FilteredPosts}" SelectedItem="{Binding SelectedPost, Mode=TwoWay}"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch" MinHeight="40"> HorizontalAlignment="Stretch" VerticalAlignment="Stretch" MinHeight="40">

View file

@ -1,20 +1,22 @@
using Microsoft.Data.Sqlite;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Diagnostics;
using Yavsc.Models;
namespace Yavsc.Org.Tests.Mandatory namespace Yavsc.Org.Tests.Mandatory
{ {[Collection("Database")]
[Collection("Database")]
[Trait("regression", "II")] [Trait("regression", "II")]
[Trait("dev", "wip")] [Trait("dev", "wip")]
public class Database: IClassFixture<WebServerFixture>, IDisposable public class Database: IClassFixture<WebServerFixture>, IDisposable
{ {
readonly WebServerFixture _serverFixture;
readonly ITestOutputHelper output; readonly ITestOutputHelper output;
public Database(WebServerFixture serverFixture, ITestOutputHelper output) readonly WebServerFixture _serverFixture;
public Database(ITestOutputHelper output, WebServerFixture _serverFixture)
{ {
this.output = output; this.output = output;
_serverFixture = serverFixture; this._serverFixture = _serverFixture;
} }
/// <summary> /// <summary>
@ -30,5 +32,13 @@ namespace Yavsc.Org.Tests.Mandatory
} }
} }
[Fact]
public void TestDatabaseMigration()
{
// Test logic goes here
_serverFixture.ResetAndMigrateDatabase();
} }
}
} }

View file

@ -189,6 +189,20 @@ public sealed class WebServerFixture : WebHostFixture
return app; return app;
} }
public void ResetAndMigrateDatabase()
{
using var scope = Services.CreateScope();
var db = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
db.Database.EnsureDeleted();
if (db.Database.IsRelational())
{
db.Database.Migrate();
return;
}
db.Database.EnsureCreated();
}
protected override async Task<WebApplication> ConfigurePipelineAsync(WebApplication app) protected override async Task<WebApplication> ConfigurePipelineAsync(WebApplication app)
{ {
// The MSBuild target CopyYavscOrgStaticAssets in // The MSBuild target CopyYavscOrgStaticAssets in

View file

@ -11,6 +11,10 @@ namespace Yavsc.Migrations
/// <inheritdoc /> /// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder) protected override void Up(MigrationBuilder migrationBuilder)
{ {
var declarationDateDefaultSql = ActiveProvider == "Microsoft.EntityFrameworkCore.Sqlite"
? "CURRENT_TIMESTAMP"
: "LOCALTIMESTAMP";
migrationBuilder.CreateTable( migrationBuilder.CreateTable(
name: "Activities", name: "Activities",
columns: table => new columns: table => new
@ -1484,7 +1488,7 @@ namespace Yavsc.Migrations
Platform = table.Column<string>(type: "text", nullable: true), Platform = table.Column<string>(type: "text", nullable: true),
Version = table.Column<string>(type: "text", nullable: true), Version = table.Column<string>(type: "text", nullable: true),
DeviceOwnerId = table.Column<string>(type: "text", nullable: true), DeviceOwnerId = table.Column<string>(type: "text", nullable: true),
DeclarationDate = table.Column<DateTime>(type: "timestamp with time zone", nullable: false, defaultValueSql: "LOCALTIMESTAMP"), DeclarationDate = table.Column<DateTime>(type: "timestamp with time zone", nullable: false, defaultValueSql: declarationDateDefaultSql),
LatestActivityUpdate = table.Column<DateTime>(type: "timestamp with time zone", nullable: true) LatestActivityUpdate = table.Column<DateTime>(type: "timestamp with time zone", nullable: true)
}, },
constraints: table => constraints: table =>