Files
Sharepoint-Toolbox/SharepointToolbox/Views/Dialogs/ProfileManagementDialog.xaml
Dev 809ac8613b feat(19-02): add app registration UI to profile dialog and 7 ViewModel tests
- ProfileManagementDialog.xaml: height 750, new Row 4 with Register/Remove buttons
- BooleanToVisibilityConverter added to Window.Resources
- Fallback instructions panel bound to ShowFallbackInstructions
- RegistrationStatus text block with StringToVisibilityConverter
- Buttons row shifted to Row 5
- ProfileManagementViewModelRegistrationTests: 7 unit tests, all passing
- ProfileManagementViewModelLogoTests: updated to 5-param constructor
2026-04-09 15:19:37 +02:00

142 lines
7.9 KiB
XML

<Window x:Class="SharepointToolbox.Views.Dialogs.ProfileManagementDialog"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:loc="clr-namespace:SharepointToolbox.Localization"
Title="Manage Profiles" Width="500" Height="750"
WindowStartupLocation="CenterOwner" ShowInTaskbar="False"
ResizeMode="NoResize">
<Window.Resources>
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
</Window.Resources>
<Grid Margin="12">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<!-- Profile list -->
<Label Content="Profiles" Grid.Row="0" />
<ListBox Grid.Row="1" Margin="0,0,0,8"
ItemsSource="{Binding Profiles}"
SelectedItem="{Binding SelectedProfile}"
DisplayMemberPath="Name" />
<!-- Input fields -->
<Grid Grid.Row="2" Margin="0,0,0,8">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Label Content="{Binding Source={x:Static loc:TranslationSource.Instance}, Path=[profile.name]}"
Grid.Row="0" Grid.Column="0" />
<TextBox Text="{Binding NewName, UpdateSourceTrigger=PropertyChanged}"
Grid.Row="0" Grid.Column="1" Margin="0,2" />
<Label Content="{Binding Source={x:Static loc:TranslationSource.Instance}, Path=[profile.url]}"
Grid.Row="1" Grid.Column="0" />
<TextBox Text="{Binding NewTenantUrl, UpdateSourceTrigger=PropertyChanged}"
Grid.Row="1" Grid.Column="1" Margin="0,2" />
<Label Content="{Binding Source={x:Static loc:TranslationSource.Instance}, Path=[profile.clientid]}"
Grid.Row="2" Grid.Column="0" />
<TextBox Text="{Binding NewClientId, UpdateSourceTrigger=PropertyChanged}"
Grid.Row="2" Grid.Column="1" Margin="0,2" />
</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"
HorizontalAlignment="Left" MinWidth="200" MinHeight="50">
<Grid>
<Image Source="{Binding ClientLogoPreview, Converter={StaticResource Base64ToImageConverter}}"
MaxHeight="60" MaxWidth="200" Stretch="Uniform" HorizontalAlignment="Left"
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">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Setter Property="Visibility" Value="Visible" />
<Style.Triggers>
<DataTrigger Binding="{Binding ClientLogoPreview, Converter={StaticResource StringToVisibilityConverter}}" Value="Visible">
<Setter Property="Visibility" Value="Collapsed" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</Grid>
</Border>
<StackPanel Orientation="Horizontal" Margin="0,6,0,0">
<Button Content="{Binding Source={x:Static loc:TranslationSource.Instance}, Path=[profile.logo.browse]}"
Command="{Binding BrowseClientLogoCommand}" Width="80" Margin="0,0,8,0" />
<Button Content="{Binding Source={x:Static loc:TranslationSource.Instance}, Path=[profile.logo.clear]}"
Command="{Binding ClearClientLogoCommand}" Width="80" Margin="0,0,8,0" />
<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"
Visibility="{Binding ValidationMessage, Converter={StaticResource StringToVisibilityConverter}}" />
</StackPanel>
<!-- App Registration -->
<StackPanel Grid.Row="4" Margin="0,8,0,8">
<Label Content="{Binding Source={x:Static loc:TranslationSource.Instance}, Path=[profile.fallback.title]}"
FontWeight="SemiBold" Padding="0,0,0,4"
Visibility="{Binding ShowFallbackInstructions, Converter={StaticResource BooleanToVisibilityConverter}}" />
<!-- Register / Remove buttons -->
<StackPanel Orientation="Horizontal" Margin="0,0,0,4">
<Button Content="{Binding Source={x:Static loc:TranslationSource.Instance}, Path=[profile.register]}"
Command="{Binding RegisterAppCommand}" Width="120" Margin="0,0,8,0" />
<Button Content="{Binding Source={x:Static loc:TranslationSource.Instance}, Path=[profile.remove]}"
Command="{Binding RemoveAppCommand}" Width="120" Margin="0,0,8,0" />
</StackPanel>
<!-- Status text -->
<TextBlock Text="{Binding RegistrationStatus}" FontSize="11" Margin="0,2,0,0"
Foreground="#006600"
Visibility="{Binding RegistrationStatus, Converter={StaticResource StringToVisibilityConverter}}" />
<!-- Fallback instructions panel -->
<Border BorderBrush="#DDDDDD" 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]}"
TextWrapping="Wrap" Margin="0,2" />
<TextBlock Text="{Binding Source={x:Static loc:TranslationSource.Instance}, Path=[profile.fallback.step2]}"
TextWrapping="Wrap" Margin="0,2" />
<TextBlock Text="{Binding Source={x:Static loc:TranslationSource.Instance}, Path=[profile.fallback.step3]}"
TextWrapping="Wrap" Margin="0,2" />
<TextBlock Text="{Binding Source={x:Static loc:TranslationSource.Instance}, Path=[profile.fallback.step4]}"
TextWrapping="Wrap" Margin="0,2" />
<TextBlock Text="{Binding Source={x:Static loc:TranslationSource.Instance}, Path=[profile.fallback.step5]}"
TextWrapping="Wrap" Margin="0,2" />
<TextBlock Text="{Binding Source={x:Static loc:TranslationSource.Instance}, Path=[profile.fallback.step6]}"
TextWrapping="Wrap" Margin="0,2" />
</StackPanel>
</Border>
</StackPanel>
<!-- Buttons -->
<StackPanel Grid.Row="5" Orientation="Horizontal" HorizontalAlignment="Right">
<Button Content="{Binding Source={x:Static loc:TranslationSource.Instance}, Path=[profile.add]}"
Command="{Binding AddCommand}" Width="60" Margin="4,0" />
<Button Content="{Binding Source={x:Static loc:TranslationSource.Instance}, Path=[profile.rename]}"
Command="{Binding RenameCommand}" Width="60" Margin="4,0" />
<Button Content="{Binding Source={x:Static loc:TranslationSource.Instance}, Path=[profile.delete]}"
Command="{Binding DeleteCommand}" Width="60" Margin="4,0" />
<Button Content="Close" Width="60" Margin="4,0"
Click="CloseButton_Click" IsCancel="True" />
</StackPanel>
</Grid>
</Window>