fix(ui): stack detail-page header action buttons one-per-row on mobile

Detail-page headers put their action buttons in a flex row with
flexWrap:"wrap", so on a phone the 2-4 buttons (Potvrzení / Zahájit
realizaci / Smazat, etc.) wrapped into a ragged grid.

New shared `headerActionsSx` (ui/PageHeader): on xs it's a full-width
column (each button its own full-width row); from sm up it's the usual
right-aligned wrapping row — desktop unchanged. A StatusChip kept in the
same group stays its natural size (alignSelf) instead of stretching.

Applied to PageHeader's own actions slot and every detail-page header
action group: Order/Offer/Invoice (both views)/Project + the Warehouse
Receipt/Issue/Item/Inventory detail headers.

Verified in Chrome at 430px on OrderDetail: the group is flexDirection
column with all three buttons at the same x, full-width, stacked. tsc -b
--noEmit, npm run build, vitest 152/152 clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
BOHA
2026-06-07 21:44:22 +02:00
parent 54f3c414f5
commit decadd895e
10 changed files with 41 additions and 59 deletions

View File

@@ -64,6 +64,7 @@ import {
LoadingState,
PageEnter,
RichTextView,
headerActionsSx,
} from "../ui";
const API_BASE = "/api/admin";
@@ -1114,14 +1115,7 @@ export default function InvoiceDetail() {
/>
</Box>
</Box>
<Box
sx={{
display: "flex",
alignItems: "center",
gap: 1,
flexWrap: "wrap",
}}
>
<Box sx={headerActionsSx}>
{hasPermission("invoices.export") && (
<Button
onClick={() => handleViewPdf(invoice.language || "cs")}
@@ -1660,14 +1654,7 @@ export default function InvoiceDetail() {
)}
</Box>
</Box>
<Box
sx={{
display: "flex",
alignItems: "center",
gap: 1,
flexWrap: "wrap",
}}
>
<Box sx={headerActionsSx}>
{isEdit && invoice && hasPermission("invoices.export") && (
<Button
onClick={() => handleViewPdf(invoice.language || "cs")}

View File

@@ -74,6 +74,7 @@ import {
EmptyState,
LoadingState,
PageEnter,
headerActionsSx,
} from "../ui";
const API_BASE = "/api/admin";
@@ -1118,14 +1119,7 @@ export default function OfferDetail() {
{isCompleted && <StatusChip label="Dokončeno" color="success" />}
</Box>
</Box>
<Box
sx={{
display: "flex",
alignItems: "center",
gap: 1,
flexWrap: "wrap",
}}
>
<Box sx={headerActionsSx}>
{isEdit && hasPermission("offers.export") && (
<Button
onClick={handlePdf}

View File

@@ -32,6 +32,7 @@ import {
LoadingState,
PageEnter,
RichTextView,
headerActionsSx,
type DataColumn,
} from "../ui";
@@ -424,14 +425,7 @@ export default function OrderDetail() {
/>
</Box>
</Box>
<Box
sx={{
display: "flex",
alignItems: "center",
gap: 1,
flexWrap: "wrap",
}}
>
<Box sx={headerActionsSx}>
{order.invoice ? (
<Button
component={RouterLink}

View File

@@ -29,6 +29,7 @@ import {
ConfirmDialog,
LoadingState,
PageEnter,
headerActionsSx,
} from "../ui";
const API_BASE = "/api/admin";
@@ -320,14 +321,7 @@ export default function ProjectDetail() {
</Box>
</Box>
{canEdit && (
<Box
sx={{
display: "flex",
alignItems: "center",
gap: 1,
flexWrap: "wrap",
}}
>
<Box sx={headerActionsSx}>
<Button onClick={handleSave} disabled={saving}>
{saving ? "Ukládání..." : "Uložit"}
</Button>

View File

@@ -24,6 +24,7 @@ import {
PageHeader,
PageEnter,
ConfirmDialog,
headerActionsSx,
type DataColumn,
} from "../ui";
@@ -192,7 +193,7 @@ export default function WarehouseInventoryDetail() {
<PageHeader
title={s.session_number || "Inventura"}
actions={
<Box sx={{ display: "flex", alignItems: "center", gap: 1 }}>
<Box sx={headerActionsSx}>
<Button
component={RouterLink}
to="/warehouse/inventory"

View File

@@ -24,6 +24,7 @@ import {
PageHeader,
ConfirmDialog,
PageEnter,
headerActionsSx,
type DataColumn,
} from "../ui";
@@ -233,7 +234,7 @@ export default function WarehouseIssueDetail() {
: undefined
}
actions={
<Box sx={{ display: "flex", alignItems: "center", gap: 1 }}>
<Box sx={headerActionsSx}>
<Button
component={RouterLink}
to="/warehouse/issues"

View File

@@ -29,6 +29,7 @@ import {
PageHeader,
ConfirmDialog,
PageEnter,
headerActionsSx,
type DataColumn,
} from "../ui";
@@ -233,7 +234,7 @@ export default function WarehouseItemDetail() {
// Edit / view mode action buttons
const headerActions = canManage ? (
<Box sx={{ display: "flex", gap: 1 }}>
<Box sx={headerActionsSx}>
{editing || isNew ? (
<>
{!isNew && (
@@ -362,7 +363,7 @@ export default function WarehouseItemDetail() {
title={title}
subtitle={subtitle}
actions={
<Box sx={{ display: "flex", alignItems: "center", gap: 1 }}>
<Box sx={headerActionsSx}>
<Button
component={RouterLink}
to="/warehouse/items"

View File

@@ -26,6 +26,7 @@ import {
PageHeader,
ConfirmDialog,
PageEnter,
headerActionsSx,
type DataColumn,
} from "../ui";
@@ -301,7 +302,7 @@ export default function WarehouseReceiptDetail() {
title={r.receipt_number || "Nový doklad"}
subtitle={r.supplier?.name}
actions={
<Box sx={{ display: "flex", alignItems: "center", gap: 1 }}>
<Box sx={headerActionsSx}>
<Button
component={RouterLink}
to="/warehouse/receipts"