Files
123123/ZA.CoreService.ESBCertificateManager/Setup/SelectContainersForm.cs
T

433 lines
13 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using ZA.CoreService.ESBCertificateManager.Models;
using ZA.CoreService.ESBCertificateManager.Services;
namespace ZA.CoreService.ESBCertificateManager.Setup;
public sealed class SelectContainersForm : Form
{
private readonly SetupCoordinator _coordinator;
private readonly SonicSystemOption _system;
private readonly SonicContainerScanner _scanner;
private readonly ComboBox _cmbCompany;
private readonly CheckedListBox _lstContainers;
private readonly TextBox _txtManual;
private readonly TextBox _txtUser;
private readonly TextBox _txtPassword;
private readonly Label _lblStatus;
private readonly Button _btnScan;
private readonly Button _btnSave;
private bool _running;
public int SavedCount { get; private set; }
public SelectContainersForm(
SetupCoordinator coordinator,
SonicSystemOption system)
{
_coordinator = coordinator;
_system = system;
_scanner = new SonicContainerScanner(coordinator.Settings.Runtime);
Text = "Container auswählen";
StartPosition = FormStartPosition.CenterParent;
FormBorderStyle = FormBorderStyle.FixedDialog;
MaximizeBox = false;
MinimizeBox = false;
ShowInTaskbar = false;
ClientSize = new Size(640, 620);
BackColor = SettingsUi.Background;
ForeColor = SettingsUi.Text;
Font = new Font("Segoe UI", 10f);
Label title = new()
{
Text = "Container für System",
Location = new Point(28, 20),
AutoSize = true,
Font = new Font("Segoe UI Semibold", 18f, FontStyle.Bold),
ForeColor = SettingsUi.Text
};
Label subtitle = new()
{
Text =
$"{system.ConnectionName} · {system.ConnectionUrl}"
+ Environment.NewLine
+ "Scan von Sonic oder manuell eintragen, dann übernehmen.",
Location = new Point(30, 54),
Size = new Size(580, 40),
ForeColor = SettingsUi.Muted
};
Panel card = SettingsUi.CreateCard();
card.Location = new Point(28, 110);
card.Size = new Size(584, 430);
card.Paint += SettingsUi.PaintCardBorder;
_cmbCompany = SettingsUi.CreateComboBox();
_lstContainers = new CheckedListBox
{
BackColor = Color.FromArgb(12, 28, 48),
ForeColor = SettingsUi.Text,
BorderStyle = BorderStyle.FixedSingle,
CheckOnClick = true,
Font = new Font("Segoe UI", 10f)
};
_txtManual = SettingsUi.CreateTextBox();
_txtUser = SettingsUi.CreateTextBox();
_txtPassword = SettingsUi.CreateTextBox();
_txtPassword.UseSystemPasswordChar = true;
AddField(card, "Company", _cmbCompany, 18, 16, 540);
AddField(card, "Gefundene / gewählte Container", _lstContainers, 18, 76, 540, 150);
Label manualLabel = SettingsUi.CreateFieldLabel("Manuell hinzufügen");
manualLabel.Location = new Point(18, 240);
_txtManual.Location = new Point(18, 262);
_txtManual.Width = 400;
Button btnAddManual = SettingsUi.CreateGhostButton("");
btnAddManual.Location = new Point(430, 260);
btnAddManual.Size = new Size(50, 32);
btnAddManual.Click += (_, _) => AddManualContainer();
Button btnSuggest = SettingsUi.CreateGhostButton("ct-ZADBService");
btnSuggest.Location = new Point(490, 260);
btnSuggest.Size = new Size(68, 32);
btnSuggest.Font = new Font("Segoe UI", 7.5f, FontStyle.Bold);
btnSuggest.Click += (_, _) =>
{
_txtManual.Text = "ct-ZADBService";
AddManualContainer();
};
AddField(card, "Sonic-Benutzer (für Scan)", _txtUser, 18, 308, 250);
AddField(card, "Kennwort", _txtPassword, 288, 308, 270);
_btnScan = SettingsUi.CreatePrimaryButton("Von Sonic scannen");
_btnScan.Location = new Point(18, 375);
_btnScan.Size = new Size(200, 36);
_btnScan.Click += async (_, _) => await ScanAsync();
_lblStatus = new Label
{
Location = new Point(230, 380),
Size = new Size(330, 30),
ForeColor = SettingsUi.Muted
};
card.Controls.Add(manualLabel);
card.Controls.Add(_txtManual);
card.Controls.Add(btnAddManual);
card.Controls.Add(btnSuggest);
card.Controls.Add(_btnScan);
card.Controls.Add(_lblStatus);
_btnSave = SettingsUi.CreatePrimaryButton("Auswahl speichern");
_btnSave.Location = new Point(352, 555);
_btnSave.Size = new Size(260, 42);
_btnSave.Click += async (_, _) => await SaveAsync();
Button skip = SettingsUi.CreateGhostButton("Später");
skip.Location = new Point(230, 555);
skip.Size = new Size(110, 42);
skip.Click += (_, _) =>
{
DialogResult = DialogResult.Cancel;
Close();
};
Controls.Add(title);
Controls.Add(subtitle);
Controls.Add(card);
Controls.Add(skip);
Controls.Add(_btnSave);
Shown += async (_, _) => await InitializeAsync();
}
private async Task InitializeAsync()
{
try
{
IReadOnlyList<CompanyOption> companies =
await _coordinator.LoadCompaniesAsync();
_cmbCompany.Items.Clear();
foreach (CompanyOption company in companies)
{
_cmbCompany.Items.Add(company);
}
if (_cmbCompany.Items.Count > 0)
{
int deIndex = 0;
for (int index = 0; index < companies.Count; index++)
{
if (string.Equals(
companies[index].CompanyCode,
"DE",
StringComparison.OrdinalIgnoreCase))
{
deIndex = index;
break;
}
}
_cmbCompany.SelectedIndex = deIndex;
}
IReadOnlyList<SonicCredentialProfile> profiles =
await _coordinator.LoadCredentialsAsync(
_system.SonicConnectionId);
SonicCredentialProfile? profile =
profiles.FirstOrDefault(item => item.IsDefault)
?? profiles.FirstOrDefault();
if (profile is not null)
{
_txtUser.Text = profile.UserName;
_txtPassword.Text = profile.Secret;
_lblStatus.Text =
"Profil geladen — Scan möglich.";
_lblStatus.ForeColor = SettingsUi.Green;
}
else
{
_lblStatus.Text =
"Kein Profil — Benutzer/Kennwort für Scan eingeben oder manuell.";
_lblStatus.ForeColor = SettingsUi.Gold;
}
// Bereits vorhandene Container vorselektieren
IReadOnlyList<ContainerOption> existing =
await _coordinator.LoadContainersAsync(
_system.SonicConnectionId);
foreach (ContainerOption container in existing)
{
AddContainerName(container.ContainerName, check: true);
}
}
catch (Exception ex)
{
_lblStatus.Text = ex.Message;
_lblStatus.ForeColor = SettingsUi.Red;
}
}
private void AddManualContainer()
{
string name = _txtManual.Text.Trim();
if (name.Length == 0)
{
return;
}
AddContainerName(name, check: true);
_txtManual.Clear();
_txtManual.Focus();
}
private void AddContainerName(string name, bool check)
{
for (int index = 0; index < _lstContainers.Items.Count; index++)
{
if (string.Equals(
_lstContainers.Items[index]?.ToString(),
name,
StringComparison.OrdinalIgnoreCase))
{
_lstContainers.SetItemChecked(index, check);
return;
}
}
int added = _lstContainers.Items.Add(name);
_lstContainers.SetItemChecked(added, check);
}
private async Task ScanAsync()
{
if (_running)
{
return;
}
_running = true;
_btnScan.Enabled = false;
_btnSave.Enabled = false;
Cursor = Cursors.WaitCursor;
_lblStatus.Text = "Scanne Domain…";
_lblStatus.ForeColor = SettingsUi.Muted;
try
{
ContainerScanResult result =
await _scanner.ScanAsync(
_system,
_txtUser.Text,
_txtPassword.Text);
if (!result.Success)
{
_lblStatus.Text = result.Message;
_lblStatus.ForeColor = SettingsUi.Red;
return;
}
foreach (string container in result.Containers)
{
AddContainerName(container, check: true);
}
_lblStatus.Text =
result.Containers.Count == 0
? "Scan OK, aber keine Container gefunden — bitte manuell."
: $"{result.Containers.Count} Container gescannt und vorausgewählt.";
_lblStatus.ForeColor =
result.Containers.Count == 0
? SettingsUi.Gold
: SettingsUi.Green;
}
catch (Exception ex)
{
_lblStatus.Text = ex.Message;
_lblStatus.ForeColor = SettingsUi.Red;
}
finally
{
_running = false;
_btnScan.Enabled = true;
_btnSave.Enabled = true;
Cursor = Cursors.Default;
}
}
private async Task SaveAsync()
{
if (_running)
{
return;
}
if (_cmbCompany.SelectedItem is not CompanyOption company)
{
MessageBox.Show(
this,
"Bitte eine Company wählen.",
"Container",
MessageBoxButtons.OK,
MessageBoxIcon.Warning);
return;
}
List<string> selected = _lstContainers.CheckedItems
.Cast<object>()
.Select(item => item.ToString() ?? string.Empty)
.Where(name => name.Length > 0)
.Distinct(StringComparer.OrdinalIgnoreCase)
.ToList();
if (selected.Count == 0)
{
MessageBox.Show(
this,
"Bitte mindestens einen Container angehakt lassen "
+ "oder manuell hinzufügen.",
"Container",
MessageBoxButtons.OK,
MessageBoxIcon.Warning);
return;
}
_running = true;
_btnSave.Enabled = false;
Cursor = Cursors.WaitCursor;
try
{
IReadOnlyList<ContainerOption> existing =
await _coordinator.LoadContainersAsync(
_system.SonicConnectionId);
HashSet<string> existingNames = existing
.Select(item => item.ContainerName)
.ToHashSet(StringComparer.OrdinalIgnoreCase);
int created = 0;
foreach (string containerName in selected)
{
if (existingNames.Contains(containerName))
{
continue;
}
await _coordinator.AddSonicContainerAsync(
company.CompanyId,
_system.SonicConnectionId,
containerName,
containerDisplayName: null,
restartTimeoutSeconds: 180);
created++;
}
SavedCount = created;
MessageBox.Show(
this,
created == 0
? "Alle gewählten Container waren bereits vorhanden."
: $"{created} Container gespeichert und geprüft.",
"Prüfung OK",
MessageBoxButtons.OK,
MessageBoxIcon.Information);
DialogResult = DialogResult.OK;
Close();
}
catch (Exception ex)
{
MessageBox.Show(
this,
ex.Message,
"Container",
MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
finally
{
_running = false;
_btnSave.Enabled = true;
Cursor = Cursors.Default;
}
}
private static void AddField(
Control parent,
string label,
Control input,
int x,
int y,
int width,
int height = 30)
{
Label fieldLabel = SettingsUi.CreateFieldLabel(label);
fieldLabel.Location = new Point(x, y);
input.Location = new Point(x, y + 22);
input.Width = width;
input.Height = height;
parent.Controls.Add(fieldLabel);
parent.Controls.Add(input);
}
}