UI-Entwurf umgesetzt, Rocket.Chat-Tool, Deploymentcenter 2.4
Sicherungspunkt vor dem Aufraeumen. Buendelt die Arbeit, die seit dem Abschluss der Avalonia-Portierung im Arbeitsverzeichnis lag. Oberflaeche - Entwurf aus Mockup/ umgesetzt: Theme.axaml (Farben je Thema, Barlow als mitgelieferte Schrift), Icons.axaml (Symbolgeometrien), Shell.axaml (eigene ControlThemes statt Fluent umzufaerben). - Neue Steuerelemente StrokeIcon und BlueprintFrame, Seiten fuer Token-Verbrauch und Agenten-Chats, Werkzeug-Einstellungen als Seite statt eigenem Fenster, Texteditor-Fenster. - ThemeManager mit hellem und dunklem Thema; die beiden Pinsel-Konverter entfallen, weil ein fester Farbwert den Themenwechsel nicht ueberlebt. Rocket.Chat - Neues Tool-Projekt (Client, Konfiguration, Workspace-Dateien) nach der Bauform des Telegram-Tools: rocketchat_poll als Tool-Job, geweckt wird nur, wenn wirklich etwas anliegt. - send_file ist freigabepflichtig, send_message bewusst nicht: Der Raum ist Arbeitsraum, der Schutz sitzt an der Raum-Allowlist. - Konzept-Doc um die Messung gegen die echte Instanz 8.7 ergaenzt; drei Annahmen waren falsch und sind korrigiert. Deploymentcenter - DC6 (Update anwenden) und DC7 (Erstinstallation ueber setup.json) erledigt, DC3 fuer win-x64/dev; deploy/publish.py als Release-Strecke. - AppHost.DisposeAsync gegen doppeltes Herunterfahren gesperrt - sonst ueberschreibt eine zweite Abmeldung den Wartungszustand am Watchdog. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -26,6 +26,14 @@ public sealed record JobDisplayItemViewModel(
|
||||
string Status
|
||||
);
|
||||
|
||||
/// <summary>Die drei Ansichten der Aufgaben-Seite.</summary>
|
||||
public enum TasksTab
|
||||
{
|
||||
Jobs,
|
||||
Services,
|
||||
History
|
||||
}
|
||||
|
||||
public sealed record ServiceDisplayItemViewModel(
|
||||
string ServiceId,
|
||||
string Name,
|
||||
@@ -61,6 +69,22 @@ public sealed partial class TasksPageViewModel : PageViewModel
|
||||
[ObservableProperty]
|
||||
private bool _isRunningJob;
|
||||
|
||||
/// <summary>
|
||||
/// Der Entwurf ersetzt die Registerkarten durch eine Segmentleiste. Fachlich ist das
|
||||
/// dasselbe: eine von drei Ansichten. Die drei Kennzeichen darunter gibt es, weil
|
||||
/// eine Bindung „Ist dieser Wert gleich Services?" in AXAML sonst jedes Mal einen
|
||||
/// Konverter mit Parameter bräuchte.
|
||||
/// </summary>
|
||||
[ObservableProperty]
|
||||
[NotifyPropertyChangedFor(nameof(IsJobsTab))]
|
||||
[NotifyPropertyChangedFor(nameof(IsServicesTab))]
|
||||
[NotifyPropertyChangedFor(nameof(IsHistoryTab))]
|
||||
private TasksTab _selectedTab = TasksTab.Jobs;
|
||||
|
||||
public bool IsJobsTab => SelectedTab == TasksTab.Jobs;
|
||||
public bool IsServicesTab => SelectedTab == TasksTab.Services;
|
||||
public bool IsHistoryTab => SelectedTab == TasksTab.History;
|
||||
|
||||
public event Func<AddJobViewModel, Task<AddJobResultData?>>? RequestAddJobDialog;
|
||||
public event Func<AddServiceViewModel, Task<AddServiceResultData?>>? RequestAddServiceDialog;
|
||||
|
||||
@@ -429,6 +453,85 @@ public sealed partial class TasksPageViewModel : PageViewModel
|
||||
RefreshServiceList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Schaltet einen Job an oder ab, ohne ihn zu entfernen — im Entwurf die neue
|
||||
/// Schaltfläche „Aktivieren/Deaktivieren" in der Werkzeugleiste.
|
||||
///
|
||||
/// <para>Gilt nur für Tool-Jobs: <c>SchedulerConfig</c> hat keinen solchen Schalter,
|
||||
/// ein Agent-Wakeup existiert oder existiert nicht. Ihn hier zu ergänzen wäre keine
|
||||
/// Oberflächenarbeit — der Scanner müsste den Schalter erst einmal lesen, sonst liefe
|
||||
/// ein „deaktivierter" Wakeup munter weiter.</para>
|
||||
/// </summary>
|
||||
[RelayCommand]
|
||||
private void ToggleJobEnabled()
|
||||
{
|
||||
if (_host is null || SelectedJob is null) return;
|
||||
|
||||
var entry = SelectedJob;
|
||||
|
||||
if (entry.JobType != "Tool Job")
|
||||
{
|
||||
StatusText = "Nur Tool-Jobs lassen sich abschalten. "
|
||||
+ "Ein Agent-Wakeup wird über die Agenten-Seite entfernt.";
|
||||
return;
|
||||
}
|
||||
|
||||
var agent = _host.Instance.Agents.FirstOrDefault(a => a.AgentId == entry.AgentId);
|
||||
var job = agent?.ToolJobs.FirstOrDefault(j => j.JobId == entry.JobId);
|
||||
if (job is null) return;
|
||||
|
||||
job.Enabled = !job.Enabled;
|
||||
SaveInstanceConfig();
|
||||
RefreshJobList();
|
||||
|
||||
// Die Auswahl geht beim Neuaufbau der Liste verloren — sie wieder zu setzen
|
||||
// erspart es, für zwei Schaltvorgänge zweimal dieselbe Zeile anzuklicken.
|
||||
SelectedJob = JobEntries.FirstOrDefault(j => j.JobId == entry.JobId);
|
||||
|
||||
StatusText = job.Enabled
|
||||
? $"Job '{entry.TaskMessage}' aktiviert."
|
||||
: $"Job '{entry.TaskMessage}' deaktiviert.";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Aktiviert bzw. deaktiviert einen Dienst.
|
||||
///
|
||||
/// <para>Bewusst nicht „Start"/„Stop" genannt, auch wenn der Entwurf das so zeigt:
|
||||
/// Umgelegt wird das Kennzeichen <c>Enabled</c> in der Instanzkonfiguration. Ein
|
||||
/// laufender Dienstprozess wird davon nicht angehalten — eine Schaltfläche „Stop",
|
||||
/// nach der etwas weiterläuft, wäre schlimmer als gar keine.</para>
|
||||
/// </summary>
|
||||
[RelayCommand]
|
||||
private void ToggleServiceEnabled()
|
||||
{
|
||||
if (_host is null || SelectedService is null) return;
|
||||
|
||||
var id = SelectedService.ServiceId;
|
||||
var service = _host.Instance.Services.FirstOrDefault(s => s.ServiceId == id);
|
||||
if (service is null) return;
|
||||
|
||||
service.Enabled = !service.Enabled;
|
||||
SaveInstanceConfig();
|
||||
RefreshServiceList();
|
||||
|
||||
SelectedService = ServiceEntries.FirstOrDefault(s => s.ServiceId == id);
|
||||
|
||||
StatusText = service.Enabled
|
||||
? $"Dienst '{service.Name}' aktiviert."
|
||||
: $"Dienst '{service.Name}' deaktiviert.";
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private void SelectTab(string? tab)
|
||||
{
|
||||
SelectedTab = tab switch
|
||||
{
|
||||
"Services" => TasksTab.Services,
|
||||
"History" => TasksTab.History,
|
||||
_ => TasksTab.Jobs
|
||||
};
|
||||
}
|
||||
|
||||
private static string CalculateNextRun(string? cronExpr)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(cronExpr)) return "—";
|
||||
|
||||
Reference in New Issue
Block a user