fix(FN-821): fix Activity Log modal layout and close control

- Fix modal sizing to properly fit within viewport on various screen sizes
- Fix close button visibility and accessibility in ActivityLogModal component
- Refactor CSS to simplify modal styles (remove unused/verbose rules)
- Add regression tests for modal layout and close button behavior
- Update Activity Log docs to reflect modal sizing changes
This commit is contained in:
gsxdsm
2026-04-04 01:25:16 -07:00
parent 482492b26e
commit 3516394e9f
5 changed files with 64 additions and 31 deletions

View File

@@ -182,9 +182,9 @@ export function ActivityLogModal({
}}
data-testid="activity-log-modal-overlay"
>
<div className="modal activity-log-modal" data-testid="activity-log-modal">
{/* Header */}
<div className="activity-log-header">
<div className="modal modal-lg activity-log-modal" data-testid="activity-log-modal">
{/* Header — uses shared modal-header pattern for consistent close control */}
<div className="modal-header activity-log-header">
<div className="activity-log-title">
<History size={18} />
<span>Activity Log</span>
@@ -250,17 +250,17 @@ export function ActivityLogModal({
<Trash2 size={14} />
</button>
)}
{/* Close button */}
<button
className="activity-log-close"
onClick={onClose}
title="Close"
data-testid="activity-close"
>
<X size={18} />
</button>
</div>
{/* Close button — uses shared modal-close for consistent sizing and alignment */}
<button
className="modal-close"
onClick={onClose}
aria-label="Close"
title="Close"
data-testid="activity-close"
>
×
</button>
</div>
{/* Active filters display */}

View File

@@ -492,6 +492,10 @@ describe("ActivityLogModal", () => {
// Verify key structural classes that the mobile CSS targets
const modal = container.querySelector(".activity-log-modal");
expect(modal).toBeTruthy();
// Modal uses shared modal-lg for consistent wide sizing
expect(modal!.classList.contains("modal-lg")).toBe(true);
// Header uses shared modal-header pattern
expect(modal!.querySelector(".modal-header")).toBeTruthy();
expect(modal!.querySelector(".activity-log-header")).toBeTruthy();
expect(modal!.querySelector(".activity-log-title")).toBeTruthy();
expect(modal!.querySelector(".activity-log-actions")).toBeTruthy();
@@ -500,6 +504,31 @@ describe("ActivityLogModal", () => {
expect(modal!.querySelector(".activity-log-entry")).toBeTruthy();
});
it("renders close button with shared modal-close class and accessibility attributes", async () => {
const { container } = render(
<ActivityLogModal
isOpen={true}
onClose={mockOnClose}
tasks={mockTasks}
onOpenTaskDetail={mockOnOpenTaskDetail}
/>
);
const closeButton = await screen.findByTestId("activity-close");
expect(closeButton).toBeTruthy();
// Uses shared modal-close class for consistent styling
expect(closeButton.classList.contains("modal-close")).toBe(true);
// Has accessibility label
expect(closeButton.getAttribute("aria-label")).toBe("Close");
// Close button is a direct child of the header, NOT inside the actions row
const header = container.querySelector(".modal-header");
expect(header).toBeTruthy();
expect(header!.contains(closeButton)).toBe(true);
const actions = container.querySelector(".activity-log-actions");
expect(actions).toBeTruthy();
expect(actions!.contains(closeButton)).toBe(false);
});
it("renders entry header and details within each entry for mobile reflow", async () => {
const { container } = render(
<ActivityLogModal