This commit is contained in:
seb
2026-10-21 11:54:46 +02:00
parent a32ea19b5e
commit 985f4a3da2
27 changed files with 139 additions and 53 deletions

View File

@@ -228,7 +228,9 @@ class SearchResultRow extends PureComponent {
{' · '} {' · '}
</> </>
)} )}
{article.sku} <Box component="span" sx={{ fontFamily: 'monospace' }}>
{article.sku}
</Box>
{article.stock != null && ( {article.stock != null && (
<> <>
{' · '} {' · '}
@@ -781,16 +783,17 @@ export default class ArticleSearch extends PureComponent {
<Box sx={{ flex: 1, minWidth: 0 }}> <Box sx={{ flex: 1, minWidth: 0 }}>
<Box sx={{ display: 'flex', alignItems: 'center', gap: 0.75 }}> <Box sx={{ display: 'flex', alignItems: 'center', gap: 0.75 }}>
<Chip <Chip
size="small" size="small"
label={article.sku} label={article.sku}
sx={{ sx={{
height: 18, height: 18,
fontSize: '0.68rem', fontSize: '0.68rem',
fontWeight: 600, fontWeight: 600,
bgcolor: 'action.hover', fontFamily: 'monospace',
}} bgcolor: 'action.hover',
/> }}
/>
<Typography variant="body2" fontWeight={600} noWrap sx={{ flex: 1 }}> <Typography variant="body2" fontWeight={600} noWrap sx={{ flex: 1 }}>
{article.name || '–'} {article.name || '–'}
</Typography> </Typography>

View File

@@ -358,7 +358,7 @@ export default class ArticleStockAdjustDialog extends PureComponent {
}} }}
> >
<Typography variant="caption" color="text.secondary" display="block"> <Typography variant="caption" color="text.secondary" display="block">
Artikel ({article?.sku}) Artikel (<Box component="span" sx={{ fontFamily: 'monospace' }}>{article?.sku}</Box>)
</Typography> </Typography>
<Typography variant="subtitle2" sx={{ fontWeight: 600 }}> <Typography variant="subtitle2" sx={{ fontWeight: 600 }}>
{article?.name || '–'} {article?.name || '–'}

View File

@@ -152,7 +152,7 @@ export default class ArticleViewEANs extends PureComponent {
return ( return (
<EditablePanelTile <EditablePanelTile
title={articleData.sku} title={<Box component="span" sx={{ fontFamily: 'monospace' }}>{articleData.sku}</Box>}
wide={1} wide={1}
minHeight={SECOND_ROW_MIN_HEIGHT} minHeight={SECOND_ROW_MIN_HEIGHT}
color={BORDER} color={BORDER}

View File

@@ -875,6 +875,7 @@ export default class ArticleViewLists extends PureComponent {
to={artikelDetailPath(item.sku)} to={artikelDetailPath(item.sku)}
sx={{ sx={{
fontSize: '0.72rem', fontSize: '0.72rem',
fontFamily: 'monospace',
color: 'text.secondary', color: 'text.secondary',
textDecoration: 'none', textDecoration: 'none',
'&:hover': { textDecoration: 'underline' }, '&:hover': { textDecoration: 'underline' },
@@ -1085,6 +1086,7 @@ export default class ArticleViewLists extends PureComponent {
to={artikelDetailPath(opt.sku)} to={artikelDetailPath(opt.sku)}
sx={{ sx={{
fontSize: '0.72rem', fontSize: '0.72rem',
fontFamily: 'monospace',
color: 'text.secondary', color: 'text.secondary',
textDecoration: 'none', textDecoration: 'none',
'&:hover': { textDecoration: 'underline' }, '&:hover': { textDecoration: 'underline' },

View File

@@ -165,6 +165,7 @@ class Kunde extends PureComponent {
height: 24, height: 24,
fontSize: '0.75rem', fontSize: '0.75rem',
fontWeight: 600, fontWeight: 600,
fontFamily: 'monospace',
fontVariantNumeric: 'tabular-nums', fontVariantNumeric: 'tabular-nums',
bgcolor: 'action.hover', bgcolor: 'action.hover',
color: 'text.primary', color: 'text.primary',

View File

@@ -130,7 +130,7 @@ export default class ArticleSearchDialog extends PureComponent {
<Typography variant="caption" color="text.secondary"> <Typography variant="caption" color="text.secondary">
{line ? ( {line ? (
<> <>
{isDelivery ? 'Lieferanten-ArtNr' : 'ArtNr'}: <strong>{rawSku || '–'}</strong> {isDelivery ? 'Lieferanten-ArtNr' : 'ArtNr'}: <strong style={{ fontFamily: 'monospace' }}>{rawSku || '–'}</strong>
{line?.name ? ` · ${line.name}` : ''} {line?.name ? ` · ${line.name}` : ''}
</> </>
) : isDelivery ? ( ) : isDelivery ? (

View File

@@ -780,7 +780,16 @@ export default class BookDeliveryDialog extends PureComponent {
{prefillLine && ( {prefillLine && (
<Alert severity="info" sx={{ mb: 2 }}> <Alert severity="info" sx={{ mb: 2 }}>
Vorausgewählt zum Verbuchen: Position{' '} Vorausgewählt zum Verbuchen: Position{' '}
<strong>{prefillLine.sku ? `ArtNr ${prefillLine.sku}` : prefillLine.name}</strong> ({amountsToBook[prefillLine.id] || 0} Stk.). Andere Positionen stehen auf 0. {prefillLine.sku ? (
<>
{'ArtNr '}
<Box component="span" sx={{ fontFamily: 'monospace', fontWeight: 700 }}>
{prefillLine.sku}
</Box>
</>
) : (
<strong>{prefillLine.name}</strong>
)} ({amountsToBook[prefillLine.id] || 0} Stk.). Andere Positionen stehen auf 0.
</Alert> </Alert>
)} )}
{this.renderLinesTable()} {this.renderLinesTable()}

View File

@@ -122,8 +122,8 @@ function renderInvisibleDummyRow(dummy) {
return ( return (
<> <>
<Box aria-hidden sx={{ gridColumn: 1, gridRow: 1, whiteSpace: 'nowrap', ...measuringCellSx }}> <Box aria-hidden sx={{ gridColumn: 1, gridRow: 1, whiteSpace: 'nowrap', ...measuringCellSx }}>
<Typography variant="body1" sx={{ fontWeight: 600 }}>{d.number}</Typography> <Typography variant="body1" sx={{ fontWeight: 600, fontFamily: 'monospace' }}>{d.number}</Typography>
<Typography variant="body2">{d.externalNumber || 'Nr. / Ref.'}</Typography> <Typography variant="body2" sx={{ fontFamily: 'monospace' }}>{d.externalNumber || 'Nr. / Ref.'}</Typography>
</Box> </Box>
<Box aria-hidden sx={{ gridColumn: 2, gridRow: 1, whiteSpace: 'nowrap', ...measuringCellSx }}> <Box aria-hidden sx={{ gridColumn: 2, gridRow: 1, whiteSpace: 'nowrap', ...measuringCellSx }}>
<Typography variant="body2">{d.date ? formatDate(d.date) : '–'}</Typography> <Typography variant="body2">{d.date ? formatDate(d.date) : '–'}</Typography>
@@ -241,10 +241,10 @@ class DeliveryRow extends Component {
{renderInvisibleDummyRow(dummy)} {renderInvisibleDummyRow(dummy)}
<Box sx={{ gridColumn: 1, gridRow: 2, minWidth: 0, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}> <Box sx={{ gridColumn: 1, gridRow: 2, minWidth: 0, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
<Typography variant="body1" sx={{ fontWeight: 600, ...ellipsisSx }}> <Typography variant="body1" sx={{ fontWeight: 600, fontFamily: 'monospace', ...ellipsisSx }}>
{delivery.number} {delivery.number}
</Typography> </Typography>
<Typography variant="body2" color="text.secondary" sx={ellipsisSx}> <Typography variant="body2" color="text.secondary" sx={{ fontFamily: 'monospace', ...ellipsisSx }}>
{numberDisplay(delivery.externalNumber)} {numberDisplay(delivery.externalNumber)}
</Typography> </Typography>
</Box> </Box>

View File

@@ -392,7 +392,7 @@ class ManifestFormLine extends PureComponent {
slotProps={{ slotProps={{
htmlInput: { htmlInput: {
inputMode: type === 'number' ? 'decimal' : 'text', inputMode: type === 'number' ? 'decimal' : 'text',
style: { textAlign: align }, style: { textAlign: align, ...(id === 'sku' ? { fontFamily: 'monospace' } : {}) },
autoComplete: 'off', autoComplete: 'off',
step: type === 'number' ? 'any' : undefined, step: type === 'number' ? 'any' : undefined,
}, },
@@ -544,6 +544,7 @@ class ManifestFormLine extends PureComponent {
fontSize: '0.875rem', fontSize: '0.875rem',
lineHeight: '20px', lineHeight: '20px',
fontWeight: id === 'sku' ? 600 : 400, fontWeight: id === 'sku' ? 600 : 400,
fontFamily: id === 'sku' ? 'monospace' : 'inherit',
color: isError color: isError
? 'error.main' ? 'error.main'
: hasValue : hasValue
@@ -751,6 +752,7 @@ class ManifestFormLine extends PureComponent {
height: 20, height: 20,
fontSize: '0.7rem', fontSize: '0.7rem',
fontWeight: 600, fontWeight: 600,
fontFamily: 'monospace',
bgcolor: 'primary.50', bgcolor: 'primary.50',
color: 'primary.dark', color: 'primary.dark',
border: '1px solid', border: '1px solid',
@@ -1108,6 +1110,7 @@ class ManifestFormLine extends PureComponent {
height: 20, height: 20,
fontSize: '0.7rem', fontSize: '0.7rem',
fontWeight: 600, fontWeight: 600,
fontFamily: 'monospace',
bgcolor: 'primary.50', bgcolor: 'primary.50',
color: 'primary.dark', color: 'primary.dark',
border: '1px solid', border: '1px solid',
@@ -1150,7 +1153,7 @@ class ManifestFormLine extends PureComponent {
{/* Supplier SKU if distinct */} {/* Supplier SKU if distinct */}
{supplierArticle.sku && supplierArticle.sku !== rawSku && supplierArticle.sku !== article.sku && ( {supplierArticle.sku && supplierArticle.sku !== rawSku && supplierArticle.sku !== article.sku && (
<Typography variant="caption" color="text.secondary" sx={{ fontSize: '0.7rem' }}> <Typography variant="caption" color="text.secondary" sx={{ fontSize: '0.7rem' }}>
(Lief.-ArtNr: <strong>{supplierArticle.sku}</strong>) (Lief.-ArtNr: <strong style={{ fontFamily: 'monospace' }}>{supplierArticle.sku}</strong>)
</Typography> </Typography>
)} )}

View File

@@ -479,9 +479,13 @@ class ManifestHeader extends PureComponent {
sx={{ sx={{
flex: { xs: '1 1 100%', sm: '1 1 120px' }, flex: { xs: '1 1 100%', sm: '1 1 120px' },
minWidth: { sm: 100 }, minWidth: { sm: 100 },
'& .MuiInputBase-input': {
fontFamily: 'monospace',
},
...(!number && previewNumber && { ...(!number && previewNumber && {
'& .MuiInputBase-input.Mui-disabled': { '& .MuiInputBase-input.Mui-disabled': {
fontStyle: 'italic', fontStyle: 'italic',
fontFamily: 'monospace',
}, },
}), }),
}} }}
@@ -496,6 +500,9 @@ class ManifestHeader extends PureComponent {
sx={{ sx={{
flex: { xs: '1 1 100%', sm: '1 1 120px' }, flex: { xs: '1 1 100%', sm: '1 1 120px' },
minWidth: { sm: 100 }, minWidth: { sm: 100 },
'& .MuiInputBase-input': {
fontFamily: 'monospace',
},
...(dirtyFields?.externalNumber && { ...(dirtyFields?.externalNumber && {
'& .MuiOutlinedInput-notchedOutline': { '& .MuiOutlinedInput-notchedOutline': {
borderColor: 'warning.main', borderColor: 'warning.main',

View File

@@ -131,11 +131,12 @@ class ManifestList extends PureComponent {
const cfg = this.cfg; const cfg = this.cfg;
const partyField = cfg.partyField; const partyField = cfg.partyField;
const columns = [{ key: 'number', label: 'Nummer' }]; const columns = [{ key: 'number', label: 'Nummer', mono: true }];
if (cfg.externalNumber) { if (cfg.externalNumber) {
columns.push({ columns.push({
key: 'externalNumber', key: 'externalNumber',
label: 'Referenz', label: 'Referenz',
mono: true,
render: (row) => numberDisplay(row.externalNumber), render: (row) => numberDisplay(row.externalNumber),
}); });
} }

View File

@@ -109,7 +109,7 @@ export class OrderDocumentsTiles extends PureComponent {
}} }}
> >
<Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', mb: 0.25 }}> <Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', mb: 0.25 }}>
<Typography variant="subtitle2" sx={{ fontWeight: 700, fontSize: '0.85rem' }}> <Typography variant="subtitle2" sx={{ fontWeight: 700, fontSize: '0.85rem', fontFamily: 'monospace' }}>
{sh.number} {sh.number}
</Typography> </Typography>
<Stack direction="row" spacing={0.5} sx={{ alignItems: 'center' }}> <Stack direction="row" spacing={0.5} sx={{ alignItems: 'center' }}>
@@ -134,7 +134,7 @@ export class OrderDocumentsTiles extends PureComponent {
{sh.externalNumber ? ( {sh.externalNumber ? (
<Typography variant="caption" color="text.secondary" sx={{ display: 'block', mb: 0.25 }}> <Typography variant="caption" color="text.secondary" sx={{ display: 'block', mb: 0.25 }}>
Ref: {sh.externalNumber} Ref: <Box component="span" sx={{ fontFamily: 'monospace' }}>{sh.externalNumber}</Box>
</Typography> </Typography>
) : null} ) : null}

View File

@@ -103,8 +103,8 @@ function renderInvisibleDummyRow(dummy) {
return ( return (
<> <>
<Box aria-hidden sx={{ gridColumn: 1, gridRow: 1, whiteSpace: 'nowrap', ...measuringCellSx }}> <Box aria-hidden sx={{ gridColumn: 1, gridRow: 1, whiteSpace: 'nowrap', ...measuringCellSx }}>
<Typography variant="body1" sx={{ fontWeight: 600 }}>{d.number}</Typography> <Typography variant="body1" sx={{ fontWeight: 600, fontFamily: 'monospace' }}>{d.number}</Typography>
<Typography variant="body2">{d.externalNumber || 'Nr. / Ref.'}</Typography> <Typography variant="body2" sx={{ fontFamily: 'monospace' }}>{d.externalNumber || 'Nr. / Ref.'}</Typography>
</Box> </Box>
<Box aria-hidden sx={{ gridColumn: 2, gridRow: 1, whiteSpace: 'nowrap', ...measuringCellSx }}> <Box aria-hidden sx={{ gridColumn: 2, gridRow: 1, whiteSpace: 'nowrap', ...measuringCellSx }}>
<Typography variant="body2">{d.date ? formatDate(d.date) : '–'}</Typography> <Typography variant="body2">{d.date ? formatDate(d.date) : '–'}</Typography>
@@ -200,10 +200,10 @@ class OrderRow extends PureComponent {
{renderInvisibleDummyRow(dummy)} {renderInvisibleDummyRow(dummy)}
<Box sx={{ gridColumn: 1, gridRow: 2, minWidth: 0, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}> <Box sx={{ gridColumn: 1, gridRow: 2, minWidth: 0, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
<Typography variant="body1" sx={{ fontWeight: 600, ...ellipsisSx }}> <Typography variant="body1" sx={{ fontWeight: 600, fontFamily: 'monospace', ...ellipsisSx }}>
{order.number} {order.number}
</Typography> </Typography>
<Typography variant="body2" color="text.secondary" sx={ellipsisSx}> <Typography variant="body2" color="text.secondary" sx={{ fontFamily: 'monospace', ...ellipsisSx }}>
{numberDisplay(order.externalNumber)} {numberDisplay(order.externalNumber)}
</Typography> </Typography>
</Box> </Box>

View File

@@ -99,7 +99,7 @@ class PaymentTableRow extends PureComponent {
<ListItemButton divider sx={rowSx} onClick={() => onNavigateOrder?.(payment.orderId)}> <ListItemButton divider sx={rowSx} onClick={() => onNavigateOrder?.(payment.orderId)}>
{/* Payment ID from payment table */} {/* Payment ID from payment table */}
<Box sx={{ width: 80, flexShrink: 0 }}> <Box sx={{ width: 80, flexShrink: 0 }}>
<Chip size="small" label={`#${payment.id}`} sx={{ fontWeight: 700, fontVariantNumeric: 'tabular-nums' }} /> <Chip size="small" label={`#${payment.id}`} sx={{ fontWeight: 700, fontVariantNumeric: 'tabular-nums', fontFamily: 'monospace' }} />
</Box> </Box>
{/* Amount */} {/* Amount */}
@@ -126,7 +126,7 @@ class PaymentTableRow extends PureComponent {
{/* Linked Manifest (Auftrag) */} {/* Linked Manifest (Auftrag) */}
<Box sx={{ width: 120, flexShrink: 0 }}> <Box sx={{ width: 120, flexShrink: 0 }}>
<Typography variant="body2" sx={{ fontWeight: 600, color: 'primary.main', ...ellipsisSx }}> <Typography variant="body2" sx={{ fontWeight: 600, color: 'primary.main', fontFamily: 'monospace', ...ellipsisSx }}>
{payment.orderNumber} {payment.orderNumber}
</Typography> </Typography>
</Box> </Box>

View File

@@ -435,7 +435,7 @@ export default class OrderShipmentDialog extends PureComponent {
</Typography> </Typography>
{orderNumber ? ( {orderNumber ? (
<Typography variant="caption" color="text.secondary"> <Typography variant="caption" color="text.secondary">
Zu: <strong>{orderNumber}</strong> Zu: <strong style={{ fontFamily: 'monospace' }}>{orderNumber}</strong>
</Typography> </Typography>
) : null} ) : null}
</Box> </Box>
@@ -486,7 +486,7 @@ export default class OrderShipmentDialog extends PureComponent {
readOnly: true, readOnly: true,
}, },
}} }}
sx={{ minWidth: 190 }} sx={{ minWidth: 190, '& .MuiInputBase-input': { fontFamily: 'monospace' } }}
/> />
<TextField <TextField
size="small" size="small"
@@ -495,6 +495,7 @@ export default class OrderShipmentDialog extends PureComponent {
disabled={saving} disabled={saving}
onChange={(e) => this.setState({ externalNumber: e.target.value })} onChange={(e) => this.setState({ externalNumber: e.target.value })}
fullWidth fullWidth
slotProps={{ input: { sx: { fontFamily: 'monospace' } } }}
/> />
</Stack> </Stack>
@@ -549,7 +550,7 @@ export default class OrderShipmentDialog extends PureComponent {
onChange={() => this.handleToggleItem(item.itemKey, item.remaining)} onChange={() => this.handleToggleItem(item.itemKey, item.remaining)}
/> />
</TableCell> </TableCell>
<TableCell sx={{ fontWeight: 600 }}>{item.sku || '–'}</TableCell> <TableCell sx={{ fontWeight: 600, fontFamily: 'monospace' }}>{item.sku || '–'}</TableCell>
<TableCell> <TableCell>
<Typography variant="body2" sx={{ fontWeight: 500 }}> <Typography variant="body2" sx={{ fontWeight: 500 }}>
{item.name || '–'} {item.name || '–'}

View File

@@ -279,6 +279,7 @@ export default class PartyFilterPanel extends PureComponent {
sx: { sx: {
color: isSelected ? 'inherit' : 'text.secondary', color: isSelected ? 'inherit' : 'text.secondary',
opacity: isSelected ? 0.8 : 1, opacity: isSelected ? 0.8 : 1,
fontFamily: 'monospace',
}, },
}, },
}} }}

View File

@@ -117,7 +117,7 @@ function renderInvisibleDummyRow(dummy) {
return ( return (
<> <>
<Box aria-hidden sx={{ gridColumn: 1, gridRow: 1, whiteSpace: 'nowrap', ...measuringCellSx }}> <Box aria-hidden sx={{ gridColumn: 1, gridRow: 1, whiteSpace: 'nowrap', ...measuringCellSx }}>
<Typography variant="body1" sx={{ fontWeight: 600 }}>{d.number}</Typography> <Typography variant="body1" sx={{ fontWeight: 600, fontFamily: 'monospace' }}>{d.number}</Typography>
</Box> </Box>
<Box aria-hidden sx={{ gridColumn: 2, gridRow: 1, whiteSpace: 'nowrap', ...measuringCellSx }}> <Box aria-hidden sx={{ gridColumn: 2, gridRow: 1, whiteSpace: 'nowrap', ...measuringCellSx }}>
<Typography variant="body2">{d.date ? formatDate(d.date) : '–'}</Typography> <Typography variant="body2">{d.date ? formatDate(d.date) : '–'}</Typography>
@@ -209,7 +209,7 @@ class QuoteRow extends PureComponent {
{renderInvisibleDummyRow(dummy)} {renderInvisibleDummyRow(dummy)}
<Box sx={{ gridColumn: 1, gridRow: 2, minWidth: 0, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}> <Box sx={{ gridColumn: 1, gridRow: 2, minWidth: 0, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
<Typography variant="body1" sx={{ fontWeight: 600, ...ellipsisSx }}> <Typography variant="body1" sx={{ fontWeight: 600, fontFamily: 'monospace', ...ellipsisSx }}>
{quote.number} {quote.number}
</Typography> </Typography>
</Box> </Box>

View File

@@ -429,12 +429,19 @@ export default class ShipmentDetailDialog extends PureComponent {
<Stack direction="row" spacing={1.5} sx={{ alignItems: 'center' }}> <Stack direction="row" spacing={1.5} sx={{ alignItems: 'center' }}>
<LocalShippingIcon color="primary" sx={{ fontSize: 28 }} /> <LocalShippingIcon color="primary" sx={{ fontSize: 28 }} />
<Box> <Box>
<Typography variant="h6" sx={{ fontWeight: 700, lineHeight: 1.2 }}> <Typography variant="h6" sx={{ fontWeight: 700, lineHeight: 1.2, fontFamily: 'monospace' }}>
{shipment.number || 'Lieferschein'} {shipment.number || 'Lieferschein'}
</Typography> </Typography>
<Typography variant="caption" color="text.secondary"> <Typography variant="caption" color="text.secondary">
{shipment.date ? `Datum: ${formatDate(shipment.date)}` : ''} {shipment.date ? `Datum: ${formatDate(shipment.date)}` : ''}
{shipment.externalNumber ? ` • Ref: ${shipment.externalNumber}` : ''} {shipment.externalNumber ? (
<>
{' • Ref: '}
<Box component="span" sx={{ fontFamily: 'monospace' }}>
{shipment.externalNumber}
</Box>
</>
) : ''}
</Typography> </Typography>
</Box> </Box>
</Stack> </Stack>
@@ -476,7 +483,7 @@ export default class ShipmentDetailDialog extends PureComponent {
) : ( ) : (
shLines.map((line, idx) => ( shLines.map((line, idx) => (
<TableRow key={line.id || idx}> <TableRow key={line.id || idx}>
<TableCell sx={{ py: 0.75, fontWeight: 500 }}>{line.sku}</TableCell> <TableCell sx={{ py: 0.75, fontWeight: 500, fontFamily: 'monospace' }}>{line.sku}</TableCell>
<TableCell sx={{ py: 0.75 }}>{line.name || '–'}</TableCell> <TableCell sx={{ py: 0.75 }}>{line.name || '–'}</TableCell>
<TableCell align="right" sx={{ py: 0.75, fontWeight: 700 }}> <TableCell align="right" sx={{ py: 0.75, fontWeight: 700 }}>
{line.amount} {line.amount}

View File

@@ -247,7 +247,7 @@ class NewShipmentModal extends PureComponent {
size="small" size="small"
value={getNextShipmentNumber(currentOrder.number, currentOrder.shipments)} value={getNextShipmentNumber(currentOrder.number, currentOrder.shipments)}
disabled disabled
slotProps={{ input: { readOnly: true } }} slotProps={{ input: { readOnly: true, sx: { fontFamily: 'monospace' } } }}
sx={{ width: 190 }} sx={{ width: 190 }}
/> />
) : null} ) : null}
@@ -256,6 +256,7 @@ class NewShipmentModal extends PureComponent {
size="small" size="small"
value={externalNumber} value={externalNumber}
onChange={(e) => this.setState({ externalNumber: e.target.value })} onChange={(e) => this.setState({ externalNumber: e.target.value })}
slotProps={{ input: { sx: { fontFamily: 'monospace' } } }}
sx={{ flex: 1 }} sx={{ flex: 1 }}
/> />
</Box> </Box>
@@ -264,7 +265,7 @@ class NewShipmentModal extends PureComponent {
{currentOrder && ( {currentOrder && (
<Box sx={{ mb: 2.5 }}> <Box sx={{ mb: 2.5 }}>
<Typography variant="subtitle2" sx={{ fontWeight: 600, mb: 1 }}> <Typography variant="subtitle2" sx={{ fontWeight: 600, mb: 1 }}>
Lieferbare Positionen für Auftrag {currentOrder.number}: Lieferbare Positionen für Auftrag <Box component="span" sx={{ fontFamily: 'monospace' }}>{currentOrder.number}</Box>:
</Typography> </Typography>
<Stack spacing={1}> <Stack spacing={1}>
{lines.map((line, idx) => { {lines.map((line, idx) => {
@@ -488,14 +489,14 @@ function renderInvisibleDummyRow(dummy) {
return ( return (
<> <>
<Box aria-hidden sx={{ gridColumn: 1, gridRow: 1, whiteSpace: 'nowrap', ...measuringCellSx }}> <Box aria-hidden sx={{ gridColumn: 1, gridRow: 1, whiteSpace: 'nowrap', ...measuringCellSx }}>
<Typography variant="body1" sx={{ fontWeight: 600 }}>{d.number}</Typography> <Typography variant="body1" sx={{ fontWeight: 600, fontFamily: 'monospace' }}>{d.number}</Typography>
<Typography variant="body2">{d.externalNumber || 'Nr. / Ref.'}</Typography> <Typography variant="body2" sx={{ fontFamily: 'monospace' }}>{d.externalNumber || 'Nr. / Ref.'}</Typography>
</Box> </Box>
<Box aria-hidden sx={{ gridColumn: 2, gridRow: 1, whiteSpace: 'nowrap', ...measuringCellSx }}> <Box aria-hidden sx={{ gridColumn: 2, gridRow: 1, whiteSpace: 'nowrap', ...measuringCellSx }}>
<Typography variant="body2">{d.date ? formatDate(d.date) : '–'}</Typography> <Typography variant="body2">{d.date ? formatDate(d.date) : '–'}</Typography>
</Box> </Box>
<Box aria-hidden sx={{ gridColumn: 3, gridRow: 1, whiteSpace: 'nowrap', ...measuringCellSx }}> <Box aria-hidden sx={{ gridColumn: 3, gridRow: 1, whiteSpace: 'nowrap', ...measuringCellSx }}>
<Typography variant="body2" sx={{ fontWeight: 600 }}>{d.orderNumber}</Typography> <Typography variant="body2" sx={{ fontWeight: 600, fontFamily: 'monospace' }}>{d.orderNumber}</Typography>
</Box> </Box>
<Box aria-hidden sx={{ gridColumn: 4, gridRow: 1, whiteSpace: 'nowrap', ...measuringCellSx }}> <Box aria-hidden sx={{ gridColumn: 4, gridRow: 1, whiteSpace: 'nowrap', ...measuringCellSx }}>
<Typography variant="body1">{d.customerName}</Typography> <Typography variant="body1">{d.customerName}</Typography>
@@ -594,10 +595,10 @@ class ShipmentRow extends PureComponent {
{/* 1. Lieferschein-Nr & Ref */} {/* 1. Lieferschein-Nr & Ref */}
<Box sx={{ gridColumn: 1, gridRow: 2, minWidth: 0, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}> <Box sx={{ gridColumn: 1, gridRow: 2, minWidth: 0, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
<Typography variant="body1" sx={{ fontWeight: 600, ...ellipsisSx }}> <Typography variant="body1" sx={{ fontWeight: 600, fontFamily: 'monospace', ...ellipsisSx }}>
{shipment.number} {shipment.number}
</Typography> </Typography>
<Typography variant="body2" color="text.secondary" sx={ellipsisSx}> <Typography variant="body2" color="text.secondary" sx={{ fontFamily: 'monospace', ...ellipsisSx }}>
{numberDisplay(shipment.externalNumber)} {numberDisplay(shipment.externalNumber)}
</Typography> </Typography>
</Box> </Box>
@@ -612,7 +613,7 @@ class ShipmentRow extends PureComponent {
{/* 3. Bezugsauftrag */} {/* 3. Bezugsauftrag */}
<Box sx={{ gridColumn: 3, gridRow: 2, minWidth: 0, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}> <Box sx={{ gridColumn: 3, gridRow: 2, minWidth: 0, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
{shipment.orderNumber ? ( {shipment.orderNumber ? (
<Typography variant="body2" sx={{ fontWeight: 600, color: 'primary.main', ...ellipsisSx }}> <Typography variant="body2" sx={{ fontWeight: 600, color: 'primary.main', fontFamily: 'monospace', ...ellipsisSx }}>
{shipment.orderNumber} {shipment.orderNumber}
</Typography> </Typography>
) : ( ) : (

View File

@@ -217,6 +217,7 @@ export default class NumberSettingsPanel extends Component {
value={draft.prefix} value={draft.prefix}
disabled={draft.busy} disabled={draft.busy}
onChange={(e) => this.handleChange(row.id, 'prefix', e.target.value)} onChange={(e) => this.handleChange(row.id, 'prefix', e.target.value)}
sx={{ input: { fontFamily: 'monospace' } }}
/> />
</TableCell> </TableCell>
<TableCell> <TableCell>
@@ -227,6 +228,7 @@ export default class NumberSettingsPanel extends Component {
disabled={draft.busy} disabled={draft.busy}
slotProps={{ htmlInput: { min: 1, step: 1 } }} slotProps={{ htmlInput: { min: 1, step: 1 } }}
onChange={(e) => this.handleChange(row.id, 'padding', e.target.value)} onChange={(e) => this.handleChange(row.id, 'padding', e.target.value)}
sx={{ input: { fontFamily: 'monospace' } }}
/> />
</TableCell> </TableCell>
<TableCell> <TableCell>
@@ -237,6 +239,7 @@ export default class NumberSettingsPanel extends Component {
disabled={draft.busy} disabled={draft.busy}
slotProps={{ htmlInput: { min: 0, step: 1 } }} slotProps={{ htmlInput: { min: 0, step: 1 } }}
onChange={(e) => this.handleChange(row.id, 'next', e.target.value)} onChange={(e) => this.handleChange(row.id, 'next', e.target.value)}
sx={{ input: { fontFamily: 'monospace' } }}
/> />
</TableCell> </TableCell>
<TableCell align="right"> <TableCell align="right">

View File

@@ -309,7 +309,12 @@ export class ArticleTile extends Tile {
/> />
) : null} ) : null}
{sku ? ( {sku ? (
<Typography variant="caption" color="text.secondary" noWrap sx={{ maxWidth: '100%' }}> <Typography
variant="caption"
color="text.secondary"
noWrap
sx={{ maxWidth: '100%', fontFamily: 'monospace' }}
>
{sku} {sku}
</Typography> </Typography>
) : null} ) : null}
@@ -497,6 +502,7 @@ export class ArticleTile extends Tile {
height: '1.2em', height: '1.2em',
overflow: 'hidden', overflow: 'hidden',
textOverflow: 'ellipsis', textOverflow: 'ellipsis',
fontFamily: 'monospace',
}} }}
> >
{sku || '\u00A0'} {sku || '\u00A0'}

View File

@@ -102,4 +102,16 @@ html.df-dialog-open #root {
box-shadow: var(--df-shadow-drag, 0 8px 20px rgba(15, 23, 42, 0.28)); box-shadow: var(--df-shadow-drag, 0 8px 20px rgba(15, 23, 42, 0.28));
cursor: grabbing !important; cursor: grabbing !important;
user-select: none !important; user-select: none !important;
}
/* ────────────────────────────────────────────────────────────────────────────
* NUMBER SCHEME MONOSPACE FONT
*
* All numbers originating from a number scheme (SKUs, customer numbers,
* delivery/quote/order/shipment document numbers) must be monospaced with tabular numbers.
* ──────────────────────────────────────────────────────────────────────────── */
.df-mono,
.df-number-scheme {
font-family: ui-monospace, 'SFMono-Regular', Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace !important;
font-variant-numeric: tabular-nums;
} }

View File

@@ -156,7 +156,7 @@ class ResultRow extends Component {
<Typography <Typography
variant="body2" variant="body2"
color="text.secondary" color="text.secondary"
sx={{ ...resultCellSx, minWidth: 84 }} sx={{ ...resultCellSx, minWidth: 84, fontFamily: 'monospace' }}
> >
{row.sku} {row.sku}
</Typography> </Typography>

View File

@@ -2,6 +2,7 @@ import { PureComponent } from 'react';
import Box from '@mui/material/Box'; import Box from '@mui/material/Box';
import Button from '@mui/material/Button'; import Button from '@mui/material/Button';
import CircularProgress from '@mui/material/CircularProgress'; import CircularProgress from '@mui/material/CircularProgress';
import Chip from '@mui/material/Chip';
import Divider from '@mui/material/Divider'; import Divider from '@mui/material/Divider';
import IconButton from '@mui/material/IconButton'; import IconButton from '@mui/material/IconButton';
import Stack from '@mui/material/Stack'; import Stack from '@mui/material/Stack';
@@ -559,11 +560,25 @@ class KundeEditPage extends PureComponent {
<PanelTileGrid> <PanelTileGrid>
<PanelTile wide={2} minHeight={200} color={BLUE_PANEL} title="Stammdaten"> <PanelTile wide={2} minHeight={200} color={BLUE_PANEL} title="Stammdaten">
<Stack spacing={2}> <Stack spacing={2}>
{groupName != null ? ( <Stack direction="row" spacing={1} alignItems="center" flexWrap="wrap">
<Typography variant="body2" color="text.secondary"> {entity?.number ? (
Gruppe: {groupName} <Chip
</Typography> size="small"
) : null} label={`Kundennummer: ${entity.number}`}
sx={{
fontFamily: 'monospace',
fontWeight: 600,
fontSize: '0.75rem',
bgcolor: 'action.hover',
}}
/>
) : null}
{groupName != null ? (
<Typography variant="body2" color="text.secondary">
Gruppe: {groupName}
</Typography>
) : null}
</Stack>
<SingleLineTextEdit <SingleLineTextEdit
size="small" size="small"
label="Name" label="Name"

View File

@@ -141,6 +141,7 @@ class KundeNeuPage extends PureComponent {
disabled disabled
slotProps={{ slotProps={{
htmlInput: { autoComplete: 'off' }, htmlInput: { autoComplete: 'off' },
input: { sx: { fontFamily: 'monospace' } },
}} }}
/> />
<Select <Select

View File

@@ -45,6 +45,9 @@ export function createDefaultTheme() {
paper: WHITE, paper: WHITE,
}, },
}, },
typography: {
fontFamilyMono: 'ui-monospace, "SFMono-Regular", Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace',
},
nav, nav,
components: { components: {
MuiModal: { MuiModal: {

View File

@@ -4,6 +4,16 @@ import orderAutomat from '../automats/orderAutomat';
import deliveryAutomat from '../automats/deliveryAutomat'; import deliveryAutomat from '../automats/deliveryAutomat';
import { order as orderApi, quote as quoteApi, delivery as deliveryApi } from '../api'; import { order as orderApi, quote as quoteApi, delivery as deliveryApi } from '../api';
/** Standard cross-platform monospace font stack for numbers from a number scheme. */
export const MONO_FONT_FAMILY =
'ui-monospace, "SFMono-Regular", Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace';
/** Common sx mixin for monospace numberscheme display. */
export const monoFontSx = {
fontFamily: MONO_FONT_FAMILY,
fontVariantNumeric: 'tabular-nums',
};
/** Highest integer counter found per document kind. */ /** Highest integer counter found per document kind. */
const maxKnownNumberByKind = new Map(); const maxKnownNumberByKind = new Map();