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 f4cc81bb71
64 changed files with 3315 additions and 405 deletions
@@ -4,6 +4,9 @@
xmlns:loc="clr-namespace:SharepointToolbox.Localization"
Title="Manage Profiles" Width="500" Height="750"
WindowStartupLocation="CenterOwner" ShowInTaskbar="False"
Background="{DynamicResource AppBgBrush}"
Foreground="{DynamicResource TextBrush}"
TextOptions.TextFormattingMode="Ideal"
ResizeMode="NoResize">
<Window.Resources>
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
@@ -50,14 +53,14 @@
<TextBox Text="{Binding NewClientId, UpdateSourceTrigger=PropertyChanged}"
Grid.Row="2" Grid.Column="1" Margin="0,2" />
<TextBlock Grid.Row="3" Grid.Column="1" Margin="0,2,0,0"
FontSize="11" FontStyle="Italic" Foreground="#666666" TextWrapping="Wrap"
FontSize="11" FontStyle="Italic" Foreground="{DynamicResource TextMutedBrush}" TextWrapping="Wrap"
Text="{Binding Source={x:Static loc:TranslationSource.Instance}, Path=[profile.clientid.hint]}" />
</Grid>
<!-- Client Logo -->
<StackPanel Grid.Row="3" Margin="0,8,0,8">
<Label Content="{Binding Source={x:Static loc:TranslationSource.Instance}, Path=[profile.logo.title]}" Padding="0,0,0,4" />
<Border BorderBrush="#DDDDDD" BorderThickness="1" Padding="8" CornerRadius="4"
<Border BorderBrush="{DynamicResource BorderSoftBrush}" BorderThickness="1" Padding="8" CornerRadius="4"
HorizontalAlignment="Left" MinWidth="200" MinHeight="50">
<Grid>
<Image Source="{Binding ClientLogoPreview, Converter={StaticResource Base64ToImageConverter}}"
@@ -65,7 +68,7 @@
Visibility="{Binding ClientLogoPreview, Converter={StaticResource StringToVisibilityConverter}}" />
<TextBlock Text="{Binding Source={x:Static loc:TranslationSource.Instance}, Path=[profile.logo.nopreview]}"
VerticalAlignment="Center" HorizontalAlignment="Center"
Foreground="#999999" FontStyle="Italic">
Foreground="{DynamicResource TextMutedBrush}" FontStyle="Italic">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Setter Property="Visibility" Value="Visible" />
@@ -87,7 +90,7 @@
<Button Content="{Binding Source={x:Static loc:TranslationSource.Instance}, Path=[profile.logo.autopull]}"
Command="{Binding AutoPullClientLogoCommand}" Width="130" />
</StackPanel>
<TextBlock Text="{Binding ValidationMessage}" Foreground="#CC0000" FontSize="11" Margin="0,4,0,0"
<TextBlock Text="{Binding ValidationMessage}" Foreground="{DynamicResource DangerBrush}" FontSize="11" Margin="0,4,0,0"
Visibility="{Binding ValidationMessage, Converter={StaticResource StringToVisibilityConverter}}" />
</StackPanel>
@@ -107,11 +110,11 @@
<!-- Status text -->
<TextBlock Text="{Binding RegistrationStatus}" FontSize="11" Margin="0,2,0,0"
Foreground="#006600"
Foreground="{DynamicResource SuccessBrush}"
Visibility="{Binding RegistrationStatus, Converter={StaticResource StringToVisibilityConverter}}" />
<!-- Fallback instructions panel -->
<Border BorderBrush="#DDDDDD" BorderThickness="1" Padding="8" CornerRadius="4" Margin="0,4,0,0"
<Border BorderBrush="{DynamicResource BorderSoftBrush}" BorderThickness="1" Padding="8" CornerRadius="4" Margin="0,4,0,0"
Visibility="{Binding ShowFallbackInstructions, Converter={StaticResource BooleanToVisibilityConverter}}">
<StackPanel>
<TextBlock Text="{Binding Source={x:Static loc:TranslationSource.Instance}, Path=[profile.fallback.step1]}"