fix(centralui): Esc-to-close and aria attributes on ExecutionDetailModal
This commit is contained in:
@@ -13,13 +13,16 @@
|
|||||||
<div class="modal-backdrop fade show" data-test="execution-detail-backdrop"
|
<div class="modal-backdrop fade show" data-test="execution-detail-backdrop"
|
||||||
@onclick="HandleClose"></div>
|
@onclick="HandleClose"></div>
|
||||||
<div class="modal fade show d-block execution-detail-modal" tabindex="-1"
|
<div class="modal fade show d-block execution-detail-modal" tabindex="-1"
|
||||||
data-test="execution-detail-modal" role="dialog">
|
data-test="execution-detail-modal" role="dialog"
|
||||||
|
aria-modal="true" aria-labelledby="execution-detail-modal-title"
|
||||||
|
@onkeydown="HandleKeyDown">
|
||||||
<div class="modal-dialog modal-lg modal-dialog-scrollable" role="document">
|
<div class="modal-dialog modal-lg modal-dialog-scrollable" role="document">
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
<div>
|
<div>
|
||||||
<div class="text-muted small text-uppercase">Execution</div>
|
<div class="text-muted small text-uppercase">Execution</div>
|
||||||
<h5 class="modal-title mb-0 d-flex align-items-baseline gap-2">
|
<h5 id="execution-detail-modal-title"
|
||||||
|
class="modal-title mb-0 d-flex align-items-baseline gap-2">
|
||||||
<span class="font-monospace">Execution @ShortExecutionId()</span>
|
<span class="font-monospace">Execution @ShortExecutionId()</span>
|
||||||
@if (!_loading && _error is null)
|
@if (!_loading && _error is null)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using Microsoft.AspNetCore.Components;
|
using Microsoft.AspNetCore.Components;
|
||||||
|
using Microsoft.AspNetCore.Components.Web;
|
||||||
using ScadaLink.CentralUI.Services;
|
using ScadaLink.CentralUI.Services;
|
||||||
using ScadaLink.Commons.Entities.Audit;
|
using ScadaLink.Commons.Entities.Audit;
|
||||||
using ScadaLink.Commons.Types.Audit;
|
using ScadaLink.Commons.Types.Audit;
|
||||||
@@ -112,6 +113,10 @@ public partial class ExecutionDetailModal
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
// No CancellationToken is passed deliberately: this is a bounded,
|
||||||
|
// small (~100-row) query for one execution, so the IDisposable/CTS
|
||||||
|
// machinery is not worth it for a modal. The closed → open guard in
|
||||||
|
// OnParametersSetAsync cleanly re-loads on the next open if needed.
|
||||||
_rows = await AuditLogQueryService.QueryAsync(
|
_rows = await AuditLogQueryService.QueryAsync(
|
||||||
new AuditLogQueryFilter(ExecutionId: ExecutionId.Value),
|
new AuditLogQueryFilter(ExecutionId: ExecutionId.Value),
|
||||||
new AuditLogPaging(PageSize: RowPageSize));
|
new AuditLogPaging(PageSize: RowPageSize));
|
||||||
@@ -150,6 +155,19 @@ public partial class ExecutionDetailModal
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Closes the modal when Escape is pressed, matching the header X, backdrop
|
||||||
|
/// click, and footer Close affordances. The root <c>.modal</c> div carries
|
||||||
|
/// <c>tabindex="-1"</c> so it can receive the keydown.
|
||||||
|
/// </summary>
|
||||||
|
private async Task HandleKeyDown(KeyboardEventArgs e)
|
||||||
|
{
|
||||||
|
if (e.Key == "Escape")
|
||||||
|
{
|
||||||
|
await HandleClose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>First 8 hex digits of the execution id, mirroring the UI's short-id convention.</summary>
|
/// <summary>First 8 hex digits of the execution id, mirroring the UI's short-id convention.</summary>
|
||||||
private string ShortExecutionId()
|
private string ShortExecutionId()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -263,6 +263,23 @@ public class ExecutionDetailModalTests : BunitContext
|
|||||||
Assert.True(closed);
|
Assert.True(closed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void EscapeKey_RaisesOnClose()
|
||||||
|
{
|
||||||
|
var executionId = Guid.NewGuid();
|
||||||
|
StubRows(new[] { MakeEvent(executionId), MakeEvent(executionId) });
|
||||||
|
|
||||||
|
var closed = false;
|
||||||
|
var cut = Render<ExecutionDetailModal>(p => p
|
||||||
|
.Add(c => c.ExecutionId, executionId)
|
||||||
|
.Add(c => c.IsOpen, true)
|
||||||
|
.Add(c => c.OnClose, EventCallback.Factory.Create(this, () => closed = true)));
|
||||||
|
|
||||||
|
cut.Find("[data-test=\"execution-detail-modal\"]").KeyDown("Escape");
|
||||||
|
|
||||||
|
Assert.True(closed);
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void Header_ShowsShortExecutionId_AndRowCount()
|
public void Header_ShowsShortExecutionId_AndRowCount()
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user