feat(ui): complete Avalonia UI port with 7 main pages, tool settings & top MenuBar
This commit is contained in:
@@ -0,0 +1,89 @@
|
||||
using System.Text.Json;
|
||||
|
||||
namespace ClawdDotNet.Core.Deploymentcenter;
|
||||
|
||||
/// <summary>Was aus einem Bugtracker-Eintrag geworden ist.</summary>
|
||||
/// <param name="ItemId">Nummer des Eintrags im Deploymentcenter.</param>
|
||||
/// <param name="IsNew">False, wenn ein bestehender Eintrag hochgezählt wurde.</param>
|
||||
/// <param name="OccurrenceCount">Wie oft dieses Vorkommnis bisher gezählt wurde.</param>
|
||||
/// <param name="Url">Adresse der Übersicht, für einen Hinweis an den Benutzer.</param>
|
||||
public sealed record BugtrackerReport(long ItemId, bool IsNew, int OccurrenceCount, string? Url);
|
||||
|
||||
/// <summary>Art eines Eintrags. Der Server kennt darüber hinaus noch <c>idea</c>.</summary>
|
||||
public static class BugtrackerItemType
|
||||
{
|
||||
public const string Bug = "bug";
|
||||
public const string Feature = "feature";
|
||||
public const string Idea = "idea";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Anbindung an <c>POST /api/bugtracker/v1/report</c> — der Weg, auf dem ClawdDotNet
|
||||
/// selbst (oder ein Benutzer über die Oberfläche) einen Fehler oder Wunsch einträgt.
|
||||
///
|
||||
/// <para>Abgegrenzt vom <see cref="ErrorReporter"/>: Der meldet <em>ungefangene</em>
|
||||
/// Ausnahmen automatisch; hier geht es um bewusst formulierte Einträge mit Titel und
|
||||
/// Beschreibung. Serverseitig landen beide in derselben Tabelle — was richtig ist,
|
||||
/// denn ein zweiter Speicher wäre nur ein zweiter Ort, an dem man suchen müsste.</para>
|
||||
///
|
||||
/// <para><b>Der Absender kommt aus dem Token</b> und lässt sich nicht frei wählen —
|
||||
/// sonst könnte sich ein Agent als ein anderer ausgeben.</para>
|
||||
/// </summary>
|
||||
public sealed class BugtrackerClient(
|
||||
DeploymentcenterApi api, string projectSlug, string environment, string build)
|
||||
{
|
||||
/// <param name="type">Siehe <see cref="BugtrackerItemType"/>.</param>
|
||||
/// <param name="clientRef">
|
||||
/// Freier Idempotenz-Schlüssel. Zweimal derselbe Wert erzeugt keinen zweiten
|
||||
/// Eintrag — nützlich, wenn eine Meldung nach einem Verbindungsabbruch wiederholt
|
||||
/// wird.
|
||||
/// </param>
|
||||
public async Task<BugtrackerReport> ReportAsync(
|
||||
string type,
|
||||
string title,
|
||||
string? description = null,
|
||||
string severity = "medium",
|
||||
string? clientRef = null,
|
||||
IReadOnlyDictionary<string, object?>? context = null,
|
||||
CancellationToken ct = default)
|
||||
{
|
||||
var payload = new Dictionary<string, object?>
|
||||
{
|
||||
["project_slug"] = projectSlug,
|
||||
["type"] = type,
|
||||
["title"] = title,
|
||||
["description"] = description,
|
||||
["severity"] = severity,
|
||||
["environment"] = environment,
|
||||
["build_version"] = build
|
||||
};
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(clientRef))
|
||||
payload["client_ref"] = clientRef;
|
||||
|
||||
if (context is { Count: > 0 })
|
||||
payload["context"] = context;
|
||||
|
||||
var response = await api.PostAsync("/api/bugtracker/v1/report", payload, ct)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return new BugtrackerReport(
|
||||
ReadLong(response, "item_id"),
|
||||
ReadBool(response, "is_new"),
|
||||
(int)ReadLong(response, "occurrence_count"),
|
||||
ReadString(response, "url"));
|
||||
}
|
||||
|
||||
private static long ReadLong(JsonElement root, string name) =>
|
||||
root.TryGetProperty(name, out var v) && v.ValueKind == JsonValueKind.Number
|
||||
? v.GetInt64()
|
||||
: 0;
|
||||
|
||||
private static bool ReadBool(JsonElement root, string name) =>
|
||||
root.TryGetProperty(name, out var v) && v.ValueKind == JsonValueKind.True;
|
||||
|
||||
private static string? ReadString(JsonElement root, string name) =>
|
||||
root.TryGetProperty(name, out var v) && v.ValueKind == JsonValueKind.String
|
||||
? v.GetString()
|
||||
: null;
|
||||
}
|
||||
Reference in New Issue
Block a user