diff --git a/src/ZB.MOM.WW.MxGateway.Server/Dashboard/Components/Pages/SessionDetailsPage.razor b/src/ZB.MOM.WW.MxGateway.Server/Dashboard/Components/Pages/SessionDetailsPage.razor
index 1c5616e..d05ef32 100644
--- a/src/ZB.MOM.WW.MxGateway.Server/Dashboard/Components/Pages/SessionDetailsPage.razor
+++ b/src/ZB.MOM.WW.MxGateway.Server/Dashboard/Components/Pages/SessionDetailsPage.razor
@@ -34,12 +34,12 @@ else
Session
@@ -176,24 +188,55 @@ else
}
}
- private Task CloseSessionAsync()
- {
- return RunAdminActionAsync(user => SessionAdminService.CloseSessionAsync(user, SessionId, CancellationToken.None));
- }
+ private PendingConfirm? PendingAction { get; set; }
- private Task KillWorkerAsync()
- {
- return RunAdminActionAsync(user => SessionAdminService.KillWorkerAsync(user, SessionId, CancellationToken.None));
- }
-
- private async Task RunAdminActionAsync(
- Func> action)
+ private void RequestClose()
{
if (IsBusy)
{
return;
}
+ PendingAction = new PendingConfirm(
+ Title: "Close session?",
+ Message: $"Gracefully close session {SessionId}? The worker will be shut down.",
+ ConfirmLabel: "Close",
+ ConfirmButtonClass: "btn-warning",
+ Action: user => SessionAdminService.CloseSessionAsync(user, SessionId, CancellationToken.None));
+ }
+
+ private void RequestKill()
+ {
+ if (IsBusy)
+ {
+ return;
+ }
+
+ PendingAction = new PendingConfirm(
+ Title: "Kill worker?",
+ Message: $"Forcefully kill the worker for session {SessionId}? This skips graceful shutdown.",
+ ConfirmLabel: "Kill",
+ ConfirmButtonClass: "btn-danger",
+ Action: user => SessionAdminService.KillWorkerAsync(user, SessionId, CancellationToken.None));
+ }
+
+ private void CancelPending()
+ {
+ if (!IsBusy)
+ {
+ PendingAction = null;
+ }
+ }
+
+ private async Task ConfirmPendingAsync()
+ {
+ if (IsBusy || PendingAction is null)
+ {
+ return;
+ }
+
+ Func> action = PendingAction.Action;
+
IsBusy = true;
try
{
@@ -207,9 +250,17 @@ else
finally
{
IsBusy = false;
+ PendingAction = null;
}
}
+ private sealed record PendingConfirm(
+ string Title,
+ string Message,
+ string ConfirmLabel,
+ string ConfirmButtonClass,
+ Func> Action);
+
private async Task AttachEventsHubAsync()
{
if (string.IsNullOrWhiteSpace(SessionId))
diff --git a/src/ZB.MOM.WW.MxGateway.Server/Dashboard/Components/Pages/SessionsPage.razor b/src/ZB.MOM.WW.MxGateway.Server/Dashboard/Components/Pages/SessionsPage.razor
index c4d801c..3c07a26 100644
--- a/src/ZB.MOM.WW.MxGateway.Server/Dashboard/Components/Pages/SessionsPage.razor
+++ b/src/ZB.MOM.WW.MxGateway.Server/Dashboard/Components/Pages/SessionsPage.razor
@@ -25,6 +25,18 @@ else
}
+ @if (CanManage)
+ {
+
+ }
+
@if (Snapshot.Sessions.Count == 0)
{
@@ -78,12 +90,12 @@ else
@@ -116,24 +128,55 @@ else
CanManage = SessionAdminService.CanManage(authenticationState.User);
}
- private Task CloseSessionAsync(string sessionId)
- {
- return RunActionAsync(user => SessionAdminService.CloseSessionAsync(user, sessionId, CancellationToken.None));
- }
+ private PendingConfirm? PendingAction { get; set; }
- private Task KillWorkerAsync(string sessionId)
- {
- return RunActionAsync(user => SessionAdminService.KillWorkerAsync(user, sessionId, CancellationToken.None));
- }
-
- private async Task RunActionAsync(
- Func> action)
+ private void RequestClose(string sessionId)
{
if (IsBusy)
{
return;
}
+ PendingAction = new PendingConfirm(
+ Title: "Close session?",
+ Message: $"Gracefully close session {sessionId}? The worker will be shut down.",
+ ConfirmLabel: "Close",
+ ConfirmButtonClass: "btn-warning",
+ Action: user => SessionAdminService.CloseSessionAsync(user, sessionId, CancellationToken.None));
+ }
+
+ private void RequestKill(string sessionId)
+ {
+ if (IsBusy)
+ {
+ return;
+ }
+
+ PendingAction = new PendingConfirm(
+ Title: "Kill worker?",
+ Message: $"Forcefully kill the worker for session {sessionId}? This skips graceful shutdown.",
+ ConfirmLabel: "Kill",
+ ConfirmButtonClass: "btn-danger",
+ Action: user => SessionAdminService.KillWorkerAsync(user, sessionId, CancellationToken.None));
+ }
+
+ private void CancelPending()
+ {
+ if (!IsBusy)
+ {
+ PendingAction = null;
+ }
+ }
+
+ private async Task ConfirmPendingAsync()
+ {
+ if (IsBusy || PendingAction is null)
+ {
+ return;
+ }
+
+ Func> action = PendingAction.Action;
+
IsBusy = true;
try
{
@@ -147,6 +190,14 @@ else
finally
{
IsBusy = false;
+ PendingAction = null;
}
}
+
+ private sealed record PendingConfirm(
+ string Title,
+ string Message,
+ string ConfirmLabel,
+ string ConfirmButtonClass,
+ Func> Action);
}
diff --git a/src/ZB.MOM.WW.MxGateway.Server/Dashboard/Components/Pages/WorkersPage.razor b/src/ZB.MOM.WW.MxGateway.Server/Dashboard/Components/Pages/WorkersPage.razor
index 5fd3edb..dbde48b 100644
--- a/src/ZB.MOM.WW.MxGateway.Server/Dashboard/Components/Pages/WorkersPage.razor
+++ b/src/ZB.MOM.WW.MxGateway.Server/Dashboard/Components/Pages/WorkersPage.razor
@@ -25,6 +25,18 @@ else
}
+ @if (CanManage)
+ {
+
+ }
+
@if (Snapshot.Workers.Count == 0)
{
@@ -61,7 +73,7 @@ else
|
@@ -93,13 +105,34 @@ else
CanManage = SessionAdminService.CanManage(authenticationState.User);
}
- private async Task KillWorkerAsync(string sessionId)
+ private string? PendingSessionId { get; set; }
+
+ private void RequestKill(string sessionId)
{
if (IsBusy)
{
return;
}
+ PendingSessionId = sessionId;
+ }
+
+ private void CancelPending()
+ {
+ if (!IsBusy)
+ {
+ PendingSessionId = null;
+ }
+ }
+
+ private async Task ConfirmKillAsync()
+ {
+ if (IsBusy || PendingSessionId is null)
+ {
+ return;
+ }
+
+ string sessionId = PendingSessionId;
IsBusy = true;
try
{
@@ -115,6 +148,7 @@ else
finally
{
IsBusy = false;
+ PendingSessionId = null;
}
}
}
diff --git a/src/ZB.MOM.WW.MxGateway.Server/Dashboard/Components/Shared/ConfirmDialog.razor b/src/ZB.MOM.WW.MxGateway.Server/Dashboard/Components/Shared/ConfirmDialog.razor
new file mode 100644
index 0000000..e52e8df
--- /dev/null
+++ b/src/ZB.MOM.WW.MxGateway.Server/Dashboard/Components/Shared/ConfirmDialog.razor
@@ -0,0 +1,59 @@
+@if (IsOpen)
+{
+
+
+}
+
+@code {
+ private readonly string TitleId = $"confirm-dialog-{Guid.NewGuid():N}";
+
+ [Parameter]
+ public bool IsOpen { get; set; }
+
+ [Parameter]
+ public string Title { get; set; } = "Confirm";
+
+ [Parameter]
+ public string Message { get; set; } = string.Empty;
+
+ [Parameter]
+ public string ConfirmLabel { get; set; } = "Confirm";
+
+ [Parameter]
+ public string ConfirmButtonClass { get; set; } = "btn-primary";
+
+ [Parameter]
+ public bool IsBusy { get; set; }
+
+ [Parameter]
+ public EventCallback OnConfirm { get; set; }
+
+ [Parameter]
+ public EventCallback OnCancel { get; set; }
+}