Add auto-scroll to first amount match in receipt mapping modal
When opening the map receipt modal, the transaction list now automatically scrolls to center on the first green-highlighted amount match (if one exists). This makes it easier to quickly find and select the most likely matching transaction without having to manually scroll through the list. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -317,7 +317,7 @@
|
|||||||
Rows highlighted in <span class="badge bg-success">green</span> have matching amounts.
|
Rows highlighted in <span class="badge bg-success">green</span> have matching amounts.
|
||||||
</div>
|
</div>
|
||||||
<input type="hidden" id="transactionId@(r.Id)" name="transactionId" required />
|
<input type="hidden" id="transactionId@(r.Id)" name="transactionId" required />
|
||||||
<div style="max-height: 400px; overflow-y: auto; border: 1px solid #dee2e6; border-radius: 0.25rem;">
|
<div id="transactionListContainer@(r.Id)" style="max-height: 400px; overflow-y: auto; border: 1px solid #dee2e6; border-radius: 0.25rem;">
|
||||||
<table class="table table-sm table-hover mb-0" style="font-size: 0.85rem;">
|
<table class="table table-sm table-hover mb-0" style="font-size: 0.85rem;">
|
||||||
<thead style="position: sticky; top: 0; background-color: white; z-index: 1;">
|
<thead style="position: sticky; top: 0; background-color: white; z-index: 1;">
|
||||||
<tr>
|
<tr>
|
||||||
@@ -330,10 +330,16 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
|
@{
|
||||||
|
var firstMatchId = matches.FirstOrDefault(t => t.IsAmountMatch)?.Id;
|
||||||
|
}
|
||||||
@foreach (var txn in matches)
|
@foreach (var txn in matches)
|
||||||
{
|
{
|
||||||
var rowClass = txn.IsAmountMatch ? "table-success" : "";
|
var rowClass = txn.IsAmountMatch ? "table-success" : "";
|
||||||
<tr class="@rowClass" style="cursor: pointer;"
|
var isFirstMatch = txn.Id == firstMatchId;
|
||||||
|
<tr class="@rowClass"
|
||||||
|
id="@(isFirstMatch ? $"firstMatch{r.Id}" : "")"
|
||||||
|
style="cursor: pointer;"
|
||||||
onclick="document.getElementById('transactionId@(r.Id)').value = '@txn.Id';
|
onclick="document.getElementById('transactionId@(r.Id)').value = '@txn.Id';
|
||||||
document.querySelectorAll('#mapModal@(r.Id) tbody tr').forEach(tr => tr.classList.remove('table-primary'));
|
document.querySelectorAll('#mapModal@(r.Id) tbody tr').forEach(tr => tr.classList.remove('table-primary'));
|
||||||
this.classList.add('table-primary');">
|
this.classList.add('table-primary');">
|
||||||
@@ -352,6 +358,25 @@
|
|||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
@if (firstMatchId.HasValue)
|
||||||
|
{
|
||||||
|
<script>
|
||||||
|
// Auto-scroll to first amount match when modal opens
|
||||||
|
document.getElementById('mapModal@(r.Id)').addEventListener('shown.bs.modal', function() {
|
||||||
|
var firstMatch = document.getElementById('firstMatch@(r.Id)');
|
||||||
|
if (firstMatch) {
|
||||||
|
var container = document.getElementById('transactionListContainer@(r.Id)');
|
||||||
|
var containerTop = container.scrollTop;
|
||||||
|
var elementTop = firstMatch.offsetTop;
|
||||||
|
var containerHeight = container.clientHeight;
|
||||||
|
var elementHeight = firstMatch.clientHeight;
|
||||||
|
|
||||||
|
// Scroll so the element is centered in the viewport
|
||||||
|
container.scrollTop = elementTop - (containerHeight / 2) + (elementHeight / 2);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user