Files
Sharepoint-Toolbox/SharepointToolbox/ViewModels/Tabs/SettingsViewModel.cs
Dev 5920d42614 feat(01-06): build WPF shell — MainWindow XAML, ViewModels, LogPanelSink wiring
- Add FeatureTabBase UserControl with ProgressBar/TextBlock/CancelButton strip
  (Visibility bound to IsRunning, shown only during operations)
- Add MainWindowViewModel with TenantProfiles ObservableCollection, ConnectCommand,
  ClearSessionCommand, ManageProfilesCommand, ProgressUpdatedMessage subscription
- Add ProfileManagementViewModel wrapping ProfileService CRUD with input validation
- Add SettingsViewModel (extends FeatureViewModelBase) with language/folder settings
- Update MainWindow.xaml: DockPanel shell with Toolbar, TabControl (8 tabs), 150px
  RichTextBox LogPanel, StatusBar (tenant name | ProgressStatus | ProgressPercentage)
- MainWindow.xaml.cs: DI constructor, DataContext=viewModel, LoadProfilesAsync on Loaded
- App.xaml.cs: register all services, wire LogPanelSink after MainWindow resolved,
  register DispatcherUnhandledException and UnobservedTaskException global handlers
- App.xaml: add BoolToVisibilityConverter resource
2026-04-02 12:32:41 +02:00

95 lines
2.7 KiB
C#

using System.Globalization;
using Microsoft.Win32;
using CommunityToolkit.Mvvm.Input;
using Microsoft.Extensions.Logging;
using SharepointToolbox.Core.Models;
using SharepointToolbox.Localization;
using SharepointToolbox.Services;
namespace SharepointToolbox.ViewModels.Tabs;
public partial class SettingsViewModel : FeatureViewModelBase
{
private readonly SettingsService _settingsService;
private string _selectedLanguage = "en";
public string SelectedLanguage
{
get => _selectedLanguage;
set
{
if (_selectedLanguage == value) return;
_selectedLanguage = value;
OnPropertyChanged();
_ = ApplyLanguageAsync(value);
}
}
private string _dataFolder = string.Empty;
public string DataFolder
{
get => _dataFolder;
set
{
if (_dataFolder == value) return;
_dataFolder = value;
OnPropertyChanged();
_ = _settingsService.SetDataFolderAsync(value);
}
}
public RelayCommand BrowseFolderCommand { get; }
public SettingsViewModel(SettingsService settingsService, ILogger<FeatureViewModelBase> logger)
: base(logger)
{
_settingsService = settingsService;
BrowseFolderCommand = new RelayCommand(BrowseFolder);
}
public async Task LoadAsync()
{
var settings = await _settingsService.GetSettingsAsync();
_selectedLanguage = settings.Lang;
_dataFolder = settings.DataFolder;
OnPropertyChanged(nameof(SelectedLanguage));
OnPropertyChanged(nameof(DataFolder));
}
private async Task ApplyLanguageAsync(string code)
{
try
{
TranslationSource.Instance.CurrentCulture = new CultureInfo(code);
await _settingsService.SetLanguageAsync(code);
}
catch (Exception ex)
{
StatusMessage = ex.Message;
}
}
private void BrowseFolder()
{
// OpenFolderDialog is available in .NET 8+ via Microsoft.Win32
var dialog = new OpenFolderDialog
{
Title = "Select data output folder",
InitialDirectory = string.IsNullOrEmpty(_dataFolder)
? Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)
: _dataFolder
};
if (dialog.ShowDialog() == true)
{
DataFolder = dialog.FolderName;
}
}
protected override Task RunOperationAsync(CancellationToken ct, IProgress<OperationProgress> progress)
{
// Settings tab has no long-running operation
throw new NotSupportedException("Settings tab does not have a run operation.");
}
}