Merge pull request #1649 from Runfusion/agent/ceo/960946e0

FUS-7: keep activity modal on screen
This commit is contained in:
gsxdsm
2026-06-20 07:37:07 +08:00
committed by GitHub
2 changed files with 29 additions and 15 deletions

View File

@@ -1,19 +1,15 @@
import { describe, it, expect } from "vitest";
import { loadAllAppCss } from "../test/cssFixture";
import { readFileSync } from "fs";
import { resolve } from "path";
/**
* Stylesheet regression test for Activity Log mobile layout.
* Stylesheet regression test for Activity Log modal layout.
*
* Parses `packages/dashboard/app/styles.css` and asserts that an
* `@media (max-width: 768px)` block contains Activity Log mobile rules
* for stacked/wrapped controls and entry layout. These selectors must
* remain inside a mobile media query so the Activity Log renders
* correctly on narrow screens.
* Parses the app CSS bundle and asserts that desktop viewport constraints
* keep the modal on screen while mobile rules keep controls usable on
* narrow screens.
*/
describe("activity-log-mobile-layout.css", () => {
describe("activity-log-layout.css", () => {
const cssContent = loadAllAppCss();
/** Extract all content inside @media (max-width: 768px) blocks. */
@@ -42,12 +38,27 @@ describe("activity-log-mobile-layout.css", () => {
// ── Modal sizing ────────────────────────────────────────────────────
it("uses modal-lg base class for consistent wide sizing", () => {
// The activity-log-modal should NOT set its own max-width; modal-lg handles width
it("keeps desktop modal width within the viewport", () => {
const modalBlock = cssContent.match(/\.activity-log-modal\s*\{[^}]*\}/)?.[0];
expect(modalBlock).toBeTruthy();
// Should NOT contain max-width (handled by modal-lg base class)
expect(modalBlock).not.toMatch(/max-width:\s*\d+px/);
expect(modalBlock).toContain("width: min(95vw, 640px);");
expect(modalBlock).toContain("max-width: 95vw;");
});
it("keeps desktop modal height inside the visible viewport", () => {
const modalBlock = cssContent.match(/\.activity-log-modal\s*\{[^}]*\}/)?.[0];
expect(modalBlock).toBeTruthy();
expect(modalBlock).toMatch(/max-height:\s*calc\(100dvh - var\(--overlay-padding-top,\s*10vh\) - 16px\);/);
expect(modalBlock).toContain("overflow: hidden;");
});
it("allows content pane to shrink and scroll inside the capped modal", () => {
const contentBlock = cssContent.match(
/\.activity-log-content\s*\{(?=[^}]*overflow-y:\s*auto;)(?=[^}]*min-height:\s*0;)[^}]*\}/,
)?.[0];
expect(contentBlock).toBeTruthy();
expect(contentBlock).toContain("overflow-y: auto;");
expect(contentBlock).toContain("min-height: 0;");
});
// ── Close button ────────────────────────────────────────────────────

View File

@@ -1185,9 +1185,12 @@ Non-Command-Center dashboard CSS must use the canonical --text token. The legacy
/* ── Activity Log Modal ─────────────────────────────────────────── */
.activity-log-modal {
max-height: 80vh;
width: min(95vw, 640px);
max-width: 95vw;
max-height: calc(100dvh - var(--overlay-padding-top, 10vh) - 16px);
display: flex;
flex-direction: column;
overflow: hidden;
}
.activity-log-header {
@@ -1255,7 +1258,7 @@ Non-Command-Center dashboard CSS must use the canonical --text token. The legacy
flex: 1;
overflow-y: auto;
padding: var(--space-lg) var(--space-xl);
min-height: 300px;
min-height: 0;
}
.activity-log-empty {