This commit is contained in:
seb
2026-10-15 00:45:05 +02:00
parent 6e0b72b34b
commit bcd61fcf5e
5 changed files with 145 additions and 73 deletions

View File

@@ -88,9 +88,6 @@ class QuoteRow extends PureComponent {
}
return (
<ListItemButton disabled divider sx={rowSx}>
<Box sx={{ width: 48, height: 24, flexShrink: 0, display: 'flex', alignItems: 'center', gap: 0.5 }}>
<Skeleton variant="rounded" width={18} height={24} />
</Box>
<Box sx={{ width: 120, flexShrink: 0 }}>
<Skeleton variant="text" width={80} height={20} />
<Skeleton variant="text" width={50} height={16} />
@@ -104,6 +101,9 @@ class QuoteRow extends PureComponent {
<Box sx={{ width: 40, flexShrink: 0, display: 'flex', justifyContent: 'center' }}>
<Skeleton variant="rounded" width={28} height={20} />
</Box>
<Box sx={{ width: 76, flexShrink: 0, display: 'flex', alignItems: 'center', gap: '3px' }}>
<Skeleton variant="rounded" width={15} height={20} />
</Box>
<Box sx={{ width: 96, flexShrink: 0, display: 'flex', justifyContent: 'flex-end' }}>
<Skeleton variant="text" width={60} height={20} />
</Box>
@@ -121,75 +121,6 @@ class QuoteRow extends PureComponent {
return (
<ListItemButton divider sx={rowSx} onClick={() => onOpen?.(quote)}>
{/* Document SkeleHash / PDF Previews (one small icon per file) */}
<Box
sx={{
width: 48,
flexShrink: 0,
display: 'flex',
alignItems: 'center',
gap: 0.5,
}}
>
{files.map((file, index) => {
const fileId = file.fileId ?? file.id;
const title = file.name ? `${file.name} (Öffnen)` : 'Datei öffnen';
return (
<Tooltip key={file.id ?? fileId ?? index} title={title}>
<Box
role="button"
tabIndex={0}
onClick={(e) => {
e.stopPropagation();
if (quote.id != null && fileId != null) {
window.open(`/api/quote/${encodeURIComponent(quote.id)}/file/${encodeURIComponent(fileId)}`, '_blank');
} else {
onOpen?.(quote);
}
}}
onKeyDown={(e) => {
if (e.key === 'Enter' || e.key === ' ') {
e.stopPropagation();
e.preventDefault();
if (quote.id != null && fileId != null) {
window.open(`/api/quote/${encodeURIComponent(quote.id)}/file/${encodeURIComponent(fileId)}`, '_blank');
}
}
}}
sx={{
width: 18,
height: 24,
flexShrink: 0,
borderRadius: 0.5,
overflow: 'hidden',
bgcolor: 'background.paper',
border: '1px solid',
borderColor: 'divider',
boxShadow: '0 1px 2px rgba(0,0,0,0.08)',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
cursor: 'pointer',
transition: 'transform 120ms ease, box-shadow 120ms ease, border-color 120ms ease',
'&:hover': {
boxShadow: '0 2px 6px rgba(0,0,0,0.22)',
borderColor: 'primary.main',
transform: 'scale(1.2)',
zIndex: 2,
},
}}
>
{file.skeledash ? (
<SkeleHashImage hash={file.skeledash} />
) : (
<PictureAsPdfIcon sx={{ fontSize: 13, color: 'error.main' }} />
)}
</Box>
</Tooltip>
);
})}
</Box>
<Box sx={{ width: 120, flexShrink: 0, minWidth: 0 }}>
<Typography variant="body1" sx={{ fontWeight: 600, ...ellipsisSx }}>
{quote.number}
@@ -228,6 +159,78 @@ class QuoteRow extends PureComponent {
}}
/>
{/* Files / Attachments column after Pos.: space for 4 per row, 2 lines max */}
<Box
sx={{
width: 76,
flexShrink: 0,
display: 'flex',
flexWrap: 'wrap',
alignContent: 'center',
gap: '3px',
maxHeight: 44,
overflow: 'hidden',
}}
>
{files.slice(0, 8).map((file, index) => {
const fileId = file.fileId ?? file.id;
const title = file.name ? `${file.name} (Öffnen)` : 'Datei öffnen';
return (
<Tooltip key={file.id ?? fileId ?? index} title={title}>
<Box
role="button"
tabIndex={0}
onClick={(e) => {
e.stopPropagation();
if (quote.id != null && fileId != null) {
window.open(`/api/quote/${encodeURIComponent(quote.id)}/file/${encodeURIComponent(fileId)}`, '_blank');
} else {
onOpen?.(quote);
}
}}
onKeyDown={(e) => {
if (e.key === 'Enter' || e.key === ' ') {
e.stopPropagation();
e.preventDefault();
if (quote.id != null && fileId != null) {
window.open(`/api/quote/${encodeURIComponent(quote.id)}/file/${encodeURIComponent(fileId)}`, '_blank');
}
}
}}
sx={{
width: 15,
height: 20,
flexShrink: 0,
borderRadius: 0.5,
overflow: 'hidden',
bgcolor: 'background.paper',
border: '1px solid',
borderColor: 'divider',
boxShadow: '0 1px 2px rgba(0,0,0,0.08)',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
cursor: 'pointer',
transition: 'transform 120ms ease, box-shadow 120ms ease, border-color 120ms ease',
'&:hover': {
boxShadow: '0 2px 6px rgba(0,0,0,0.25)',
borderColor: 'primary.main',
transform: 'scale(1.3)',
zIndex: 3,
},
}}
>
{file.skeledash ? (
<SkeleHashImage hash={file.skeledash} />
) : (
<PictureAsPdfIcon sx={{ fontSize: 11, color: 'error.main' }} />
)}
</Box>
</Tooltip>
);
})}
</Box>
<Typography
variant="body2"
sx={{ width: 96, flexShrink: 0, textAlign: 'right', fontWeight: 600, fontVariantNumeric: 'tabular-nums' }}
@@ -590,11 +593,11 @@ export class QuoteList extends PureComponent {
userSelect: 'none',
}}
>
<Box sx={{ width: 48, flexShrink: 0 }} />
<Box sx={{ width: 120, flexShrink: 0 }}>Nr. / Ref.</Box>
<Box sx={{ width: 100, flexShrink: 0 }}>Datum</Box>
<Box sx={{ flex: 1, minWidth: 0 }}>Kunde</Box>
<Box sx={{ width: 40, flexShrink: 0, textAlign: 'center' }}>Pos.</Box>
<Box sx={{ width: 76, flexShrink: 0, textAlign: 'center' }}>Dateien</Box>
<Box sx={{ width: 96, flexShrink: 0, textAlign: 'right' }}>Gesamt</Box>
<Box sx={{ width: 40, flexShrink: 0 }} />
</Box>