Phase 5-UI: Polymarket-Accounts-Tab (allgemeine Account-Verwaltung)
- tabPage2: DataGridView (Name/Wallet/Demo/Aktiv) + Toolstrip (Neuer Account/ Loeschen) + PropertyGrid. Da AccountState jetzt general-only ist, zeigt das PropertyGrid automatisch nur die allgemeinen Felder (Wallet, API-Keys, Payouts). - SettingsView.cs: Accounts laden, Auswahl -> PropertyGrid, Bearbeiten -> speichern (IAccountRepository + TradingState), Neu/Loeschen. - Program.cs: Settings-View bekommt IAccountRepository + TradingState injiziert. - Copytrading-Detail-Limits folgen im Modul-Account-View. - Build 0 Fehler. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
095c4b64aa
commit
87dd9a750d
+3
-1
@@ -157,7 +157,9 @@ internal static class Program
|
|||||||
view.Initialize(
|
view.Initialize(
|
||||||
viewServices.GetRequiredService<ThreemaService>(),
|
viewServices.GetRequiredService<ThreemaService>(),
|
||||||
viewServices.GetRequiredService<MullvadVpnService>(),
|
viewServices.GetRequiredService<MullvadVpnService>(),
|
||||||
viewServices.GetRequiredService<TerminalLogger>());
|
viewServices.GetRequiredService<TerminalLogger>(),
|
||||||
|
viewServices.GetRequiredService<PolyTrader.Core.Persistence.IAccountRepository>(),
|
||||||
|
viewServices.GetRequiredService<TradingState>());
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
Generated
+109
@@ -26,9 +26,21 @@ namespace PolyTraderSharp.Ui.Views
|
|||||||
toolStrip2 = new ToolStrip();
|
toolStrip2 = new ToolStrip();
|
||||||
btn_save = new ToolStripButton();
|
btn_save = new ToolStripButton();
|
||||||
btn_loadsettings = new ToolStripButton();
|
btn_loadsettings = new ToolStripButton();
|
||||||
|
toolStripAccounts = new ToolStrip();
|
||||||
|
btnAccNew = new ToolStripButton();
|
||||||
|
btnAccDelete = new ToolStripButton();
|
||||||
|
dgvAccounts = new DataGridView();
|
||||||
|
colAccName = new DataGridViewTextBoxColumn();
|
||||||
|
colAccWallet = new DataGridViewTextBoxColumn();
|
||||||
|
colAccDemo = new DataGridViewCheckBoxColumn();
|
||||||
|
colAccActive = new DataGridViewCheckBoxColumn();
|
||||||
|
pgAccount = new PropertyGrid();
|
||||||
tabControl1.SuspendLayout();
|
tabControl1.SuspendLayout();
|
||||||
tabPage1.SuspendLayout();
|
tabPage1.SuspendLayout();
|
||||||
|
tabPage2.SuspendLayout();
|
||||||
toolStrip2.SuspendLayout();
|
toolStrip2.SuspendLayout();
|
||||||
|
toolStripAccounts.SuspendLayout();
|
||||||
|
((System.ComponentModel.ISupportInitialize)dgvAccounts).BeginInit();
|
||||||
SuspendLayout();
|
SuspendLayout();
|
||||||
//
|
//
|
||||||
// propertyGrid
|
// propertyGrid
|
||||||
@@ -74,6 +86,9 @@ namespace PolyTraderSharp.Ui.Views
|
|||||||
//
|
//
|
||||||
// tabPage2
|
// tabPage2
|
||||||
//
|
//
|
||||||
|
tabPage2.Controls.Add(pgAccount);
|
||||||
|
tabPage2.Controls.Add(dgvAccounts);
|
||||||
|
tabPage2.Controls.Add(toolStripAccounts);
|
||||||
tabPage2.Location = new Point(4, 34);
|
tabPage2.Location = new Point(4, 34);
|
||||||
tabPage2.Name = "tabPage2";
|
tabPage2.Name = "tabPage2";
|
||||||
tabPage2.Padding = new Padding(3);
|
tabPage2.Padding = new Padding(3);
|
||||||
@@ -108,6 +123,86 @@ namespace PolyTraderSharp.Ui.Views
|
|||||||
btn_loadsettings.Size = new Size(223, 29);
|
btn_loadsettings.Size = new Size(223, 29);
|
||||||
btn_loadsettings.Text = "Load Settings from File";
|
btn_loadsettings.Text = "Load Settings from File";
|
||||||
//
|
//
|
||||||
|
// toolStripAccounts
|
||||||
|
//
|
||||||
|
toolStripAccounts.ImageScalingSize = new Size(24, 24);
|
||||||
|
toolStripAccounts.Items.AddRange(new ToolStripItem[] { btnAccNew, btnAccDelete });
|
||||||
|
toolStripAccounts.Location = new Point(3, 3);
|
||||||
|
toolStripAccounts.Name = "toolStripAccounts";
|
||||||
|
toolStripAccounts.Size = new Size(1171, 34);
|
||||||
|
toolStripAccounts.TabIndex = 0;
|
||||||
|
//
|
||||||
|
// btnAccNew
|
||||||
|
//
|
||||||
|
btnAccNew.DisplayStyle = ToolStripItemDisplayStyle.Text;
|
||||||
|
btnAccNew.Name = "btnAccNew";
|
||||||
|
btnAccNew.Size = new Size(130, 29);
|
||||||
|
btnAccNew.Text = "Neuer Account";
|
||||||
|
//
|
||||||
|
// btnAccDelete
|
||||||
|
//
|
||||||
|
btnAccDelete.DisplayStyle = ToolStripItemDisplayStyle.Text;
|
||||||
|
btnAccDelete.Name = "btnAccDelete";
|
||||||
|
btnAccDelete.Size = new Size(90, 29);
|
||||||
|
btnAccDelete.Text = "Löschen";
|
||||||
|
//
|
||||||
|
// dgvAccounts
|
||||||
|
//
|
||||||
|
dgvAccounts.AllowUserToAddRows = false;
|
||||||
|
dgvAccounts.AllowUserToDeleteRows = false;
|
||||||
|
dgvAccounts.AutoGenerateColumns = false;
|
||||||
|
dgvAccounts.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
|
||||||
|
dgvAccounts.Columns.AddRange(new DataGridViewColumn[] { colAccName, colAccWallet, colAccDemo, colAccActive });
|
||||||
|
dgvAccounts.Dock = DockStyle.Left;
|
||||||
|
dgvAccounts.Location = new Point(3, 37);
|
||||||
|
dgvAccounts.MultiSelect = false;
|
||||||
|
dgvAccounts.Name = "dgvAccounts";
|
||||||
|
dgvAccounts.ReadOnly = true;
|
||||||
|
dgvAccounts.RowHeadersVisible = false;
|
||||||
|
dgvAccounts.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
|
||||||
|
dgvAccounts.Size = new Size(620, 847);
|
||||||
|
dgvAccounts.TabIndex = 1;
|
||||||
|
//
|
||||||
|
// colAccName
|
||||||
|
//
|
||||||
|
colAccName.DataPropertyName = "Name";
|
||||||
|
colAccName.HeaderText = "Name";
|
||||||
|
colAccName.Name = "colAccName";
|
||||||
|
colAccName.ReadOnly = true;
|
||||||
|
colAccName.Width = 200;
|
||||||
|
//
|
||||||
|
// colAccWallet
|
||||||
|
//
|
||||||
|
colAccWallet.DataPropertyName = "WalletAddress";
|
||||||
|
colAccWallet.HeaderText = "Wallet";
|
||||||
|
colAccWallet.Name = "colAccWallet";
|
||||||
|
colAccWallet.ReadOnly = true;
|
||||||
|
colAccWallet.Width = 260;
|
||||||
|
//
|
||||||
|
// colAccDemo
|
||||||
|
//
|
||||||
|
colAccDemo.DataPropertyName = "IsDemo";
|
||||||
|
colAccDemo.HeaderText = "Demo";
|
||||||
|
colAccDemo.Name = "colAccDemo";
|
||||||
|
colAccDemo.ReadOnly = true;
|
||||||
|
colAccDemo.Width = 60;
|
||||||
|
//
|
||||||
|
// colAccActive
|
||||||
|
//
|
||||||
|
colAccActive.DataPropertyName = "IsActive";
|
||||||
|
colAccActive.HeaderText = "Aktiv";
|
||||||
|
colAccActive.Name = "colAccActive";
|
||||||
|
colAccActive.ReadOnly = true;
|
||||||
|
colAccActive.Width = 60;
|
||||||
|
//
|
||||||
|
// pgAccount
|
||||||
|
//
|
||||||
|
pgAccount.Dock = DockStyle.Fill;
|
||||||
|
pgAccount.Location = new Point(623, 37);
|
||||||
|
pgAccount.Name = "pgAccount";
|
||||||
|
pgAccount.Size = new Size(551, 847);
|
||||||
|
pgAccount.TabIndex = 2;
|
||||||
|
//
|
||||||
// SettingsView
|
// SettingsView
|
||||||
//
|
//
|
||||||
AutoScaleDimensions = new SizeF(10F, 25F);
|
AutoScaleDimensions = new SizeF(10F, 25F);
|
||||||
@@ -121,8 +216,13 @@ namespace PolyTraderSharp.Ui.Views
|
|||||||
tabControl1.ResumeLayout(false);
|
tabControl1.ResumeLayout(false);
|
||||||
tabPage1.ResumeLayout(false);
|
tabPage1.ResumeLayout(false);
|
||||||
tabPage1.PerformLayout();
|
tabPage1.PerformLayout();
|
||||||
|
tabPage2.ResumeLayout(false);
|
||||||
|
tabPage2.PerformLayout();
|
||||||
toolStrip2.ResumeLayout(false);
|
toolStrip2.ResumeLayout(false);
|
||||||
toolStrip2.PerformLayout();
|
toolStrip2.PerformLayout();
|
||||||
|
toolStripAccounts.ResumeLayout(false);
|
||||||
|
toolStripAccounts.PerformLayout();
|
||||||
|
((System.ComponentModel.ISupportInitialize)dgvAccounts).EndInit();
|
||||||
ResumeLayout(false);
|
ResumeLayout(false);
|
||||||
PerformLayout();
|
PerformLayout();
|
||||||
}
|
}
|
||||||
@@ -137,5 +237,14 @@ namespace PolyTraderSharp.Ui.Views
|
|||||||
private TabPage tabPage2;
|
private TabPage tabPage2;
|
||||||
private ToolStripButton btn_save;
|
private ToolStripButton btn_save;
|
||||||
private ToolStripButton btn_loadsettings;
|
private ToolStripButton btn_loadsettings;
|
||||||
|
private ToolStrip toolStripAccounts;
|
||||||
|
private ToolStripButton btnAccNew;
|
||||||
|
private ToolStripButton btnAccDelete;
|
||||||
|
private DataGridView dgvAccounts;
|
||||||
|
private DataGridViewTextBoxColumn colAccName;
|
||||||
|
private DataGridViewTextBoxColumn colAccWallet;
|
||||||
|
private DataGridViewCheckBoxColumn colAccDemo;
|
||||||
|
private DataGridViewCheckBoxColumn colAccActive;
|
||||||
|
private PropertyGrid pgAccount;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,18 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Linq;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
|
using PolyTrader.Core.Persistence;
|
||||||
using PolyTraderSharp.Models;
|
using PolyTraderSharp.Models;
|
||||||
using PolyTraderSharp.Services;
|
using PolyTraderSharp.Services;
|
||||||
|
|
||||||
namespace PolyTraderSharp.Ui.Views
|
namespace PolyTraderSharp.Ui.Views
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Core-Settings-Ansicht: bearbeitet die ServerSettings über ein PropertyGrid.
|
/// Core-Settings-Fenster: allgemeine Server-Einstellungen (PropertyGrid) und die
|
||||||
/// Designbar (siehe SettingsView.Designer.cs); Laufzeit-Abhängigkeiten via Initialize.
|
/// allgemeine Verwaltung der Polymarket-Accounts (Wallets, API-Keys …).
|
||||||
/// Verhalten entspricht dem bisherigen Settings-Tab (Speichern -> XML + Services neu laden).
|
/// Die copytrading-spezifischen Detail-Limits werden NICHT hier, sondern im
|
||||||
|
/// Copytrading-Modul-View bearbeitet (AccountState ist bewusst general-only).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public partial class SettingsView : Form
|
public partial class SettingsView : Form
|
||||||
{
|
{
|
||||||
@@ -19,21 +23,44 @@ namespace PolyTraderSharp.Ui.Views
|
|||||||
private MullvadVpnService? _vpn;
|
private MullvadVpnService? _vpn;
|
||||||
private TerminalLogger? _logger;
|
private TerminalLogger? _logger;
|
||||||
|
|
||||||
|
private IAccountRepository? _accountRepo;
|
||||||
|
private TradingState? _state;
|
||||||
|
private BindingList<AccountState> _accounts = new();
|
||||||
|
|
||||||
public SettingsView()
|
public SettingsView()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
|
||||||
btn_save.Click += (_, _) => Save();
|
btn_save.Click += (_, _) => Save();
|
||||||
btn_loadsettings.Click += (_, _) => Reload();
|
btn_loadsettings.Click += (_, _) => Reload();
|
||||||
|
|
||||||
|
btnAccNew.Click += (_, _) => AddAccount();
|
||||||
|
btnAccDelete.Click += (_, _) => DeleteAccount();
|
||||||
|
dgvAccounts.SelectionChanged += (_, _) =>
|
||||||
|
{
|
||||||
|
pgAccount.SelectedObject = dgvAccounts.CurrentRow?.DataBoundItem as AccountState;
|
||||||
|
};
|
||||||
|
pgAccount.PropertyValueChanged += (_, _) =>
|
||||||
|
{
|
||||||
|
if (pgAccount.SelectedObject is AccountState acc) SaveAccount(acc);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Initialize(ThreemaService threema, MullvadVpnService vpn, TerminalLogger logger)
|
public void Initialize(ThreemaService threema, MullvadVpnService vpn, TerminalLogger logger,
|
||||||
|
IAccountRepository accountRepo, TradingState state)
|
||||||
{
|
{
|
||||||
_threema = threema;
|
_threema = threema;
|
||||||
_vpn = vpn;
|
_vpn = vpn;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
|
_accountRepo = accountRepo;
|
||||||
|
_state = state;
|
||||||
|
|
||||||
Reload();
|
Reload();
|
||||||
|
LoadAccounts();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ===== Server-Settings =====
|
||||||
|
|
||||||
private void Reload()
|
private void Reload()
|
||||||
{
|
{
|
||||||
_settings = ServerSettings.Load(SettingsPath);
|
_settings = ServerSettings.Load(SettingsPath);
|
||||||
@@ -57,5 +84,50 @@ namespace PolyTraderSharp.Ui.Views
|
|||||||
MessageBoxButtons.OK, MessageBoxIcon.Error);
|
MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ===== Polymarket Accounts (allgemeine Einstellungen) =====
|
||||||
|
|
||||||
|
private void LoadAccounts()
|
||||||
|
{
|
||||||
|
if (_state == null) return;
|
||||||
|
_accounts = new BindingList<AccountState>(_state.Accounts.Values.OrderBy(a => a.AccountId).ToList());
|
||||||
|
dgvAccounts.DataSource = _accounts;
|
||||||
|
pgAccount.SelectedObject = dgvAccounts.CurrentRow?.DataBoundItem as AccountState;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AddAccount()
|
||||||
|
{
|
||||||
|
if (_state == null || _accountRepo == null) return;
|
||||||
|
|
||||||
|
int newId = _state.Accounts.Count > 0 ? _state.Accounts.Keys.Max() + 1 : 1;
|
||||||
|
var acc = new AccountState { AccountId = newId, Name = "Neuer Account" };
|
||||||
|
|
||||||
|
_state.Accounts[acc.AccountId] = acc;
|
||||||
|
_accountRepo.Upsert(acc);
|
||||||
|
|
||||||
|
_accounts.Add(acc);
|
||||||
|
dgvAccounts.CurrentCell = dgvAccounts.Rows[dgvAccounts.Rows.Count - 1].Cells[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DeleteAccount()
|
||||||
|
{
|
||||||
|
if (_state == null || _accountRepo == null) return;
|
||||||
|
if (dgvAccounts.CurrentRow?.DataBoundItem is not AccountState acc) return;
|
||||||
|
|
||||||
|
if (MessageBox.Show($"Account '{acc.Name}' (ID {acc.AccountId}) wirklich löschen?",
|
||||||
|
"Löschen bestätigen", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) != DialogResult.Yes)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_state.Accounts.TryRemove(acc.AccountId, out _);
|
||||||
|
_accountRepo.Delete(acc.AccountId);
|
||||||
|
_accounts.Remove(acc);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SaveAccount(AccountState acc)
|
||||||
|
{
|
||||||
|
_accountRepo?.Upsert(acc);
|
||||||
|
_state?.Accounts.AddOrUpdate(acc.AccountId, acc, (_, _) => acc);
|
||||||
|
dgvAccounts.Refresh();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user