feat: detached-runs monitor page (T3 parity)
Some checks failed
Security / Security check (push) Failing after 1s
Some checks failed
Security / Security check (push) Failing after 1s
New Runs sidebar destination listing detached invocations (detach:true) with phase, current step, project and a Cancel button while pending/running. Workspace-scoped like Audit/Approvals, polls every 2s. Detached runs are opt-in (detached.enabled) — the empty state explains how to enable them. Inline help doc DE+EN. DetachedRun model + listDetachedRuns/cancelDetachedRun in HubService, backed by the SDK's listInvocations()/cancelInvocation(). flutter analyze clean; 29 tests green (sidebar Y-stability updated for the new destination, model mapping unit-tested). Screenshot verification (light+dark) deferred — shared desktop in use. Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
This commit is contained in:
parent
984c91f91d
commit
54ccd3936a
13 changed files with 764 additions and 2 deletions
|
|
@ -1667,5 +1667,22 @@
|
|||
"federationEnrollmentHint": "Übergib das Token dem Satelliten-Betreiber über einen sicheren Kanal. Die mitgelieferte CA authentifiziert den ersten Connect des Satelliten.",
|
||||
"workspaceAll": "Alle Projekte",
|
||||
"workspaceSwitcherTooltip": "Arbeitsbereich — filtert diese Ansicht und stempelt neue Läufe mit dem gewählten Projekt",
|
||||
"workspaceProtectedHint": "Geschützt: logisch getrennt im gemeinsamen Hub — keine harte Prozessgrenze. Kritische Mandate nutzen einen abgeschotteten Bereich."
|
||||
"workspaceProtectedHint": "Geschützt: logisch getrennt im gemeinsamen Hub — keine harte Prozessgrenze. Kritische Mandate nutzen einen abgeschotteten Bereich.",
|
||||
"runsTitle": "Läufe",
|
||||
"runsReloadTooltip": "Lauf-Liste neu laden",
|
||||
"runsEmptyTitle": "Keine abgekoppelten Läufe",
|
||||
"runsEmptyHint": "Mit detach gestartete Läufe stehen hier, bis sie fertig sind. Abgekoppelte Aufrufe sind optional — dazu detached.enabled in der Betreiber-Konfiguration aktivieren.",
|
||||
"runsCancelButton": "Abbrechen",
|
||||
"runsCancelSignalled": "Abbruch für {flow} ausgelöst.",
|
||||
"@runsCancelSignalled": {"placeholders": {"flow": {"type": "String"}}},
|
||||
"runsCancelTooLate": "Der Lauf war schon fertig — nichts abzubrechen.",
|
||||
"runsCurrentStep": "Schritt: {step}",
|
||||
"@runsCurrentStep": {"placeholders": {"step": {"type": "String"}}},
|
||||
"runsPhasePending": "Wartet",
|
||||
"runsPhaseRunning": "Läuft",
|
||||
"runsPhaseSucceeded": "Erfolgreich",
|
||||
"runsPhaseFailed": "Fehlgeschlagen",
|
||||
"runsPhaseCancelled": "Abgebrochen",
|
||||
"runsPhaseUnknown": "Unbekannt",
|
||||
"navRuns": "Läufe"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1706,5 +1706,22 @@
|
|||
"federationEnrollmentHint": "Hand the token to the satellite operator over a secure channel. The bundled CA authenticates the satellite's first connect.",
|
||||
"workspaceAll": "All projects",
|
||||
"workspaceSwitcherTooltip": "Workspace — filters this view and stamps new runs with the selected project",
|
||||
"workspaceProtectedHint": "Protected: logically separated in the shared hub — no hard process barrier. Critical engagements use a sealed area."
|
||||
"workspaceProtectedHint": "Protected: logically separated in the shared hub — no hard process barrier. Critical engagements use a sealed area.",
|
||||
"runsTitle": "Runs",
|
||||
"runsReloadTooltip": "Reload the runs list",
|
||||
"runsEmptyTitle": "No detached runs",
|
||||
"runsEmptyHint": "Runs submitted with detach stay here until they finish. Detached invocations are opt-in — enable detached.enabled in the operator config to use them.",
|
||||
"runsCancelButton": "Cancel",
|
||||
"runsCancelSignalled": "Cancel signalled for {flow}.",
|
||||
"@runsCancelSignalled": {"placeholders": {"flow": {"type": "String"}}},
|
||||
"runsCancelTooLate": "The run had already finished — nothing to cancel.",
|
||||
"runsCurrentStep": "Step: {step}",
|
||||
"@runsCurrentStep": {"placeholders": {"step": {"type": "String"}}},
|
||||
"runsPhasePending": "Pending",
|
||||
"runsPhaseRunning": "Running",
|
||||
"runsPhaseSucceeded": "Succeeded",
|
||||
"runsPhaseFailed": "Failed",
|
||||
"runsPhaseCancelled": "Cancelled",
|
||||
"runsPhaseUnknown": "Unknown",
|
||||
"navRuns": "Runs"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4908,6 +4908,96 @@ abstract class AppLocalizations {
|
|||
/// In en, this message translates to:
|
||||
/// **'Protected: logically separated in the shared hub — no hard process barrier. Critical engagements use a sealed area.'**
|
||||
String get workspaceProtectedHint;
|
||||
|
||||
/// No description provided for @runsTitle.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Runs'**
|
||||
String get runsTitle;
|
||||
|
||||
/// No description provided for @runsReloadTooltip.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Reload the runs list'**
|
||||
String get runsReloadTooltip;
|
||||
|
||||
/// No description provided for @runsEmptyTitle.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'No detached runs'**
|
||||
String get runsEmptyTitle;
|
||||
|
||||
/// No description provided for @runsEmptyHint.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Runs submitted with detach stay here until they finish. Detached invocations are opt-in — enable detached.enabled in the operator config to use them.'**
|
||||
String get runsEmptyHint;
|
||||
|
||||
/// No description provided for @runsCancelButton.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Cancel'**
|
||||
String get runsCancelButton;
|
||||
|
||||
/// No description provided for @runsCancelSignalled.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Cancel signalled for {flow}.'**
|
||||
String runsCancelSignalled(String flow);
|
||||
|
||||
/// No description provided for @runsCancelTooLate.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'The run had already finished — nothing to cancel.'**
|
||||
String get runsCancelTooLate;
|
||||
|
||||
/// No description provided for @runsCurrentStep.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Step: {step}'**
|
||||
String runsCurrentStep(String step);
|
||||
|
||||
/// No description provided for @runsPhasePending.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Pending'**
|
||||
String get runsPhasePending;
|
||||
|
||||
/// No description provided for @runsPhaseRunning.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Running'**
|
||||
String get runsPhaseRunning;
|
||||
|
||||
/// No description provided for @runsPhaseSucceeded.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Succeeded'**
|
||||
String get runsPhaseSucceeded;
|
||||
|
||||
/// No description provided for @runsPhaseFailed.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Failed'**
|
||||
String get runsPhaseFailed;
|
||||
|
||||
/// No description provided for @runsPhaseCancelled.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Cancelled'**
|
||||
String get runsPhaseCancelled;
|
||||
|
||||
/// No description provided for @runsPhaseUnknown.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Unknown'**
|
||||
String get runsPhaseUnknown;
|
||||
|
||||
/// No description provided for @navRuns.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Runs'**
|
||||
String get navRuns;
|
||||
}
|
||||
|
||||
class _AppLocalizationsDelegate
|
||||
|
|
|
|||
|
|
@ -2882,4 +2882,55 @@ class AppLocalizationsDe extends AppLocalizations {
|
|||
@override
|
||||
String get workspaceProtectedHint =>
|
||||
'Geschützt: logisch getrennt im gemeinsamen Hub — keine harte Prozessgrenze. Kritische Mandate nutzen einen abgeschotteten Bereich.';
|
||||
|
||||
@override
|
||||
String get runsTitle => 'Läufe';
|
||||
|
||||
@override
|
||||
String get runsReloadTooltip => 'Lauf-Liste neu laden';
|
||||
|
||||
@override
|
||||
String get runsEmptyTitle => 'Keine abgekoppelten Läufe';
|
||||
|
||||
@override
|
||||
String get runsEmptyHint =>
|
||||
'Mit detach gestartete Läufe stehen hier, bis sie fertig sind. Abgekoppelte Aufrufe sind optional — dazu detached.enabled in der Betreiber-Konfiguration aktivieren.';
|
||||
|
||||
@override
|
||||
String get runsCancelButton => 'Abbrechen';
|
||||
|
||||
@override
|
||||
String runsCancelSignalled(String flow) {
|
||||
return 'Abbruch für $flow ausgelöst.';
|
||||
}
|
||||
|
||||
@override
|
||||
String get runsCancelTooLate =>
|
||||
'Der Lauf war schon fertig — nichts abzubrechen.';
|
||||
|
||||
@override
|
||||
String runsCurrentStep(String step) {
|
||||
return 'Schritt: $step';
|
||||
}
|
||||
|
||||
@override
|
||||
String get runsPhasePending => 'Wartet';
|
||||
|
||||
@override
|
||||
String get runsPhaseRunning => 'Läuft';
|
||||
|
||||
@override
|
||||
String get runsPhaseSucceeded => 'Erfolgreich';
|
||||
|
||||
@override
|
||||
String get runsPhaseFailed => 'Fehlgeschlagen';
|
||||
|
||||
@override
|
||||
String get runsPhaseCancelled => 'Abgebrochen';
|
||||
|
||||
@override
|
||||
String get runsPhaseUnknown => 'Unbekannt';
|
||||
|
||||
@override
|
||||
String get navRuns => 'Läufe';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2885,4 +2885,55 @@ class AppLocalizationsEn extends AppLocalizations {
|
|||
@override
|
||||
String get workspaceProtectedHint =>
|
||||
'Protected: logically separated in the shared hub — no hard process barrier. Critical engagements use a sealed area.';
|
||||
|
||||
@override
|
||||
String get runsTitle => 'Runs';
|
||||
|
||||
@override
|
||||
String get runsReloadTooltip => 'Reload the runs list';
|
||||
|
||||
@override
|
||||
String get runsEmptyTitle => 'No detached runs';
|
||||
|
||||
@override
|
||||
String get runsEmptyHint =>
|
||||
'Runs submitted with detach stay here until they finish. Detached invocations are opt-in — enable detached.enabled in the operator config to use them.';
|
||||
|
||||
@override
|
||||
String get runsCancelButton => 'Cancel';
|
||||
|
||||
@override
|
||||
String runsCancelSignalled(String flow) {
|
||||
return 'Cancel signalled for $flow.';
|
||||
}
|
||||
|
||||
@override
|
||||
String get runsCancelTooLate =>
|
||||
'The run had already finished — nothing to cancel.';
|
||||
|
||||
@override
|
||||
String runsCurrentStep(String step) {
|
||||
return 'Step: $step';
|
||||
}
|
||||
|
||||
@override
|
||||
String get runsPhasePending => 'Pending';
|
||||
|
||||
@override
|
||||
String get runsPhaseRunning => 'Running';
|
||||
|
||||
@override
|
||||
String get runsPhaseSucceeded => 'Succeeded';
|
||||
|
||||
@override
|
||||
String get runsPhaseFailed => 'Failed';
|
||||
|
||||
@override
|
||||
String get runsPhaseCancelled => 'Cancelled';
|
||||
|
||||
@override
|
||||
String get runsPhaseUnknown => 'Unknown';
|
||||
|
||||
@override
|
||||
String get navRuns => 'Runs';
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue