FN-8131: wrap Quality header actions on mobile
Keep Quality preset and refresh actions visible beneath the title on compact screens. - Wrap the scoped Quality dashboard header at mobile breakpoints. - Give the title and action cluster full-width rows without desktop regressions. - Add responsive CSS coverage and a patch changeset. Files changed: .changeset/fn-8131-quality-mobile-header.md | 7 ++++ .../__tests__/dashboard-view-mobile-header.test.ts | 37 ++++++++++++++++++++++ .../fusion-plugin-quality/src/dashboard-view.css | 29 +++++++++++++++++ 3 files changed, 73 insertions(+) Fusion-Task-Id: FN-8131 Fusion-Task-Lineage: 920ae59f-327a-45c8-90b1-1b4d7639442f Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
This commit is contained in:
7
.changeset/fn-8131-quality-mobile-header.md
Normal file
7
.changeset/fn-8131-quality-mobile-header.md
Normal file
@@ -0,0 +1,7 @@
|
||||
---
|
||||
"@runfusion/fusion": patch
|
||||
---
|
||||
|
||||
summary: Keep Quality hub actions visible beneath the title on mobile.
|
||||
category: fix
|
||||
dev: Scope the responsive header-wrap treatment to the bundled Quality plugin.
|
||||
@@ -0,0 +1,37 @@
|
||||
import { readFileSync } from "node:fs";
|
||||
import { dirname, join } from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
const srcRoot = join(dirname(fileURLToPath(import.meta.url)), "..");
|
||||
const dashboardViewCss = readFileSync(join(srcRoot, "dashboard-view.css"), "utf8");
|
||||
const mobileMediaQuery = "@media (max-width: 768px), (max-height: 480px)";
|
||||
|
||||
function mediaBlock(css: string, query: string): string {
|
||||
const start = css.indexOf(query);
|
||||
expect(start, `expected ${query} mobile rule`).toBeGreaterThanOrEqual(0);
|
||||
|
||||
const openBrace = css.indexOf("{", start);
|
||||
let depth = 0;
|
||||
for (let index = openBrace; index < css.length; index += 1) {
|
||||
if (css[index] === "{") depth += 1;
|
||||
if (css[index] === "}") depth -= 1;
|
||||
if (depth === 0) return css.slice(openBrace + 1, index);
|
||||
}
|
||||
|
||||
throw new Error(`unterminated ${query} rule`);
|
||||
}
|
||||
|
||||
describe("QualityDashboardView mobile header CSS", () => {
|
||||
it("gives the title its own row and wraps preset actions below it", () => {
|
||||
const mobileCss = mediaBlock(dashboardViewCss, mobileMediaQuery);
|
||||
|
||||
// FNXC:Quality 2026-07-16-12:45: FN-8131 preserves the mobile invariant for every run-count width and both canonical mobile breakpoint arms.
|
||||
expect(mobileCss).toMatch(/\.quality-view \.view-header\s*\{[\s\S]*?flex-wrap\s*:\s*wrap\s*;/);
|
||||
expect(mobileCss).toMatch(/\.quality-view \.view-header__title\s*\{[\s\S]*?flex\s*:\s*1\s+0\s+100%\s*;/);
|
||||
expect(mobileCss).toMatch(/\.quality-view \.view-header__title\s*\{[\s\S]*?min-width\s*:\s*100%\s*;/);
|
||||
expect(mobileCss).toMatch(/\.quality-view \.view-header__title span\s*\{[\s\S]*?overflow\s*:\s*visible\s*;/);
|
||||
expect(mobileCss).toMatch(/\.quality-view \.view-header__actions\s*\{[\s\S]*?width\s*:\s*100%\s*;/);
|
||||
expect(mobileCss).toMatch(/\.quality-view \.view-header__actions\s*\{[\s\S]*?margin-left\s*:\s*0\s*;/);
|
||||
});
|
||||
});
|
||||
@@ -172,3 +172,32 @@ or bare h2/table inline styles.
|
||||
.quality-header-actions {
|
||||
display: contents;
|
||||
}
|
||||
|
||||
/*
|
||||
FNXC:Quality 2026-07-16-12:45:
|
||||
FN-8131: On mobile, Quality's wide preset and refresh action cluster must give the title its own full-width row and wrap below it instead of shrinking the title to a `Q…` ellipsis or clipping buttons. This mirrors InsightsView FN-7830 while preserving the shared desktop header clamp.
|
||||
*/
|
||||
@media (max-width: 768px), (max-height: 480px) {
|
||||
.quality-view .view-header {
|
||||
align-items: flex-start;
|
||||
flex-wrap: wrap;
|
||||
gap: var(--space-sm) var(--space-md);
|
||||
}
|
||||
|
||||
.quality-view .view-header__title {
|
||||
flex: 1 0 100%;
|
||||
min-width: 100%;
|
||||
}
|
||||
|
||||
.quality-view .view-header__title span {
|
||||
overflow: visible;
|
||||
text-overflow: clip;
|
||||
}
|
||||
|
||||
.quality-view .view-header__actions {
|
||||
justify-content: flex-start;
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user