Build / build (push) Canceled after 0s
- Demo-Geraete nicht mehr nur in Debug-Builds: Abschnitt 'Testumgebung' im Verbindungs-Schritt, abschaltbar in den Einstellungen (Mac v1.8.0) - Ein simuliertes Geraet je Host fuer die App-Laufzeit, Aenderungen ueberstehen Wiederverbinden (z. B. simulierter Neustart) - Hauptfenster startet maximiert, Startbildschirm ca. 2,5 s (Mac v1.7.0/v1.8.0) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
177 lines
6.1 KiB
C#
177 lines
6.1 KiB
C#
using System.Collections.ObjectModel;
|
|
using CommunityToolkit.Mvvm.ComponentModel;
|
|
using CommunityToolkit.Mvvm.Input;
|
|
using MikrotikInstaller.App.Credentials;
|
|
using MikrotikInstaller.Core.Connectivity;
|
|
using MikrotikInstaller.Core.Connectivity.Demo;
|
|
using MikrotikInstaller.Core.Devices;
|
|
|
|
namespace MikrotikInstaller.App.ViewModels.Steps;
|
|
|
|
/// <summary>
|
|
/// Erster Schritt: Verbindungsdaten zum MikroTik-Gerät erfassen und testen — nur noch für neue,
|
|
/// unbekannte Geräte gedacht. "Bekannte Router" leben seit dem Sidebar-Umbau (MainWindow.xaml)
|
|
/// dauerhaft dort als Kurzauswahl statt hier im Hauptfenster verdoppelt zu werden; dieses ViewModel
|
|
/// hält <see cref="SavedRouters"/> aber weiterhin (die Sidebar bindet direkt über
|
|
/// <c>MainViewModel.Connection</c> darauf) und stellt <see cref="ConnectToSavedRouterCommand"/>/
|
|
/// <see cref="RemoveSavedRouterCommand"/> dafür bereit. Ein Eintrag wird erst im nächsten Schritt
|
|
/// (Geräte-Erkennung) tatsächlich gespeichert/aktualisiert — dort sind Modell und Seriennummer für
|
|
/// den Namensvorschlag bzw. die Unterscheidung zweier Geräte mit gleichem Host+Benutzername bekannt.
|
|
/// </summary>
|
|
public partial class ConnectionStepViewModel : WizardStepViewModelBase
|
|
{
|
|
private readonly WizardSession _session;
|
|
private readonly SavedRoutersStore _savedRoutersStore = new();
|
|
|
|
public ConnectionStepViewModel(WizardSession session)
|
|
: base(
|
|
title: "Verbindung",
|
|
description: "Gib die Adresse deines MikroTik-Geräts sowie Benutzername und Passwort ein.")
|
|
{
|
|
_session = session;
|
|
RefreshSavedRouters();
|
|
}
|
|
|
|
public ObservableCollection<SavedRouterEntry> SavedRouters { get; } = [];
|
|
|
|
public bool HasSavedRouters => SavedRouters.Count > 0;
|
|
|
|
/// <summary>Simulierte Testgeräte (Mac v1.8.0 „Testumgebung"), abschaltbar in den Einstellungen.</summary>
|
|
public IReadOnlyList<DemoDeviceProfile> TestDevices => DemoRouterOsClient.Profiles;
|
|
|
|
public bool ShowTestEnvironment => UserSettings.Current.TestEnvironment;
|
|
|
|
[RelayCommand]
|
|
private async Task ConnectToTestDeviceAsync(DemoDeviceProfile profile)
|
|
{
|
|
Host = profile.Host;
|
|
Username = DemoRouterOsClient.DemoUsername;
|
|
Password = DemoRouterOsClient.DemoPassword;
|
|
UseEncryption = false;
|
|
await TestConnectionAsync();
|
|
}
|
|
|
|
[ObservableProperty]
|
|
private string _host = string.Empty;
|
|
|
|
[ObservableProperty]
|
|
private string _username = "admin";
|
|
|
|
[ObservableProperty]
|
|
private string _password = string.Empty;
|
|
|
|
[ObservableProperty]
|
|
private bool _useEncryption;
|
|
|
|
[ObservableProperty]
|
|
private bool _rememberPassword = true;
|
|
|
|
[ObservableProperty]
|
|
private bool _isTesting;
|
|
|
|
[ObservableProperty]
|
|
private string? _statusMessage;
|
|
|
|
[ObservableProperty]
|
|
private bool _statusIsError;
|
|
|
|
[ObservableProperty]
|
|
[NotifyPropertyChangedFor(nameof(CanGoNext))]
|
|
private bool _isConnected;
|
|
|
|
public override bool CanGoNext => IsConnected;
|
|
|
|
private bool CanTestConnection => !IsTesting && !string.IsNullOrWhiteSpace(Host) && !string.IsNullOrWhiteSpace(Username);
|
|
|
|
public override Task OnActivatedAsync()
|
|
{
|
|
RefreshSavedRouters();
|
|
OnPropertyChanged(nameof(ShowTestEnvironment));
|
|
return Task.CompletedTask;
|
|
}
|
|
|
|
private void RefreshSavedRouters()
|
|
{
|
|
SavedRouters.Clear();
|
|
var routers = _savedRoutersStore.Load().OrderByDescending(r => r.LastConnectedAt);
|
|
|
|
foreach (var router in routers)
|
|
{
|
|
SavedRouters.Add(new SavedRouterEntry(router));
|
|
}
|
|
|
|
OnPropertyChanged(nameof(HasSavedRouters));
|
|
}
|
|
|
|
/// <summary>Nur noch intern von <see cref="ConnectToSavedRouterAsync"/> genutzt — Name/Standort werden nirgends mehr manuell bearbeitet, daher kein eigenes Kommando mehr dafür.</summary>
|
|
private void UseSavedRouter(SavedRouterEntry entry)
|
|
{
|
|
Host = entry.Host;
|
|
Username = entry.Username;
|
|
var storedPassword = WindowsCredentialStore.TryRead(entry.Id);
|
|
Password = storedPassword ?? string.Empty;
|
|
RememberPassword = storedPassword is not null;
|
|
}
|
|
|
|
/// <summary>Ein-Klick-Verbinden für die Sidebar-Kurzauswahl — übernimmt die Zugangsdaten und verbindet direkt, ohne den Umweg über die Formularfelder.</summary>
|
|
[RelayCommand]
|
|
private async Task ConnectToSavedRouterAsync(SavedRouterEntry entry)
|
|
{
|
|
UseSavedRouter(entry);
|
|
await TestConnectionAsync();
|
|
}
|
|
|
|
[RelayCommand]
|
|
private void RemoveSavedRouter(SavedRouterEntry entry)
|
|
{
|
|
_savedRoutersStore.Remove(entry.Id);
|
|
WindowsCredentialStore.Delete(entry.Id);
|
|
SavedRouters.Remove(entry);
|
|
OnPropertyChanged(nameof(HasSavedRouters));
|
|
}
|
|
|
|
[RelayCommand(CanExecute = nameof(CanTestConnection))]
|
|
private async Task TestConnectionAsync()
|
|
{
|
|
IsTesting = true;
|
|
StatusMessage = "Verbindung wird getestet …";
|
|
StatusIsError = false;
|
|
IsConnected = false;
|
|
|
|
await _session.DisposeClientAsync();
|
|
_session.Device = null;
|
|
|
|
try
|
|
{
|
|
var credentials = new RouterOsCredentials(Host.Trim(), Username.Trim(), Password)
|
|
{
|
|
UseEncryption = UseEncryption,
|
|
};
|
|
|
|
_session.Client = await RouterOsClientFactory.ConnectAsync(credentials);
|
|
_session.Credentials = credentials;
|
|
_session.RememberPassword = RememberPassword;
|
|
|
|
IsConnected = true;
|
|
StatusIsError = false;
|
|
StatusMessage = "Verbindung erfolgreich hergestellt.";
|
|
}
|
|
catch (RouterOsException ex)
|
|
{
|
|
IsConnected = false;
|
|
StatusIsError = true;
|
|
StatusMessage = ex.Message;
|
|
}
|
|
finally
|
|
{
|
|
IsTesting = false;
|
|
}
|
|
}
|
|
|
|
partial void OnHostChanged(string value) => TestConnectionCommand.NotifyCanExecuteChanged();
|
|
|
|
partial void OnUsernameChanged(string value) => TestConnectionCommand.NotifyCanExecuteChanged();
|
|
|
|
partial void OnIsTestingChanged(bool value) => TestConnectionCommand.NotifyCanExecuteChanged();
|
|
}
|