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
@@ -54,6 +54,18 @@ else } + @if (CanManage) + { + + } +

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; } +}