ui(scripts): inline source expander → dialog + stacked row identity (§1d Task 2)
This commit is contained in:
@@ -25,30 +25,72 @@ else
|
||||
}
|
||||
else
|
||||
{
|
||||
@foreach (var s in _rows)
|
||||
{
|
||||
<details style="border-top:1px solid var(--rule)">
|
||||
<summary style="padding:.75rem 1rem;cursor:pointer">
|
||||
<span class="mono">@s.ScriptId</span>
|
||||
· <span>@s.Name</span>
|
||||
· <span class="chip chip-idle ms-1">@s.Language</span>
|
||||
<span class="text-muted small ms-2 mono">hash=@DisplayText.Abbreviate(s.SourceHash, 12)</span>
|
||||
</summary>
|
||||
<div style="padding:0 1rem 1rem">
|
||||
<div class="d-flex mb-2">
|
||||
<a href="/scripts/@s.ScriptId" class="btn btn-sm btn-outline-primary">Edit</a>
|
||||
</div>
|
||||
<pre class="mono small" style="background:var(--zebra-bg);padding:1rem;border-radius:4px;overflow:auto">@s.SourceCode</pre>
|
||||
</div>
|
||||
</details>
|
||||
}
|
||||
<table class="table table-sm mb-0 align-middle">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Script</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (var s in _rows)
|
||||
{
|
||||
<tr>
|
||||
<td>
|
||||
<div>
|
||||
<span>@(string.IsNullOrWhiteSpace(s.Name) ? s.ScriptId : s.Name)</span>
|
||||
<span class="chip chip-idle ms-1">@s.Language</span>
|
||||
</div>
|
||||
<div class="mono small text-muted">
|
||||
@s.ScriptId · hash=@DisplayText.Abbreviate(s.SourceHash, 12)
|
||||
</div>
|
||||
</td>
|
||||
<td class="text-end">
|
||||
<div class="btn-group btn-group-sm" role="group">
|
||||
<button type="button" class="btn btn-sm btn-outline-secondary"
|
||||
@onclick="() => ShowSource(s.ScriptId)">Source</button>
|
||||
<a href="/scripts/@s.ScriptId" class="btn btn-sm btn-outline-primary">Edit</a>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
}
|
||||
</section>
|
||||
}
|
||||
|
||||
@if (FindSourceScript() is { } src)
|
||||
{
|
||||
<div class="modal-backdrop fade show" style="display:block"></div>
|
||||
<div class="modal fade show" tabindex="-1" role="dialog" style="display:block">
|
||||
<div class="modal-dialog modal-lg modal-dialog-scrollable" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">
|
||||
@(string.IsNullOrWhiteSpace(src.Name) ? src.ScriptId : src.Name)
|
||||
<span class="mono small text-muted ms-2">@src.ScriptId</span>
|
||||
</h5>
|
||||
<button type="button" class="btn-close" aria-label="Close" @onclick="CloseSource"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<pre class="mono small mb-0" style="background:var(--zebra-bg);padding:1rem;border-radius:4px;overflow:auto">@src.SourceCode</pre>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-outline-secondary" @onclick="CloseSource">Close</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
@code {
|
||||
private List<Script>? _rows;
|
||||
|
||||
// Only the id of the script whose source dialog is open — never the record itself, so a reload
|
||||
// that drops or replaces the row cannot leave a stale object on screen.
|
||||
private string? _sourceScriptId;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
await using var db = await DbFactory.CreateDbContextAsync();
|
||||
@@ -56,4 +98,16 @@ else
|
||||
.OrderBy(s => s.Name)
|
||||
.ToListAsync();
|
||||
}
|
||||
|
||||
/// <summary>Re-resolves the open dialog's script from the current list on every render; a script
|
||||
/// that is no longer loaded renders nothing, so the dialog self-closes.</summary>
|
||||
private Script? FindSourceScript()
|
||||
=> _sourceScriptId is null
|
||||
? null
|
||||
: _rows?.FirstOrDefault(s => s.ScriptId == _sourceScriptId);
|
||||
|
||||
// One dialog at a time: opening another row replaces the id.
|
||||
private void ShowSource(string scriptId) => _sourceScriptId = scriptId;
|
||||
|
||||
private void CloseSource() => _sourceScriptId = null;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user