Import des bestehenden Projektstands in Git. - .NET 10 WinForms Anwendung (Multi-Agent / Tool-System) - .gitignore fuer Build-Artefakte, Secrets und Runtime-Daten ergaenzt Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
259 lines
8.2 KiB
C#
259 lines
8.2 KiB
C#
using ClawdDotNet.Core.Config;
|
|
using ClawdDotNet.Core.Scheduling;
|
|
using ClawdDotNet.Core.Tools;
|
|
|
|
namespace ClawdDotNet;
|
|
|
|
public sealed partial class frm_AddJob : Form
|
|
{
|
|
private readonly IReadOnlyList<AgentConfig> _agents;
|
|
private readonly IReadOnlyList<(IAgentTool Tool, IToolJobProvider Provider)> _jobProviders;
|
|
|
|
// ─── Output Properties ───
|
|
|
|
public bool IsToolJob => cbJobType.SelectedIndex == 1;
|
|
public string SelectedAgentId => (cbAgent.SelectedItem as AgentComboItem)?.AgentId ?? "";
|
|
public string CronExpression => txtCron.Text.Trim();
|
|
public string TaskMessage => txtTask.Text.Trim();
|
|
public bool RunOnStart => chkRunOnStart.Checked;
|
|
public string SelectedToolName => (cbTool.SelectedItem as ToolComboItem)?.ToolName ?? "";
|
|
public string SelectedJobTypeId => (cbJobDef.SelectedItem as JobDefComboItem)?.JobTypeId ?? "";
|
|
|
|
/// <summary>Konstruktor für "Hinzufügen"</summary>
|
|
public frm_AddJob(IReadOnlyList<AgentConfig> agents, ToolRegistry toolRegistry)
|
|
{
|
|
InitializeComponent();
|
|
|
|
_agents = agents;
|
|
_jobProviders = toolRegistry.GetJobProviders();
|
|
|
|
foreach (var agent in agents)
|
|
cbAgent.Items.Add(new AgentComboItem(agent.AgentId, agent.DisplayName));
|
|
if (cbAgent.Items.Count > 0) cbAgent.SelectedIndex = 0;
|
|
|
|
foreach (var (tool, _) in _jobProviders)
|
|
cbTool.Items.Add(new ToolComboItem(tool.Name, tool.Description));
|
|
if (cbTool.Items.Count > 0) cbTool.SelectedIndex = 0;
|
|
|
|
cbJobType.SelectedIndex = 0;
|
|
}
|
|
|
|
/// <summary>Konstruktor für "Bearbeiten" — Agent, Tool und Job-Typ sind gesperrt</summary>
|
|
public frm_AddJob(IReadOnlyList<AgentConfig> agents, ToolRegistry toolRegistry,
|
|
string agentId, string cron, string taskMessage, bool runOnStart,
|
|
bool isToolJob, string? toolName = null, string? jobTypeId = null)
|
|
: this(agents, toolRegistry)
|
|
{
|
|
Text = "Job bearbeiten";
|
|
btnOk.Text = "Speichern";
|
|
|
|
// Job-Typ setzen und sperren
|
|
cbJobType.SelectedIndex = isToolJob ? 1 : 0;
|
|
cbJobType.Enabled = false;
|
|
|
|
// Agent vorauswählen und sperren
|
|
for (int i = 0; i < cbAgent.Items.Count; i++)
|
|
{
|
|
if (((AgentComboItem)cbAgent.Items[i]!).AgentId == agentId)
|
|
{
|
|
cbAgent.SelectedIndex = i;
|
|
break;
|
|
}
|
|
}
|
|
cbAgent.Enabled = false;
|
|
|
|
// Bearbeitbare Felder befüllen
|
|
txtCron.Text = cron;
|
|
chkRunOnStart.Checked = runOnStart;
|
|
|
|
if (isToolJob && toolName is not null)
|
|
{
|
|
// Tool vorauswählen und sperren
|
|
for (int i = 0; i < cbTool.Items.Count; i++)
|
|
{
|
|
if (((ToolComboItem)cbTool.Items[i]!).ToolName == toolName)
|
|
{
|
|
cbTool.SelectedIndex = i;
|
|
break;
|
|
}
|
|
}
|
|
cbTool.Enabled = false;
|
|
|
|
// Job-Definition vorauswählen und sperren
|
|
if (jobTypeId is not null)
|
|
{
|
|
for (int i = 0; i < cbJobDef.Items.Count; i++)
|
|
{
|
|
if (((JobDefComboItem)cbJobDef.Items[i]!).JobTypeId == jobTypeId)
|
|
{
|
|
cbJobDef.SelectedIndex = i;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
cbJobDef.Enabled = false;
|
|
}
|
|
else
|
|
{
|
|
txtTask.Text = taskMessage;
|
|
}
|
|
}
|
|
|
|
private void OnJobTypeChanged(object? sender, EventArgs e)
|
|
{
|
|
var isToolJob = cbJobType.SelectedIndex == 1;
|
|
|
|
lblTool.Visible = isToolJob;
|
|
cbTool.Visible = isToolJob;
|
|
lblJobDef.Visible = isToolJob;
|
|
cbJobDef.Visible = isToolJob;
|
|
|
|
lblTask.Visible = !isToolJob;
|
|
txtTask.Visible = !isToolJob;
|
|
|
|
RefreshAgentList();
|
|
}
|
|
|
|
private void OnToolChanged(object? sender, EventArgs e)
|
|
{
|
|
cbJobDef.Items.Clear();
|
|
|
|
if (cbTool.SelectedItem is not ToolComboItem toolItem)
|
|
return;
|
|
|
|
var provider = _jobProviders.FirstOrDefault(p => ((IAgentTool)p.Provider).Name == toolItem.ToolName);
|
|
if (provider.Provider is null)
|
|
return;
|
|
|
|
foreach (var def in provider.Provider.GetJobDefinitions())
|
|
cbJobDef.Items.Add(new JobDefComboItem(def.JobTypeId, def.DisplayName, def.Description));
|
|
|
|
if (cbJobDef.Items.Count > 0) cbJobDef.SelectedIndex = 0;
|
|
|
|
RefreshAgentList();
|
|
}
|
|
|
|
private void RefreshAgentList()
|
|
{
|
|
var previousAgentId = (cbAgent.SelectedItem as AgentComboItem)?.AgentId;
|
|
cbAgent.Items.Clear();
|
|
|
|
var toolName = IsToolJob && cbTool.SelectedItem is ToolComboItem toolItem
|
|
? toolItem.ToolName : null;
|
|
|
|
foreach (var agent in _agents)
|
|
{
|
|
if (toolName is not null && !agent.Tools.ContainsKey(toolName))
|
|
continue;
|
|
|
|
cbAgent.Items.Add(new AgentComboItem(agent.AgentId, agent.DisplayName));
|
|
}
|
|
|
|
if (previousAgentId is not null)
|
|
{
|
|
for (int i = 0; i < cbAgent.Items.Count; i++)
|
|
{
|
|
if (((AgentComboItem)cbAgent.Items[i]!).AgentId == previousAgentId)
|
|
{
|
|
cbAgent.SelectedIndex = i;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (cbAgent.SelectedIndex < 0 && cbAgent.Items.Count > 0)
|
|
cbAgent.SelectedIndex = 0;
|
|
}
|
|
|
|
private void OnCronChanged(object? sender, EventArgs e)
|
|
{
|
|
var text = txtCron.Text.Trim();
|
|
if (string.IsNullOrWhiteSpace(text))
|
|
{
|
|
lblPreview.Text = "";
|
|
return;
|
|
}
|
|
|
|
try
|
|
{
|
|
var cron = Core.Scheduling.CronExpression.Parse(text);
|
|
var next = cron.GetNextOccurrence(DateTime.Now);
|
|
lblPreview.Text = next is not null
|
|
? $"Nächste Ausführung: {next:dd.MM.yyyy HH:mm}"
|
|
: "Kein nächster Zeitpunkt";
|
|
lblPreview.ForeColor = Color.Green;
|
|
}
|
|
catch
|
|
{
|
|
lblPreview.Text = "Ungültiger Cron-Ausdruck";
|
|
lblPreview.ForeColor = Color.Red;
|
|
}
|
|
}
|
|
|
|
private void OnOkClick(object? sender, EventArgs e)
|
|
{
|
|
if (cbAgent.SelectedItem is null)
|
|
{
|
|
MessageBox.Show("Bitte einen Agenten auswählen.", "Validierung",
|
|
MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
|
DialogResult = DialogResult.None;
|
|
return;
|
|
}
|
|
|
|
if (string.IsNullOrWhiteSpace(txtCron.Text))
|
|
{
|
|
MessageBox.Show("Bitte einen Cron-Ausdruck eingeben.", "Validierung",
|
|
MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
|
DialogResult = DialogResult.None;
|
|
return;
|
|
}
|
|
|
|
try
|
|
{
|
|
Core.Scheduling.CronExpression.Parse(txtCron.Text.Trim());
|
|
}
|
|
catch
|
|
{
|
|
MessageBox.Show("Ungültiger Cron-Ausdruck.", "Validierung",
|
|
MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
|
DialogResult = DialogResult.None;
|
|
return;
|
|
}
|
|
|
|
if (IsToolJob)
|
|
{
|
|
if (cbTool.SelectedItem is null)
|
|
{
|
|
MessageBox.Show("Bitte ein Tool auswählen.", "Validierung",
|
|
MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
|
DialogResult = DialogResult.None;
|
|
return;
|
|
}
|
|
|
|
if (cbJobDef.SelectedItem is null)
|
|
{
|
|
MessageBox.Show("Bitte einen Job-Typ auswählen.", "Validierung",
|
|
MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
|
DialogResult = DialogResult.None;
|
|
}
|
|
}
|
|
}
|
|
|
|
// ─── ComboBox Items ───
|
|
|
|
private sealed record AgentComboItem(string AgentId, string DisplayName)
|
|
{
|
|
public override string ToString() => DisplayName;
|
|
}
|
|
|
|
private sealed record ToolComboItem(string ToolName, string Description)
|
|
{
|
|
public override string ToString() => ToolName;
|
|
}
|
|
|
|
private sealed record JobDefComboItem(string JobTypeId, string DisplayName, string Description)
|
|
{
|
|
public override string ToString() => $"{DisplayName} ({JobTypeId})";
|
|
}
|
|
}
|