fix(web): address code review findings from Razor Pages migration

- Remove legacy wwwroot files (old index.html, app.css, api.js, page scripts)
- Add Index page that redirects / to /board
- Fix mapping delete button missing handler=Delete in URL
- Add [IgnoreAntiforgeryToken] to AnalyticsModel for consistency
- Remove duplicate JS from _TaskDetail.cshtml (already in app.js)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-01 22:47:49 -05:00
parent cffd09941a
commit 6ea0e40d38
13 changed files with 14 additions and 1495 deletions

View File

@@ -7,6 +7,7 @@ using TaskTracker.Core.Interfaces;
namespace TaskTracker.Api.Pages;
[IgnoreAntiforgeryToken]
public class AnalyticsModel : PageModel
{
private readonly ITaskRepository _taskRepo;

View File

@@ -0,0 +1,2 @@
@page
@model TaskTracker.Api.Pages.IndexModel

View File

@@ -0,0 +1,9 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace TaskTracker.Api.Pages;
public class IndexModel : PageModel
{
public IActionResult OnGet() => RedirectToPage("/Board");
}

View File

@@ -28,7 +28,7 @@
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M17 3a2.85 2.85 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5Z"/><path d="m15 5 4 4"/></svg>
</button>
<button class="btn btn--ghost btn--sm"
hx-delete="/mappings?id=@Model.Id"
hx-delete="/mappings?handler=Delete&id=@Model.Id"
hx-target="#mapping-row-@Model.Id"
hx-swap="outerHTML"
hx-confirm="Delete this mapping rule?"

View File

@@ -259,65 +259,4 @@
}
</div>
<script>
// Open the detail panel when this partial is loaded
(function() {
var overlay = document.querySelector('.detail-overlay');
var panel = document.querySelector('.detail-panel');
// Use requestAnimationFrame to ensure the DOM is painted before adding classes
requestAnimationFrame(function() {
if (overlay) overlay.classList.add('detail-overlay--open');
if (panel) panel.classList.add('detail-panel--open');
});
})();
function closeDetailPanel() {
var overlay = document.querySelector('.detail-overlay');
var panel = document.querySelector('.detail-panel');
if (overlay) overlay.classList.remove('detail-overlay--open');
if (panel) panel.classList.remove('detail-panel--open');
// Clear the panel content after the transition
setTimeout(function() {
var container = document.getElementById('detail-panel');
if (container) container.innerHTML = '';
}, 300);
}
function startEdit(field) {
var wrapper = document.getElementById('edit-' + field);
if (!wrapper) return;
var display = wrapper.querySelector('.inline-edit-display');
var form = wrapper.querySelector('.inline-edit-form');
if (display) display.style.display = 'none';
if (form) {
form.style.display = '';
var input = form.querySelector('input, textarea');
if (input) {
input.focus();
if (input.type === 'text' || input.tagName === 'TEXTAREA') {
input.setSelectionRange(input.value.length, input.value.length);
}
}
}
}
function cancelEdit(field) {
var wrapper = document.getElementById('edit-' + field);
if (!wrapper) return;
var display = wrapper.querySelector('.inline-edit-display');
var form = wrapper.querySelector('.inline-edit-form');
if (display) display.style.display = '';
if (form) form.style.display = 'none';
}
// Close panel on Escape key
document.addEventListener('keydown', function(e) {
if (e.key === 'Escape') {
var panel = document.querySelector('.detail-panel--open');
if (panel) {
closeDetailPanel();
e.stopPropagation();
}
}
});
</script>
<!-- Panel open/close, inline editing, and keyboard handling are in app.js -->