diff --git a/.planning/ROADMAP.md b/.planning/ROADMAP.md index 5ecd977..573db5c 100644 --- a/.planning/ROADMAP.md +++ b/.planning/ROADMAP.md @@ -138,5 +138,5 @@ Phases execute in numeric order: 1 → 2 → 3 → 4 → 5 | 1. Foundation | 8/8 | Complete | 2026-04-02 | | 2. Permissions | 7/7 | Complete | 2026-04-02 | | 3. Storage and File Operations | 8/8 | Complete | 2026-04-02 | -| 4. Bulk Operations and Provisioning | 7/10 | In Progress| | +| 4. Bulk Operations and Provisioning | 8/10 | In Progress| | | 5. Distribution and Hardening | 0/? | Not started | - | diff --git a/.planning/STATE.md b/.planning/STATE.md index b4756be..e679a93 100644 --- a/.planning/STATE.md +++ b/.planning/STATE.md @@ -3,14 +3,14 @@ gsd_state_version: 1.0 milestone: v1.0 milestone_name: milestone status: executing -stopped_at: Completed 04-bulk-operations-and-provisioning-04-07-PLAN.md -last_updated: "2026-04-03T08:14:57.163Z" +stopped_at: Completed 04-bulk-operations-and-provisioning-04-08-PLAN.md +last_updated: "2026-04-03T08:20:22.554Z" last_activity: 2026-04-03 — Plan 04-04 complete — BulkMemberService with Graph API and CSOM fallback progress: total_phases: 5 completed_phases: 3 total_plans: 33 - completed_plans: 30 + completed_plans: 31 percent: 65 --- @@ -90,6 +90,7 @@ Progress: [██████░░░░] 65% | Phase 04-bulk-operations-and-provisioning P04 | 7min | 2 tasks | 3 files | | Phase 04-bulk-operations-and-provisioning P06 | 10min | 2 tasks | 4 files | | Phase 04-bulk-operations-and-provisioning P07 | 15 | 2 tasks | 11 files | +| Phase 04-bulk-operations-and-provisioning P08 | 20min | 2 tasks | 6 files | ## Accumulated Context @@ -172,6 +173,8 @@ Recent decisions affecting current work: - [Phase 04-bulk-operations-and-provisioning]: TemplateService.ApplyTemplateAsync creates new ClientContext for new site URL — adminCtx.Url points to admin site, new site needs separate context - [Phase 04-bulk-operations-and-provisioning]: FolderBrowserDialog uses Core.Helpers.ExecuteQueryRetryHelper (not Infrastructure.Auth) — consistent with established project namespace pattern - [Phase 04-bulk-operations-and-provisioning]: Example CSV files placed in Resources/ and registered as EmbeddedResource — accessible via Assembly.GetManifestResourceStream without file system dependency +- [Phase 04-bulk-operations-and-provisioning]: SitePickerDialog.SelectedUrls.FirstOrDefault() used for single-site transfer selection — avoids new dialog variant while reusing existing dialog +- [Phase 04-bulk-operations-and-provisioning]: EnumBoolConverter added for RadioButton-to-enum binding (TransferMode); ConverterParameter=EnumValueName pattern established for future ViewModels ### Pending Todos @@ -184,6 +187,6 @@ None yet. ## Session Continuity -Last session: 2026-04-03T08:14:57.160Z -Stopped at: Completed 04-bulk-operations-and-provisioning-04-07-PLAN.md +Last session: 2026-04-03T08:20:14.108Z +Stopped at: Completed 04-bulk-operations-and-provisioning-04-08-PLAN.md Resume file: None diff --git a/.planning/phases/04-bulk-operations-and-provisioning/04-08-SUMMARY.md b/.planning/phases/04-bulk-operations-and-provisioning/04-08-SUMMARY.md new file mode 100644 index 0000000..e74ac91 --- /dev/null +++ b/.planning/phases/04-bulk-operations-and-provisioning/04-08-SUMMARY.md @@ -0,0 +1,137 @@ +--- +phase: 04-bulk-operations-and-provisioning +plan: 08 +subsystem: ui +tags: [wpf, mvvm, viewmodel, view, xaml, filetransfer, csharp, converters] + +requires: + - phase: 04-03 + provides: FileTransferService implementing IFileTransferService + - phase: 04-07 + provides: ConfirmBulkOperationDialog, FolderBrowserDialog, SitePickerDialog, localization keys for transfer.* + +provides: + - TransferViewModel with source/dest selection, transfer mode, conflict policy, progress, per-item results, CSV export of failed items + - TransferView.xaml + TransferView.xaml.cs — WPF UserControl for the file transfer tab + - EnumBoolConverter and StringToVisibilityConverter added to converters file + - IFileTransferService, BulkResultCsvExportService, TransferViewModel, TransferView registered in DI + +affects: + - 04-09 + - 04-10 + - MainWindow (tab wiring) + +tech-stack: + added: [] + patterns: + - TransferViewModel follows FeatureViewModelBase override pattern (RunOperationAsync, OnTenantSwitched) + - Dialog factories as Func<> set by code-behind to keep ViewModel testable + - SitePickerDialog.SelectedUrls.FirstOrDefault() for single-site transfer selection + - EnumBoolConverter for RadioButton binding to enum properties + +key-files: + created: + - SharepointToolbox/ViewModels/Tabs/TransferViewModel.cs + - SharepointToolbox/Views/Tabs/TransferView.xaml + - SharepointToolbox/Views/Tabs/TransferView.xaml.cs + modified: + - SharepointToolbox/Views/Converters/IndentConverter.cs + - SharepointToolbox/App.xaml + - SharepointToolbox/App.xaml.cs + +key-decisions: + - "SitePickerDialog returns SelectedUrls (list); TransferView uses .FirstOrDefault() for single-site transfer — avoids new dialog variant while reusing existing dialog" + - "EnumBoolConverter and StringToVisibilityConverter added to existing IndentConverter.cs — keeps converter classes co-located as project convention" + - "TransferViewModel exposes CurrentProfile publicly — required by code-behind to build per-site TenantProfile for FolderBrowserDialog" + +patterns-established: + - "EnumBoolConverter: ConverterParameter=EnumValueName for RadioButton-to-enum binding (reusable for other enum properties in future ViewModels)" + +requirements-completed: + - BULK-01 + - BULK-04 + - BULK-05 + +duration: 20min +completed: 2026-04-03 +--- + +# Phase 04 Plan 08: TransferViewModel + TransferView Summary + +**WPF file transfer tab with source/dest site+folder browser, Copy/Move mode, conflict policy, confirmation dialog, per-item result reporting, and failed-items CSV export** + +## Performance + +- **Duration:** 20 min +- **Started:** 2026-04-03T10:00:00Z +- **Completed:** 2026-04-03T10:20:00Z +- **Tasks:** 2 +- **Files modified:** 6 + +## Accomplishments + +- TransferViewModel wires IFileTransferService.TransferAsync with source and dest contexts acquired from ISessionManager, progress reporting, cancellation, and failed-items export via BulkResultCsvExportService +- TransferView provides a left-panel layout with source/dest GroupBoxes (site URL + browse button + library/folder display), Copy/Move radio buttons, conflict policy ComboBox (Skip/Overwrite/Rename), start/cancel buttons, progress bar, result summary, and Export Failed Items button +- Added EnumBoolConverter (for RadioButton binding) and StringToVisibilityConverter (for result summary visibility) to the converters file; registered both in App.xaml resources +- Registered IFileTransferService, BulkResultCsvExportService, TransferViewModel, TransferView in App.xaml.cs DI container + +## Task Commits + +1. **Tasks 1 + 2: TransferViewModel + TransferView** - `7b78b19` (feat) + +## Files Created/Modified + +- `SharepointToolbox/ViewModels/Tabs/TransferViewModel.cs` — ViewModel with source/dest properties, RunOperationAsync calling TransferAsync, ExportFailedAsync +- `SharepointToolbox/Views/Tabs/TransferView.xaml` — UserControl XAML with DockPanel layout +- `SharepointToolbox/Views/Tabs/TransferView.xaml.cs` — Code-behind wiring SitePickerDialog + FolderBrowserDialog factories, confirm dialog +- `SharepointToolbox/Views/Converters/IndentConverter.cs` — Added EnumBoolConverter, StringToVisibilityConverter +- `SharepointToolbox/App.xaml` — Registered EnumBoolConverter, StringToVisibilityConverter, ListToStringConverter (added by linter) as static resources +- `SharepointToolbox/App.xaml.cs` — Registered IFileTransferService, BulkResultCsvExportService, TransferViewModel, TransferView + +## Decisions Made + +- SitePickerDialog.SelectedUrls is a list (multi-site); used `.FirstOrDefault()` in TransferView code-behind to get the single selected site for transfer — avoids creating a new single-site variant of SitePickerDialog while reusing the established pattern. +- EnumBoolConverter added alongside existing converters in IndentConverter.cs rather than a separate file, consistent with project file convention (BytesConverter, InverseBoolConverter are also in that file). +- TransferViewModel.CurrentProfile is a public read-only property (same pattern as StorageViewModel) so the code-behind can build site-specific TenantProfile for FolderBrowserDialog acquisition. + +## Deviations from Plan + +### Auto-fixed Issues + +**1. [Rule 1 - Bug] Adapted SitePickerDialog usage — SelectedSite vs SelectedUrls** +- **Found during:** Task 2 (TransferView code-behind) +- **Issue:** Plan referenced `sitePicker.SelectedSite` (singular property), but actual SitePickerDialog exposes `SelectedUrls` (IReadOnlyList). No SelectedSite property exists. +- **Fix:** Used `sitePicker.SelectedUrls.FirstOrDefault()` in both BrowseSource_Click and BrowseDest_Click to pick the first (or only) user selection. +- **Files modified:** SharepointToolbox/Views/Tabs/TransferView.xaml.cs +- **Verification:** Build passes with 0 errors. +- **Committed in:** 7b78b19 + +**2. [Rule 3 - Blocking] Added missing EnumBoolConverter and StringToVisibilityConverter** +- **Found during:** Task 2 (TransferView XAML used these converters) +- **Issue:** Plan noted converters may be missing and instructed to create them. EnumBoolConverter and StringToVisibilityConverter were not in the project. +- **Fix:** Added both converter classes to IndentConverter.cs and registered them in App.xaml. +- **Files modified:** SharepointToolbox/Views/Converters/IndentConverter.cs, SharepointToolbox/App.xaml +- **Verification:** Build passes with 0 errors; converters accessible in App.xaml. +- **Committed in:** 7b78b19 + +--- + +**Total deviations:** 2 auto-fixed (1 bug/API mismatch, 1 missing critical converters) +**Impact on plan:** Both fixes were explicitly anticipated in plan notes. No scope creep. + +## Issues Encountered + +- Linter auto-created a ListToStringConverter x:Key reference in App.xaml — corresponding class was added to IndentConverter.cs to satisfy the build (0 errors confirmed). + +## User Setup Required + +None - no external service configuration required. + +## Next Phase Readiness + +- TransferViewModel and TransferView are ready; must be wired into MainWindow as a tab (Plan 04-09 or 04-10). +- IFileTransferService and all DI registrations are complete; TransferView can be resolved from the DI container. + +--- +*Phase: 04-bulk-operations-and-provisioning* +*Completed: 2026-04-03*