docs(13-02): complete User Directory ViewModel plan
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
203
.planning/phases/12-branding-ui-views/12-03-PLAN.md
Normal file
203
.planning/phases/12-branding-ui-views/12-03-PLAN.md
Normal file
@@ -0,0 +1,203 @@
|
||||
---
|
||||
phase: 12-branding-ui-views
|
||||
plan: 03
|
||||
type: execute
|
||||
wave: 2
|
||||
depends_on: [12-01]
|
||||
files_modified:
|
||||
- SharepointToolbox/Views/Dialogs/ProfileManagementDialog.xaml
|
||||
autonomous: true
|
||||
requirements:
|
||||
- BRAND-04
|
||||
|
||||
must_haves:
|
||||
truths:
|
||||
- "ProfileManagementDialog shows a Client Logo section between the input fields and the action buttons"
|
||||
- "The logo section shows a live thumbnail preview bound to ClientLogoPreview via Base64ToImageConverter"
|
||||
- "When ClientLogoPreview is null, the preview area shows a 'No logo configured' placeholder text"
|
||||
- "Import, Clear, and Pull from Entra buttons are bound to BrowseClientLogoCommand, ClearClientLogoCommand, and AutoPullClientLogoCommand respectively"
|
||||
- "All three logo buttons are disabled when no profile is selected"
|
||||
- "ValidationMessage displays below the logo buttons when set"
|
||||
- "Dialog height is increased to accommodate the new section"
|
||||
artifacts:
|
||||
- path: "SharepointToolbox/Views/Dialogs/ProfileManagementDialog.xaml"
|
||||
provides: "Client logo section with live preview, import, clear, and auto-pull controls"
|
||||
contains: "ClientLogoPreview"
|
||||
key_links:
|
||||
- from: "SharepointToolbox/Views/Dialogs/ProfileManagementDialog.xaml"
|
||||
to: "SharepointToolbox/ViewModels/ProfileManagementViewModel.cs"
|
||||
via: "data binding"
|
||||
pattern: "BrowseClientLogoCommand|ClearClientLogoCommand|AutoPullClientLogoCommand|ClientLogoPreview"
|
||||
- from: "SharepointToolbox/Views/Dialogs/ProfileManagementDialog.xaml"
|
||||
to: "SharepointToolbox/Views/Converters/Base64ToImageSourceConverter.cs"
|
||||
via: "StaticResource"
|
||||
pattern: "Base64ToImageConverter"
|
||||
---
|
||||
|
||||
<objective>
|
||||
Add the client logo section to ProfileManagementDialog.xaml with live thumbnail preview, Import, Clear, and Pull from Entra buttons.
|
||||
|
||||
Purpose: Allows administrators to see, import, clear, and auto-pull client logos per tenant directly from the profile management dialog.
|
||||
|
||||
Output: Updated ProfileManagementDialog.xaml with a client logo section and increased dialog height.
|
||||
</objective>
|
||||
|
||||
<execution_context>
|
||||
@C:/Users/dev/.claude/get-shit-done/workflows/execute-plan.md
|
||||
@C:/Users/dev/.claude/get-shit-done/templates/summary.md
|
||||
</execution_context>
|
||||
|
||||
<context>
|
||||
@.planning/PROJECT.md
|
||||
@.planning/ROADMAP.md
|
||||
@.planning/STATE.md
|
||||
@.planning/phases/12-branding-ui-views/12-RESEARCH.md
|
||||
|
||||
<interfaces>
|
||||
<!-- ProfileManagementViewModel properties and commands (Phase 11 + 12-01) -->
|
||||
|
||||
From SharepointToolbox/ViewModels/ProfileManagementViewModel.cs:
|
||||
```csharp
|
||||
public string? ClientLogoPreview { get; } // data URI string or null (added in 12-01)
|
||||
public IAsyncRelayCommand BrowseClientLogoCommand { get; } // gated on SelectedProfile != null
|
||||
public IAsyncRelayCommand ClearClientLogoCommand { get; } // gated on SelectedProfile != null
|
||||
public IAsyncRelayCommand AutoPullClientLogoCommand { get; } // gated on SelectedProfile != null
|
||||
public string ValidationMessage { get; set; } // set on error or success feedback
|
||||
public TenantProfile? SelectedProfile { get; set; }
|
||||
```
|
||||
|
||||
<!-- Current ProfileManagementDialog.xaml structure -->
|
||||
From SharepointToolbox/Views/Dialogs/ProfileManagementDialog.xaml:
|
||||
```xml
|
||||
<Window ... Width="500" Height="480" ResizeMode="NoResize">
|
||||
<Grid Margin="12">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" /> <!-- Row 0: Label "Profiles" -->
|
||||
<RowDefinition Height="*" /> <!-- Row 1: Profile ListBox -->
|
||||
<RowDefinition Height="Auto" /> <!-- Row 2: Input fields (Name/URL/ClientId) -->
|
||||
<RowDefinition Height="Auto" /> <!-- Row 3: Action buttons -->
|
||||
</Grid.RowDefinitions>
|
||||
...
|
||||
</Grid>
|
||||
</Window>
|
||||
```
|
||||
|
||||
<!-- Available converters from App.xaml -->
|
||||
- `{StaticResource Base64ToImageConverter}` — converts data URI string to BitmapImage
|
||||
- `{StaticResource StringToVisibilityConverter}` — Visible if non-empty, else Collapsed
|
||||
</interfaces>
|
||||
</context>
|
||||
|
||||
<tasks>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 1: Add client logo section and resize ProfileManagementDialog</name>
|
||||
<files>
|
||||
SharepointToolbox/Views/Dialogs/ProfileManagementDialog.xaml
|
||||
</files>
|
||||
<behavior>
|
||||
- Dialog height increases from 480 to 620 to accommodate the logo section
|
||||
- A new row (Row 3) is inserted between the input fields (Row 2) and buttons (now Row 4)
|
||||
- The client logo section contains:
|
||||
a) A labeled GroupBox "Client Logo" (localized)
|
||||
b) Inside: a Border with either an Image preview or placeholder text
|
||||
c) Three buttons: Import, Clear, Pull from Entra — horizontally aligned
|
||||
d) A TextBlock for ValidationMessage feedback
|
||||
- All logo controls are visually disabled when no profile is selected (via command CanExecute)
|
||||
- ValidationMessage shows success/error messages (already set by ViewModel commands)
|
||||
</behavior>
|
||||
<action>
|
||||
1. Edit `SharepointToolbox/Views/Dialogs/ProfileManagementDialog.xaml`:
|
||||
|
||||
a) Increase dialog height from 480 to 620:
|
||||
Change `Height="480"` to `Height="620"`
|
||||
|
||||
b) Add a new Row 3 for the logo section. Update RowDefinitions to:
|
||||
```xml
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" /> <!-- Row 0: Label -->
|
||||
<RowDefinition Height="*" /> <!-- Row 1: ListBox -->
|
||||
<RowDefinition Height="Auto" /> <!-- Row 2: Input fields -->
|
||||
<RowDefinition Height="Auto" /> <!-- Row 3: Client logo (NEW) -->
|
||||
<RowDefinition Height="Auto" /> <!-- Row 4: Buttons (was Row 3) -->
|
||||
</Grid.RowDefinitions>
|
||||
```
|
||||
|
||||
c) Move existing buttons StackPanel from Grid.Row="3" to Grid.Row="4"
|
||||
|
||||
d) Add the client logo section at Grid.Row="3":
|
||||
```xml
|
||||
<!-- 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>
|
||||
```
|
||||
|
||||
Key decisions:
|
||||
- GroupBox replaced with Label + StackPanel for consistency with SettingsView pattern
|
||||
- Smaller preview (60px height vs 80px in Settings) because dialog has less space
|
||||
- Pull from Entra button is wider (130px) to fit localized text
|
||||
- ValidationMessage already set by Browse/Clear/AutoPull commands — just needs display
|
||||
- All three buttons auto-disable via ICommand.CanExecute when SelectedProfile is null
|
||||
</action>
|
||||
<verify>
|
||||
<automated>dotnet build --no-restore -warnaserror</automated>
|
||||
</verify>
|
||||
<done>ProfileManagementDialog shows client logo section with preview, three buttons, and feedback. Dialog resized. Build passes.</done>
|
||||
</task>
|
||||
|
||||
</tasks>
|
||||
|
||||
<verification>
|
||||
```bash
|
||||
dotnet build --no-restore -warnaserror
|
||||
```
|
||||
Build must pass with zero failures. Visual verification requires manual testing.
|
||||
</verification>
|
||||
|
||||
<success_criteria>
|
||||
- ProfileManagementDialog.xaml has a visible Client Logo section between input fields and buttons
|
||||
- Image binds to ClientLogoPreview via Base64ToImageConverter
|
||||
- Placeholder text shows when no logo is configured
|
||||
- Import, Clear, and Pull from Entra buttons bind to existing ViewModel commands
|
||||
- All logo buttons disabled when no profile selected
|
||||
- ValidationMessage displays feedback when set
|
||||
- Dialog height increased to 620 to accommodate new section
|
||||
- Build passes with zero warnings
|
||||
</success_criteria>
|
||||
|
||||
<output>
|
||||
After completion, create `.planning/phases/12-branding-ui-views/12-03-SUMMARY.md`
|
||||
</output>
|
||||
Reference in New Issue
Block a user