chore: release v2.4

- Add theme system (Dark/Light palettes, ModernTheme, ThemeManager)
- Add InputDialog, Spinner common view
- Add DuplicatesCsvExportService
- Refresh views, dialogs, and view models across tabs
- Update localization strings (en/fr)
- Tweak services (transfer, permissions, search, user access, ownership elevation, bulk operations)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Dev
2026-04-20 11:23:11 +02:00
parent 8f30a60d2a
commit 12dd1de9f2
93 changed files with 8708 additions and 1159 deletions
+37 -21
View File
@@ -28,7 +28,7 @@
<CheckBox Content="{Binding Source={x:Static loc:TranslationSource.Instance}, Path=[chk.max.depth]}"
IsChecked="{Binding IsMaxDepth}" Margin="0,2" />
<TextBlock Text="{Binding Source={x:Static loc:TranslationSource.Instance}, Path=[stor.note]}"
TextWrapping="Wrap" FontSize="11" Foreground="#888"
TextWrapping="Wrap" FontSize="11" Foreground="{DynamicResource TextMutedBrush}"
Margin="0,6,0,0" />
</StackPanel>
</GroupBox>
@@ -45,6 +45,16 @@
<GroupBox Header="{Binding Source={x:Static loc:TranslationSource.Instance}, Path=[grp.export.fmt]}"
Margin="0,0,0,8">
<StackPanel Margin="4">
<Label Content="{Binding Source={x:Static loc:TranslationSource.Instance}, Path=[export.split.label]}" Margin="0,0,0,0" Padding="0,2" />
<ComboBox SelectedIndex="{Binding SplitModeIndex}" Height="24" Margin="0,0,0,4">
<ComboBoxItem Content="{Binding Source={x:Static loc:TranslationSource.Instance}, Path=[export.split.single]}" />
<ComboBoxItem Content="{Binding Source={x:Static loc:TranslationSource.Instance}, Path=[export.split.bySite]}" />
</ComboBox>
<Label Content="{Binding Source={x:Static loc:TranslationSource.Instance}, Path=[export.html.layout.label]}" Padding="0,2" />
<ComboBox SelectedIndex="{Binding HtmlLayoutIndex}" Height="24" Margin="0,0,0,6">
<ComboBoxItem Content="{Binding Source={x:Static loc:TranslationSource.Instance}, Path=[export.html.layout.separate]}" />
<ComboBoxItem Content="{Binding Source={x:Static loc:TranslationSource.Instance}, Path=[export.html.layout.tabbed]}" />
</ComboBox>
<Button Content="{Binding Source={x:Static loc:TranslationSource.Instance}, Path=[stor.rad.csv]}"
Command="{Binding ExportCsvCommand}"
Height="26" Margin="0,2" />
@@ -68,7 +78,7 @@
<!-- Status -->
<TextBlock Text="{Binding StatusMessage}" TextWrapping="Wrap"
FontSize="11" Foreground="#555" Margin="0,4" />
FontSize="11" Foreground="{DynamicResource TextMutedBrush}" Margin="0,4" />
</StackPanel>
</ScrollViewer>
@@ -82,7 +92,7 @@
</Grid.RowDefinitions>
<!-- Summary bar -->
<Border Grid.Row="0" Background="#F0F7FF" CornerRadius="4" Padding="12,8" Margin="0,0,0,6">
<Border Grid.Row="0" Background="{DynamicResource AccentSoftBrush}" CornerRadius="4" Padding="12,8" Margin="0,0,0,6">
<Border.Style>
<Style TargetType="Border">
<Setter Property="Visibility" Value="Collapsed" />
@@ -94,18 +104,18 @@
</Style>
</Border.Style>
<StackPanel Orientation="Horizontal">
<TextBlock Margin="0,0,24,0">
<Run Text="Total Size: " FontWeight="SemiBold" />
<Run Text="{Binding SummaryTotalSize, Converter={StaticResource BytesConverter}, Mode=OneWay}" />
</TextBlock>
<TextBlock Margin="0,0,24,0">
<Run Text="Version Size: " FontWeight="SemiBold" />
<Run Text="{Binding SummaryVersionSize, Converter={StaticResource BytesConverter}, Mode=OneWay}" />
</TextBlock>
<TextBlock>
<Run Text="Files: " FontWeight="SemiBold" />
<Run Text="{Binding SummaryFileCount, StringFormat=N0, Mode=OneWay}" />
</TextBlock>
<StackPanel Orientation="Horizontal" Margin="0,0,24,0">
<TextBlock Text="{Binding Source={x:Static loc:TranslationSource.Instance}, Path=[storage.lbl.total_size_colon]}" FontWeight="SemiBold" />
<TextBlock Text="{Binding SummaryTotalSize, Converter={StaticResource BytesConverter}, Mode=OneWay}" />
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,0,24,0">
<TextBlock Text="{Binding Source={x:Static loc:TranslationSource.Instance}, Path=[storage.lbl.version_size_colon]}" FontWeight="SemiBold" />
<TextBlock Text="{Binding SummaryVersionSize, Converter={StaticResource BytesConverter}, Mode=OneWay}" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Source={x:Static loc:TranslationSource.Instance}, Path=[storage.lbl.files_colon]}" FontWeight="SemiBold" />
<TextBlock Text="{Binding SummaryFileCount, StringFormat=N0, Mode=OneWay}" />
</StackPanel>
</StackPanel>
</Border>
@@ -147,11 +157,11 @@
<!-- Splitter between DataGrid and Chart -->
<GridSplitter Grid.Row="2" Height="5" HorizontalAlignment="Stretch"
Background="#DDD" ResizeDirection="Rows" />
Background="{DynamicResource BorderSoftBrush}" ResizeDirection="Rows" />
<!-- Chart panel -->
<Border Grid.Row="3" BorderBrush="#DDD" BorderThickness="1" CornerRadius="4"
Padding="8" Background="White">
<Border Grid.Row="3" BorderBrush="{DynamicResource BorderSoftBrush}" BorderThickness="1" CornerRadius="4"
Padding="8" Background="{DynamicResource SurfaceBrush}">
<Grid>
<!-- Chart title -->
<TextBlock Text="{Binding Source={x:Static loc:TranslationSource.Instance}, Path=[stor.chart.title]}"
@@ -160,7 +170,7 @@
<!-- No data placeholder -->
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center"
Foreground="#888" FontSize="12"
Foreground="{DynamicResource TextMutedBrush}" FontSize="12"
Text="{Binding Source={x:Static loc:TranslationSource.Instance}, Path=[stor.chart.nodata]}">
<TextBlock.Style>
<Style TargetType="TextBlock">
@@ -192,7 +202,11 @@
</Grid.Style>
<lvc:PieChart x:Name="StoragePieChart"
Series="{Binding PieChartSeries}"
LegendPosition="Right" />
LegendPosition="Right"
LegendTextPaint="{Binding LegendTextPaint}"
LegendBackgroundPaint="{Binding LegendBackgroundPaint}"
TooltipTextPaint="{Binding TooltipTextPaint}"
TooltipBackgroundPaint="{Binding TooltipBackgroundPaint}" />
</Grid>
<!-- Bar chart wrapper (visible when IsDonutChart=false AND HasChartData=true) -->
@@ -214,7 +228,9 @@
<lvc:CartesianChart Series="{Binding BarChartSeries}"
XAxes="{Binding BarXAxes}"
YAxes="{Binding BarYAxes}"
LegendPosition="Hidden" />
LegendPosition="Hidden"
TooltipTextPaint="{Binding TooltipTextPaint}"
TooltipBackgroundPaint="{Binding TooltipBackgroundPaint}" />
</Grid>
</Grid>
</Border>