Add server profile editing and deletion

This commit is contained in:
Ochenstarik 2026-07-16 19:13:44 +07:00
parent bd94af38e7
commit 46f00afb7d
3 changed files with 110 additions and 2 deletions

View file

@ -18,8 +18,8 @@
- [x] сохранять профили локально без паролей;
- [x] получать CPU/load, RAM, disk, uptime и latency;
- [x] собрать и реально запустить x64-приложение;
- [ ] редактирование и удаление серверов;
- [ ] единственный изменяемый Hub;
- [x] редактирование и удаление серверов;
- [x] единственный изменяемый Hub;
- [ ] настоящие страницы Servers, Links, Sessions и Settings.
## Этап 2 — установщик Hub/Node

View file

@ -79,6 +79,16 @@
Click="AddServerButton_Click"
Icon="Add"
Label="Добавить сервер" />
<AppBarButton
AutomationProperties.Name="Изменить выбранный сервер"
Click="EditServerButton_Click"
Icon="Edit"
Label="Изменить" />
<AppBarButton
AutomationProperties.Name="Удалить выбранный сервер"
Click="DeleteServerButton_Click"
Icon="Delete"
Label="Удалить" />
</CommandBar>
</Grid>

View file

@ -154,6 +154,11 @@ public sealed partial class MainPage : Page
{
return;
}
if (hubBox.IsChecked == true && Servers.Any(server => server.IsHub))
{
ShowInfo("Hub уже выбран", "Измените существующий Hub или снимите эту отметку.", InfoBarSeverity.Warning);
return;
}
var profile = new ServerProfileData(
Guid.NewGuid().ToString("N"),
@ -169,6 +174,99 @@ public sealed partial class MainPage : Page
await RefreshServerAsync(server);
}
private async void EditServerButton_Click(object sender, RoutedEventArgs e)
{
if (ServerList.SelectedItem is not ServerViewModel selected)
{
ShowInfo("Сервер не выбран", "Выберите сервер в списке для изменения.", InfoBarSeverity.Warning);
return;
}
var nameBox = new TextBox { Header = "Название", Text = selected.Profile.Name };
var hostBox = new TextBox { Header = "IP или домен", Text = selected.Profile.Host };
var portBox = new NumberBox
{
Header = "SSH-порт",
Value = selected.Profile.Port,
Minimum = 1,
Maximum = 65535,
SpinButtonPlacementMode = NumberBoxSpinButtonPlacementMode.Compact
};
var userBox = new TextBox { Header = "Пользователь", Text = selected.Profile.User };
var hubBox = new CheckBox { Content = "Это главный Mesh Hub", IsChecked = selected.IsHub };
AutomationProperties.SetName(hubBox, "Использовать сервер как главный Mesh Hub");
var dialog = new ContentDialog
{
XamlRoot = XamlRoot,
Title = "Изменить сервер",
Content = new StackPanel
{
Spacing = 12,
MinWidth = 420,
Children = { nameBox, hostBox, portBox, userBox, hubBox }
},
PrimaryButtonText = "Сохранить",
CloseButtonText = "Отмена",
DefaultButton = ContentDialogButton.Primary
};
if (await dialog.ShowAsync() != ContentDialogResult.Primary)
{
return;
}
if (string.IsNullOrWhiteSpace(nameBox.Text)
|| string.IsNullOrWhiteSpace(hostBox.Text)
|| string.IsNullOrWhiteSpace(userBox.Text)
|| double.IsNaN(portBox.Value))
{
ShowInfo("Данные не сохранены", "Название, адрес, порт и пользователь обязательны.", InfoBarSeverity.Warning);
return;
}
if (hubBox.IsChecked == true && Servers.Any(server => server.IsHub && server != selected))
{
ShowInfo("Hub уже выбран", "В конфигурации может быть только один главный Mesh Hub.", InfoBarSeverity.Warning);
return;
}
var index = Servers.IndexOf(selected);
var updated = new ServerViewModel(new ServerProfileData(
selected.Profile.Id,
nameBox.Text.Trim(),
hostBox.Text.Trim(),
checked((int)portBox.Value),
userBox.Text.Trim(),
hubBox.IsChecked == true));
Servers[index] = updated;
await SaveProfilesAsync();
await RefreshServerAsync(updated);
ShowInfo("Сервер изменён", updated.Name, InfoBarSeverity.Success);
}
private async void DeleteServerButton_Click(object sender, RoutedEventArgs e)
{
if (ServerList.SelectedItem is not ServerViewModel selected)
{
ShowInfo("Сервер не выбран", "Выберите сервер в списке для удаления.", InfoBarSeverity.Warning);
return;
}
var dialog = new ContentDialog
{
XamlRoot = XamlRoot,
Title = $"Удалить {selected.Name}?",
Content = "Удаляется только локальный профиль. Серверная часть и WireGuard Node останутся установленными.",
PrimaryButtonText = "Удалить профиль",
CloseButtonText = "Отмена",
DefaultButton = ContentDialogButton.Close
};
if (await dialog.ShowAsync() != ContentDialogResult.Primary)
{
return;
}
Servers.Remove(selected);
await SaveProfilesAsync();
UpdateEmptyState();
ShowInfo("Профиль удалён", selected.Name, InfoBarSeverity.Success);
}
private async void RefreshButton_Click(object sender, RoutedEventArgs e)
=> await RefreshAllAsync();