This commit is contained in:
seb
2026-09-22 07:59:00 +02:00
parent 5e13b8f9cd
commit 51d01a502b
5 changed files with 220 additions and 80 deletions

View File

@@ -1,23 +1,87 @@
import { createContext, useContext, useState, useLayoutEffect } from 'react';
import { createPortal } from 'react-dom';
import Box from '@mui/material/Box';
import Typography from '@mui/material/Typography';
import { GRID_COLUMNS } from 'dashgui/panels';
export const PageTitleRightContext = createContext(null);
export function PageTitleRight({ children }) {
const contextNode = useContext(PageTitleRightContext);
const [domNode, setDomNode] = useState(
() => (typeof document !== 'undefined' ? document.getElementById('page-title-right') : null)
);
useLayoutEffect(() => {
if (!contextNode && typeof document !== 'undefined') {
const el = document.getElementById('page-title-right');
if (el && el !== domNode) {
setDomNode(el);
}
}
}, [contextNode, domNode]);
const target = contextNode || domNode;
if (!target) return null;
return createPortal(children, target);
}
export default function PageLayout({
title,
showTitle = true,
titleAction,
titleRightAction,
titleWide = 3,
children,
}) {
const [rightNode, setRightNode] = useState(null);
return (
<Box sx={{ minWidth: 0 }}>
{showTitle ? (
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1.5, mb: 2 }}>
<Typography variant="h5" sx={{ fontWeight: 700 }}>
{title}
</Typography>
{titleAction}
</Box>
) : null}
{children}
</Box>
<PageTitleRightContext.Provider value={rightNode}>
<Box sx={{ minWidth: 0 }}>
{showTitle ? (
<Box
sx={{
display: 'grid',
gridTemplateColumns: {
xs: '1fr',
sm: 'repeat(2, 1fr)',
md: `repeat(${GRID_COLUMNS}, 1fr)`,
},
gap: 2,
mb: 2,
}}
>
<Box
sx={{
gridColumn: {
xs: '1 / -1',
sm: titleWide >= 2 ? 'span 2' : 'span 1',
md: `span ${Math.min(Math.max(titleWide, 1), GRID_COLUMNS)}`,
},
display: 'flex',
alignItems: 'center',
gap: 1.5,
minWidth: 0,
}}
>
<Typography variant="h5" sx={{ fontWeight: 700 }}>
{title}
</Typography>
{titleAction}
<Box
id="page-title-right"
ref={setRightNode}
sx={{ ml: 'auto', display: 'flex', alignItems: 'center', gap: 1 }}
>
{titleRightAction}
</Box>
</Box>
</Box>
) : null}
{children}
</Box>
</PageTitleRightContext.Provider>
);
}

View File

@@ -1,9 +1,11 @@
import { PureComponent } from 'react';
import Box from '@mui/material/Box';
import Button from '@mui/material/Button';
import CircularProgress from '@mui/material/CircularProgress';
import Typography from '@mui/material/Typography';
import { enqueueSnackbar } from 'notistack';
import BackendError from '../BackendError';
import { PageTitleRight } from '../PageLayout';
import { PanelTile, PanelTileGrid } from 'dashgui/panels';
import { StorageManagerContext } from '../../api/storageManagerContext';
import { requireArray, requireDefined, requireObject } from '../../utils/apiShape';
@@ -473,6 +475,18 @@ class ManifestForm extends PureComponent {
return (
<>
{status === 'ready' && (
<PageTitleRight>
<Button
variant="contained"
size="small"
disabled={saving}
onClick={this.handleSave}
>
{saving ? 'Speichern…' : 'Speichern'}
</Button>
</PageTitleRight>
)}
<PanelTileGrid>
<ManifestHeader
kind={kind}

View File

@@ -101,15 +101,6 @@ class ManifestLines extends PureComponent {
>
Zeile hinzufügen
</Button>
<Box sx={{ flex: 1 }} />
<Button
variant="contained"
size="small"
disabled={saving}
onClick={onSave}
>
{saving ? 'Speichern…' : 'Speichern'}
</Button>
</Box>
</Stack>
</PanelTile>