using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Windows; using System.Windows.Controls; using SharepointToolbox.Core.Models; using SharepointToolbox.Services; namespace SharepointToolbox.Views.Dialogs; /// /// Dialog for selecting multiple SharePoint sites. /// Loads sites from ISiteListService, shows them in a filterable list with checkboxes. /// public partial class SitePickerDialog : Window { private readonly ISiteListService _siteListService; private readonly TenantProfile _profile; private List _allItems = new(); /// /// Returns the list of sites the user checked before clicking OK. /// public IReadOnlyList SelectedUrls => _allItems.Where(i => i.IsSelected).Select(i => new SiteInfo(i.Url, i.Title)).ToList(); public SitePickerDialog(ISiteListService siteListService, TenantProfile profile) { InitializeComponent(); _siteListService = siteListService; _profile = profile; } private async void Window_Loaded(object sender, RoutedEventArgs e) => await LoadSitesAsync(); private async Task LoadSitesAsync() { StatusText.Text = "Loading sites..."; LoadButton.IsEnabled = false; try { var sites = await _siteListService.GetSitesAsync( _profile, new Progress(), System.Threading.CancellationToken.None); _allItems = sites.Select(s => new SitePickerItem(s.Url, s.Title)).ToList(); ApplyFilter(); StatusText.Text = $"{_allItems.Count} sites loaded."; } catch (InvalidOperationException ex) { StatusText.Text = ex.Message; } catch (Exception ex) { StatusText.Text = $"Error: {ex.Message}"; } finally { LoadButton.IsEnabled = true; } } private void ApplyFilter() { var filter = FilterBox.Text.Trim(); SiteList.ItemsSource = string.IsNullOrEmpty(filter) ? (IEnumerable)_allItems : _allItems.Where(i => i.Url.Contains(filter, StringComparison.OrdinalIgnoreCase) || i.Title.Contains(filter, StringComparison.OrdinalIgnoreCase)).ToList(); } private void FilterBox_TextChanged(object sender, TextChangedEventArgs e) => ApplyFilter(); private void SelectAll_Click(object sender, RoutedEventArgs e) { foreach (var item in _allItems) item.IsSelected = true; ApplyFilter(); } private void DeselectAll_Click(object sender, RoutedEventArgs e) { foreach (var item in _allItems) item.IsSelected = false; ApplyFilter(); } private async void LoadButton_Click(object sender, RoutedEventArgs e) => await LoadSitesAsync(); private void OK_Click(object sender, RoutedEventArgs e) { DialogResult = true; Close(); } } /// /// Mutable wrapper for a site entry shown in the SitePickerDialog list. /// Supports two-way CheckBox binding via INotifyPropertyChanged. /// public class SitePickerItem : INotifyPropertyChanged { private bool _isSelected; public string Url { get; init; } = string.Empty; public string Title { get; init; } = string.Empty; public bool IsSelected { get => _isSelected; set { if (_isSelected == value) return; _isSelected = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(IsSelected))); } } public event PropertyChangedEventHandler? PropertyChanged; public SitePickerItem(string url, string title) { Url = url; Title = title; } }