fix(01-foundation): revise plans based on checker feedback
- 01-04: wave 3 → 4 (01-03 is also wave 3; parallel executor would race) - 01-06: wave 4 → 5 (cascades from 01-04 fix); add FeatureTabBase UserControl for per-tab progress/cancel strip; bind StatusBar middle item to ProgressStatus instead of ConnectionStatus per locked CONTEXT.md decision - 01-07: wave 5 → 6 (cascades) - 01-08: wave 6 → 7 (cascades) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
eeb9a3bcd1
commit
b4a901e52a
4 files changed
+120
-25
No files matched your search
@@ -2,7 +2,7 @@
|
|||||||
phase: 01-foundation
|
phase: 01-foundation
|
||||||
plan: 04
|
plan: 04
|
||||||
type: execute
|
type: execute
|
||||||
wave: 3
|
wave: 4
|
||||||
depends_on:
|
depends_on:
|
||||||
- 01-02
|
- 01-02
|
||||||
- 01-03
|
- 01-03
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
phase: 01-foundation
|
phase: 01-foundation
|
||||||
plan: 06
|
plan: 06
|
||||||
type: execute
|
type: execute
|
||||||
wave: 4
|
wave: 5
|
||||||
depends_on:
|
depends_on:
|
||||||
- 01-03
|
- 01-03
|
||||||
- 01-04
|
- 01-04
|
||||||
@@ -13,6 +13,8 @@ files_modified:
|
|||||||
- SharepointToolbox/ViewModels/MainWindowViewModel.cs
|
- SharepointToolbox/ViewModels/MainWindowViewModel.cs
|
||||||
- SharepointToolbox/ViewModels/ProfileManagementViewModel.cs
|
- SharepointToolbox/ViewModels/ProfileManagementViewModel.cs
|
||||||
- SharepointToolbox/ViewModels/Tabs/SettingsViewModel.cs
|
- SharepointToolbox/ViewModels/Tabs/SettingsViewModel.cs
|
||||||
|
- SharepointToolbox/Views/Controls/FeatureTabBase.xaml
|
||||||
|
- SharepointToolbox/Views/Controls/FeatureTabBase.xaml.cs
|
||||||
- SharepointToolbox/Views/MainWindow.xaml
|
- SharepointToolbox/Views/MainWindow.xaml
|
||||||
- SharepointToolbox/Views/MainWindow.xaml.cs
|
- SharepointToolbox/Views/MainWindow.xaml.cs
|
||||||
- SharepointToolbox/App.xaml.cs
|
- SharepointToolbox/App.xaml.cs
|
||||||
@@ -31,6 +33,8 @@ must_haves:
|
|||||||
- "Global exception handlers (DispatcherUnhandledException + TaskScheduler.UnobservedTaskException) funnel to log panel + MessageBox"
|
- "Global exception handlers (DispatcherUnhandledException + TaskScheduler.UnobservedTaskException) funnel to log panel + MessageBox"
|
||||||
- "LogPanelSink wired to MainWindow RichTextBox after Generic Host starts"
|
- "LogPanelSink wired to MainWindow RichTextBox after Generic Host starts"
|
||||||
- "FeatureViewModelBaseTests: progress reporting, cancellation, and error handling all green"
|
- "FeatureViewModelBaseTests: progress reporting, cancellation, and error handling all green"
|
||||||
|
- "All 7 stub feature tabs use FeatureTabBase UserControl — ProgressBar + TextBlock + Cancel button shown only when IsRunning"
|
||||||
|
- "StatusBar middle item shows live operation status text (ProgressStatus from ProgressUpdatedMessage), not static ConnectionStatus"
|
||||||
artifacts:
|
artifacts:
|
||||||
- path: "SharepointToolbox/ViewModels/FeatureViewModelBase.cs"
|
- path: "SharepointToolbox/ViewModels/FeatureViewModelBase.cs"
|
||||||
provides: "Base class for all feature ViewModels with canonical async command pattern"
|
provides: "Base class for all feature ViewModels with canonical async command pattern"
|
||||||
@@ -38,6 +42,9 @@ must_haves:
|
|||||||
- path: "SharepointToolbox/ViewModels/MainWindowViewModel.cs"
|
- path: "SharepointToolbox/ViewModels/MainWindowViewModel.cs"
|
||||||
provides: "Shell ViewModel with TenantProfiles and connection state"
|
provides: "Shell ViewModel with TenantProfiles and connection state"
|
||||||
contains: "ObservableCollection"
|
contains: "ObservableCollection"
|
||||||
|
- path: "SharepointToolbox/Views/Controls/FeatureTabBase.xaml"
|
||||||
|
provides: "Reusable UserControl with ProgressBar + TextBlock + Cancel button strip"
|
||||||
|
contains: "ProgressBar"
|
||||||
- path: "SharepointToolbox/Views/MainWindow.xaml"
|
- path: "SharepointToolbox/Views/MainWindow.xaml"
|
||||||
provides: "WPF shell with toolbar, TabControl, log panel, StatusBar"
|
provides: "WPF shell with toolbar, TabControl, log panel, StatusBar"
|
||||||
contains: "RichTextBox"
|
contains: "RichTextBox"
|
||||||
@@ -56,15 +63,23 @@ must_haves:
|
|||||||
pattern: "TenantSwitchedMessage"
|
pattern: "TenantSwitchedMessage"
|
||||||
- from: "SharepointToolbox/ViewModels/MainWindowViewModel.cs"
|
- from: "SharepointToolbox/ViewModels/MainWindowViewModel.cs"
|
||||||
to: "SharepointToolbox/Core/Messages/ProgressUpdatedMessage.cs"
|
to: "SharepointToolbox/Core/Messages/ProgressUpdatedMessage.cs"
|
||||||
via: "Messenger.Register<ProgressUpdatedMessage> in OnActivated — updates StatusBar observable properties"
|
via: "Messenger.Register<ProgressUpdatedMessage> in OnActivated — updates ProgressStatus + ProgressPercentage"
|
||||||
pattern: "ProgressUpdatedMessage"
|
pattern: "ProgressUpdatedMessage"
|
||||||
|
- from: "SharepointToolbox/Views/MainWindow.xaml StatusBar middle item"
|
||||||
|
to: "SharepointToolbox/ViewModels/MainWindowViewModel.cs ProgressStatus"
|
||||||
|
via: "Binding Content={Binding ProgressStatus}"
|
||||||
|
pattern: "ProgressStatus"
|
||||||
|
- from: "SharepointToolbox/Views/MainWindow.xaml stub TabItems"
|
||||||
|
to: "SharepointToolbox/Views/Controls/FeatureTabBase.xaml"
|
||||||
|
via: "TabItem Content contains <controls:FeatureTabBase />"
|
||||||
|
pattern: "FeatureTabBase"
|
||||||
---
|
---
|
||||||
|
|
||||||
<objective>
|
<objective>
|
||||||
Build the WPF shell — MainWindow XAML + all ViewModels. Wire LogPanelSink to the RichTextBox. Implement FeatureViewModelBase with the canonical async pattern. Register global exception handlers.
|
Build the WPF shell — MainWindow XAML + all ViewModels. Wire LogPanelSink to the RichTextBox. Implement FeatureViewModelBase with the canonical async pattern. Create FeatureTabBase UserControl (per-tab progress/cancel strip). Register global exception handlers.
|
||||||
|
|
||||||
Purpose: This is the first time the application visually exists. All subsequent feature plans add TabItems to the already-wired TabControl.
|
Purpose: This is the first time the application visually exists. All subsequent feature plans add TabItems to the already-wired TabControl. FeatureTabBase gives Phase 2+ a XAML template to extend rather than stub TextBlocks.
|
||||||
Output: Runnable WPF application showing the shell with placeholder tabs, log panel, and status bar.
|
Output: Runnable WPF application showing the shell with placeholder tabs (using FeatureTabBase), log panel, and status bar with live operation text.
|
||||||
</objective>
|
</objective>
|
||||||
|
|
||||||
<execution_context>
|
<execution_context>
|
||||||
@@ -109,7 +124,8 @@ public sealed class LanguageChangedMessage : ValueChangedMessage<string>
|
|||||||
// Toolbar (L→R): ComboBox (220px) → Button "Connect" → Button "Manage Profiles..." → separator → Button "Clear Session"
|
// Toolbar (L→R): ComboBox (220px) → Button "Connect" → Button "Manage Profiles..." → separator → Button "Clear Session"
|
||||||
// TabControl: 8 tabs (Permissions, Storage, File Search, Duplicates, Templates, Bulk Operations, Folder Structure, Settings)
|
// TabControl: 8 tabs (Permissions, Storage, File Search, Duplicates, Templates, Bulk Operations, Folder Structure, Settings)
|
||||||
// Log panel: RichTextBox, 150px tall, always visible, x:Name="LogPanel"
|
// Log panel: RichTextBox, 150px tall, always visible, x:Name="LogPanel"
|
||||||
// StatusBar: tenant name | operation status | progress %
|
// StatusBar: tenant name | operation status text | progress %
|
||||||
|
// Per-tab layout: ProgressBar + TextBlock + Button "Cancel" — shown only when IsRunning (CONTEXT.md Gray Areas, locked)
|
||||||
</interfaces>
|
</interfaces>
|
||||||
</context>
|
</context>
|
||||||
|
|
||||||
@@ -238,8 +254,10 @@ public sealed class LanguageChangedMessage : ValueChangedMessage<string>
|
|||||||
</task>
|
</task>
|
||||||
|
|
||||||
<task type="auto">
|
<task type="auto">
|
||||||
<name>Task 2: MainWindowViewModel, shell ViewModels, and MainWindow XAML</name>
|
<name>Task 2: FeatureTabBase UserControl, MainWindowViewModel, shell ViewModels, and MainWindow XAML</name>
|
||||||
<files>
|
<files>
|
||||||
|
SharepointToolbox/Views/Controls/FeatureTabBase.xaml,
|
||||||
|
SharepointToolbox/Views/Controls/FeatureTabBase.xaml.cs,
|
||||||
SharepointToolbox/ViewModels/MainWindowViewModel.cs,
|
SharepointToolbox/ViewModels/MainWindowViewModel.cs,
|
||||||
SharepointToolbox/ViewModels/ProfileManagementViewModel.cs,
|
SharepointToolbox/ViewModels/ProfileManagementViewModel.cs,
|
||||||
SharepointToolbox/ViewModels/Tabs/SettingsViewModel.cs,
|
SharepointToolbox/ViewModels/Tabs/SettingsViewModel.cs,
|
||||||
@@ -248,7 +266,53 @@ public sealed class LanguageChangedMessage : ValueChangedMessage<string>
|
|||||||
SharepointToolbox/App.xaml.cs
|
SharepointToolbox/App.xaml.cs
|
||||||
</files>
|
</files>
|
||||||
<action>
|
<action>
|
||||||
Create `ViewModels/Tabs/` and `Views/` directories.
|
Create `Views/Controls/`, `ViewModels/Tabs/`, and `Views/` directories.
|
||||||
|
|
||||||
|
**FeatureTabBase.xaml** — UserControl that every stub feature tab uses as its Content.
|
||||||
|
This gives Phase 2+ a concrete XAML template to replace rather than a bare TextBlock.
|
||||||
|
The progress/cancel strip is Visibility-bound to IsRunning per the locked CONTEXT.md decision.
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<UserControl x:Class="SharepointToolbox.Views.Controls.FeatureTabBase"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||||
|
<Grid>
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="*" /> <!-- Feature content area (Phase 2+ replaces this) -->
|
||||||
|
<RowDefinition Height="Auto" /> <!-- Progress/cancel strip -->
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
|
<!-- Placeholder content — Phase 2+ replaces Row 0 -->
|
||||||
|
<TextBlock Grid.Row="0"
|
||||||
|
Text="{Binding Source={x:Static loc:TranslationSource.Instance}, Path=[tab.comingsoon]}"
|
||||||
|
HorizontalAlignment="Center" VerticalAlignment="Center" />
|
||||||
|
|
||||||
|
<!-- Per-tab progress/cancel strip (locked CONTEXT.md: shown only when IsRunning) -->
|
||||||
|
<Grid Grid.Row="1" Margin="8,4"
|
||||||
|
Visibility="{Binding IsRunning, Converter={StaticResource BoolToVisibilityConverter}}">
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="*" />
|
||||||
|
<ColumnDefinition Width="Auto" />
|
||||||
|
<ColumnDefinition Width="Auto" />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<ProgressBar Grid.Column="0" Height="16" Minimum="0" Maximum="100"
|
||||||
|
Value="{Binding ProgressValue}" />
|
||||||
|
<TextBlock Grid.Column="1" Margin="8,0" VerticalAlignment="Center"
|
||||||
|
Text="{Binding StatusMessage}" />
|
||||||
|
<Button Grid.Column="2"
|
||||||
|
Content="{Binding Source={x:Static loc:TranslationSource.Instance}, Path=[btn.cancel]}"
|
||||||
|
Command="{Binding CancelCommand}" Width="70" />
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</UserControl>
|
||||||
|
```
|
||||||
|
|
||||||
|
**FeatureTabBase.xaml.cs**: Standard code-behind with no extra logic (DataContext is set by the parent TabItem's DataContext chain).
|
||||||
|
|
||||||
|
Add `BoolToVisibilityConverter` to App.xaml resources if not already present:
|
||||||
|
```xml
|
||||||
|
<BooleanToVisibilityConverter x:Key="BoolToVisibilityConverter" />
|
||||||
|
```
|
||||||
|
|
||||||
**MainWindowViewModel.cs**:
|
**MainWindowViewModel.cs**:
|
||||||
```csharp
|
```csharp
|
||||||
@@ -294,7 +358,13 @@ public sealed class LanguageChangedMessage : ValueChangedMessage<string>
|
|||||||
- `RunOperationAsync`: not applicable — stub throws `NotSupportedException` (Settings tab has no long-running operation)
|
- `RunOperationAsync`: not applicable — stub throws `NotSupportedException` (Settings tab has no long-running operation)
|
||||||
|
|
||||||
**MainWindow.xaml** — Full shell layout as locked in CONTEXT.md.
|
**MainWindow.xaml** — Full shell layout as locked in CONTEXT.md.
|
||||||
StatusBar MUST have three fields per the locked decision (tenant name | operation status text | progress percentage):
|
|
||||||
|
StatusBar middle item MUST bind to `ProgressStatus` (live operation text from ProgressUpdatedMessage),
|
||||||
|
NOT `ConnectionStatus`. Per locked CONTEXT.md: "operation status text" means the live progress text.
|
||||||
|
|
||||||
|
The 7 stub feature tabs MUST use `<controls:FeatureTabBase />` as their Content,
|
||||||
|
NOT bare TextBlocks. This gives Phase 2 a XAML template to extend.
|
||||||
|
|
||||||
```xml
|
```xml
|
||||||
<Window Title="{Binding Source={x:Static loc:TranslationSource.Instance}, Path=[app.title]}"
|
<Window Title="{Binding Source={x:Static loc:TranslationSource.Instance}, Path=[app.title]}"
|
||||||
MinWidth="900" MinHeight="600">
|
MinWidth="900" MinHeight="600">
|
||||||
@@ -313,11 +383,12 @@ public sealed class LanguageChangedMessage : ValueChangedMessage<string>
|
|||||||
Command="{Binding ClearSessionCommand}" />
|
Command="{Binding ClearSessionCommand}" />
|
||||||
</ToolBar>
|
</ToolBar>
|
||||||
|
|
||||||
<!-- StatusBar: three fields per locked layout decision -->
|
<!-- StatusBar: three fields per locked layout decision.
|
||||||
|
Middle field binds to ProgressStatus (live operation text), NOT ConnectionStatus. -->
|
||||||
<StatusBar DockPanel.Dock="Bottom" Height="24">
|
<StatusBar DockPanel.Dock="Bottom" Height="24">
|
||||||
<StatusBarItem Content="{Binding SelectedProfile.Name}" />
|
<StatusBarItem Content="{Binding SelectedProfile.Name}" />
|
||||||
<Separator />
|
<Separator />
|
||||||
<StatusBarItem Content="{Binding ConnectionStatus}" />
|
<StatusBarItem Content="{Binding ProgressStatus}" />
|
||||||
<Separator />
|
<Separator />
|
||||||
<StatusBarItem Content="{Binding ProgressPercentage, StringFormat={}{0}%}" />
|
<StatusBarItem Content="{Binding ProgressPercentage, StringFormat={}{0}%}" />
|
||||||
</StatusBar>
|
</StatusBar>
|
||||||
@@ -328,15 +399,32 @@ public sealed class LanguageChangedMessage : ValueChangedMessage<string>
|
|||||||
Background="Black" Foreground="LimeGreen"
|
Background="Black" Foreground="LimeGreen"
|
||||||
FontFamily="Consolas" FontSize="11" />
|
FontFamily="Consolas" FontSize="11" />
|
||||||
|
|
||||||
<!-- TabControl -->
|
<!-- TabControl: 7 stub tabs use FeatureTabBase; Settings tab wired in plan 01-07 -->
|
||||||
<TabControl>
|
<TabControl>
|
||||||
<TabItem Header="{Binding Source={x:Static loc:TranslationSource.Instance}, Path=[tab.permissions]}">
|
<TabItem Header="{Binding Source={x:Static loc:TranslationSource.Instance}, Path=[tab.permissions]}">
|
||||||
<TextBlock Text="{Binding Source={x:Static loc:TranslationSource.Instance}, Path=[tab.comingsoon]}"
|
<controls:FeatureTabBase />
|
||||||
HorizontalAlignment="Center" VerticalAlignment="Center" />
|
|
||||||
</TabItem>
|
</TabItem>
|
||||||
<!-- Repeat for: Storage, File Search, Duplicates, Templates, Bulk Operations, Folder Structure -->
|
<TabItem Header="{Binding Source={x:Static loc:TranslationSource.Instance}, Path=[tab.storage]}">
|
||||||
<!-- Settings tab binds to SettingsView (plan 01-07) -->
|
<controls:FeatureTabBase />
|
||||||
<TabItem Header="{Binding Source={x:Static loc:TranslationSource.Instance}, Path=[tab.settings]}">
|
</TabItem>
|
||||||
|
<TabItem Header="{Binding Source={x:Static loc:TranslationSource.Instance}, Path=[tab.filesearch]}">
|
||||||
|
<controls:FeatureTabBase />
|
||||||
|
</TabItem>
|
||||||
|
<TabItem Header="{Binding Source={x:Static loc:TranslationSource.Instance}, Path=[tab.duplicates]}">
|
||||||
|
<controls:FeatureTabBase />
|
||||||
|
</TabItem>
|
||||||
|
<TabItem Header="{Binding Source={x:Static loc:TranslationSource.Instance}, Path=[tab.templates]}">
|
||||||
|
<controls:FeatureTabBase />
|
||||||
|
</TabItem>
|
||||||
|
<TabItem Header="{Binding Source={x:Static loc:TranslationSource.Instance}, Path=[tab.bulk]}">
|
||||||
|
<controls:FeatureTabBase />
|
||||||
|
</TabItem>
|
||||||
|
<TabItem Header="{Binding Source={x:Static loc:TranslationSource.Instance}, Path=[tab.folderstructure]}">
|
||||||
|
<controls:FeatureTabBase />
|
||||||
|
</TabItem>
|
||||||
|
<!-- Settings tab: placeholder TextBlock replaced by SettingsView in plan 01-07 -->
|
||||||
|
<TabItem x:Name="SettingsTabItem"
|
||||||
|
Header="{Binding Source={x:Static loc:TranslationSource.Instance}, Path=[tab.settings]}">
|
||||||
<TextBlock Text="Settings (plan 01-07)" HorizontalAlignment="Center" VerticalAlignment="Center" />
|
<TextBlock Text="Settings (plan 01-07)" HorizontalAlignment="Center" VerticalAlignment="Center" />
|
||||||
</TabItem>
|
</TabItem>
|
||||||
</TabControl>
|
</TabControl>
|
||||||
@@ -344,6 +432,9 @@ public sealed class LanguageChangedMessage : ValueChangedMessage<string>
|
|||||||
</Window>
|
</Window>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Add namespace in Window opening tag:
|
||||||
|
`xmlns:controls="clr-namespace:SharepointToolbox.Views.Controls"`
|
||||||
|
|
||||||
**MainWindow.xaml.cs**: Constructor receives `MainWindowViewModel` via DI constructor injection. Sets `DataContext = viewModel`. Calls `viewModel.LoadProfilesAsync()` in `Loaded` event.
|
**MainWindow.xaml.cs**: Constructor receives `MainWindowViewModel` via DI constructor injection. Sets `DataContext = viewModel`. Calls `viewModel.LoadProfilesAsync()` in `Loaded` event.
|
||||||
|
|
||||||
**App.xaml.cs** — Update RegisterServices:
|
**App.xaml.cs** — Update RegisterServices:
|
||||||
@@ -397,7 +488,7 @@ public sealed class LanguageChangedMessage : ValueChangedMessage<string>
|
|||||||
<verify>
|
<verify>
|
||||||
<automated>cd "C:\Users\dev\Documents\projets\Sharepoint" && dotnet build SharepointToolbox/SharepointToolbox.csproj 2>&1 | tail -5</automated>
|
<automated>cd "C:\Users\dev\Documents\projets\Sharepoint" && dotnet build SharepointToolbox/SharepointToolbox.csproj 2>&1 | tail -5</automated>
|
||||||
</verify>
|
</verify>
|
||||||
<done>Build succeeds with 0 errors. MainWindow.xaml contains RichTextBox x:Name="LogPanel". StatusBar has three StatusBarItems (tenant name, connection status, progress %). All 8 tab headers use TranslationSource bindings. Global exception handlers registered in App.xaml.cs.</done>
|
<done>Build succeeds with 0 errors. MainWindow.xaml contains RichTextBox x:Name="LogPanel". StatusBar middle StatusBarItem binds to ProgressStatus (not ConnectionStatus). All 7 stub feature TabItems contain <controls:FeatureTabBase /> (not bare TextBlocks). Settings TabItem has x:Name="SettingsTabItem". All 8 tab headers use TranslationSource bindings. Global exception handlers registered in App.xaml.cs.</done>
|
||||||
</task>
|
</task>
|
||||||
|
|
||||||
</tasks>
|
</tasks>
|
||||||
@@ -406,7 +497,9 @@ public sealed class LanguageChangedMessage : ValueChangedMessage<string>
|
|||||||
- `dotnet build SharepointToolbox.sln` passes with 0 errors
|
- `dotnet build SharepointToolbox.sln` passes with 0 errors
|
||||||
- `dotnet test --filter "Category=Unit"` all pass
|
- `dotnet test --filter "Category=Unit"` all pass
|
||||||
- MainWindow.xaml contains `x:Name="LogPanel"` RichTextBox
|
- MainWindow.xaml contains `x:Name="LogPanel"` RichTextBox
|
||||||
- MainWindow.xaml StatusBar has three StatusBarItems: SelectedProfile.Name | ConnectionStatus | ProgressPercentage%
|
- MainWindow.xaml StatusBar middle StatusBarItem binds to `ProgressStatus` (live operation text)
|
||||||
|
- MainWindow.xaml 7 stub TabItems contain `controls:FeatureTabBase` (not TextBlocks)
|
||||||
|
- FeatureTabBase.xaml contains ProgressBar + TextBlock + Button with Visibility bound to IsRunning
|
||||||
- App.xaml.cs registers `DispatcherUnhandledException` and `TaskScheduler.UnobservedTaskException`
|
- App.xaml.cs registers `DispatcherUnhandledException` and `TaskScheduler.UnobservedTaskException`
|
||||||
- FeatureViewModelBase contains no `async void` methods (anti-pattern violation)
|
- FeatureViewModelBase contains no `async void` methods (anti-pattern violation)
|
||||||
- ObservableCollection is never modified from Task.Run (pattern 7 compliance)
|
- ObservableCollection is never modified from Task.Run (pattern 7 compliance)
|
||||||
@@ -414,7 +507,7 @@ public sealed class LanguageChangedMessage : ValueChangedMessage<string>
|
|||||||
</verification>
|
</verification>
|
||||||
|
|
||||||
<success_criteria>
|
<success_criteria>
|
||||||
Application compiles and launches to a visible WPF shell. FeatureViewModelBase tests green. All ViewModels registered in DI. Log panel wired to Serilog. StatusBar shows all three fields including live progress percentage.
|
Application compiles and launches to a visible WPF shell. FeatureViewModelBase tests green. All ViewModels registered in DI. Log panel wired to Serilog. StatusBar middle field shows live operation status text (ProgressStatus). All 7 stub feature tabs include the progress/cancel strip template via FeatureTabBase.
|
||||||
</success_criteria>
|
</success_criteria>
|
||||||
|
|
||||||
<output>
|
<output>
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
phase: 01-foundation
|
phase: 01-foundation
|
||||||
plan: 07
|
plan: 07
|
||||||
type: execute
|
type: execute
|
||||||
wave: 5
|
wave: 6
|
||||||
depends_on:
|
depends_on:
|
||||||
- 01-06
|
- 01-06
|
||||||
files_modified:
|
files_modified:
|
||||||
@@ -242,7 +242,7 @@ public class SettingsViewModel : FeatureViewModelBase
|
|||||||
```csharp
|
```csharp
|
||||||
SettingsTabItem.Content = serviceProvider.GetRequiredService<SettingsView>();
|
SettingsTabItem.Content = serviceProvider.GetRequiredService<SettingsView>();
|
||||||
```
|
```
|
||||||
Add `x:Name="SettingsTabItem"` to the Settings TabItem in XAML.
|
The Settings TabItem already has `x:Name="SettingsTabItem"` from plan 01-06.
|
||||||
|
|
||||||
Run `dotnet build` and fix any errors.
|
Run `dotnet build` and fix any errors.
|
||||||
</action>
|
</action>
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
phase: 01-foundation
|
phase: 01-foundation
|
||||||
plan: 08
|
plan: 08
|
||||||
type: execute
|
type: execute
|
||||||
wave: 6
|
wave: 7
|
||||||
depends_on:
|
depends_on:
|
||||||
- 01-07
|
- 01-07
|
||||||
files_modified: []
|
files_modified: []
|
||||||
@@ -100,6 +100,8 @@ Output: Confirmed working foundation. Green light for Phase 2.
|
|||||||
- Serilog rolling file log + LogPanelSink writing to in-app RichTextBox
|
- Serilog rolling file log + LogPanelSink writing to in-app RichTextBox
|
||||||
- Global exception handlers wired
|
- Global exception handlers wired
|
||||||
- All infrastructure patterns in place (pagination helper, retry helper, FeatureViewModelBase)
|
- All infrastructure patterns in place (pagination helper, retry helper, FeatureViewModelBase)
|
||||||
|
- Per-tab FeatureTabBase UserControl with ProgressBar + Cancel strip (shown only when IsRunning)
|
||||||
|
- StatusBar middle field shows live operation status text (ProgressStatus)
|
||||||
</what-built>
|
</what-built>
|
||||||
<how-to-verify>
|
<how-to-verify>
|
||||||
Run the application: `dotnet run --project SharepointToolbox/SharepointToolbox.csproj`
|
Run the application: `dotnet run --project SharepointToolbox/SharepointToolbox.csproj`
|
||||||
@@ -147,7 +149,7 @@ Output: Confirmed working foundation. Green light for Phase 2.
|
|||||||
All Phase 1 ROADMAP success criteria met:
|
All Phase 1 ROADMAP success criteria met:
|
||||||
1. User can create, rename, delete, and switch between tenant profiles via the UI
|
1. User can create, rename, delete, and switch between tenant profiles via the UI
|
||||||
2. MSAL token cache infrastructure ready (interactive login requires a real Azure AD tenant — not testable in this checkpoint)
|
2. MSAL token cache infrastructure ready (interactive login requires a real Azure AD tenant — not testable in this checkpoint)
|
||||||
3. Per-tab progress bar + cancel button infrastructure built (no long-running ops in Phase 1 to demo, but FeatureViewModelBase tests prove the pattern)
|
3. Per-tab progress bar + cancel button infrastructure built (FeatureTabBase UserControl wired in all 7 stub tabs; FeatureViewModelBase tests prove the pattern)
|
||||||
4. Log panel surfaces errors in red; global exception handlers registered
|
4. Log panel surfaces errors in red; global exception handlers registered
|
||||||
5. Language switches between EN and FR dynamically without restart
|
5. Language switches between EN and FR dynamically without restart
|
||||||
</verification>
|
</verification>
|
||||||
|
|||||||
Reference in new issue
Block a user