- 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
95 lines
2.7 KiB
C#
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.");
|
|
}
|
|
}
|