This commit is contained in:
seb
2026-10-14 15:00:31 +02:00
parent 4188d8f46f
commit b8fdef4e11
5 changed files with 87 additions and 96 deletions

View File

@@ -69,6 +69,7 @@ class ManifestForm extends PureComponent {
isDirty: Boolean(initialEdit?.isDirty),
dirtyFields: initialEdit?.dirtyFields || null,
dirtyLineKeys: initialEdit?.dirtyLineKeys || [],
dirtyLineFields: initialEdit?.dirtyLineFields || {},
dirtySummary: initialEdit?.dirtySummary || [],
saving: false,
pdfUploading: false,
@@ -172,6 +173,7 @@ class ManifestForm extends PureComponent {
isDirty: Boolean(state.isDirty),
dirtyFields: state.dirtyFields,
dirtyLineKeys: state.dirtyLineKeys,
dirtyLineFields: state.dirtyLineFields,
dirtySummary: state.dirtySummary,
};
}
@@ -225,13 +227,14 @@ class ManifestForm extends PureComponent {
lines: this.state.lines,
attachments: this.state.attachments,
});
const { isDirty, dirtyFields, dirtyLineKeys, dirtySummary } = this.editAutomat.state;
const { isDirty, dirtyFields, dirtyLineKeys, dirtyLineFields, dirtySummary } = this.editAutomat.state;
if (
this.state.isDirty !== isDirty ||
this.state.dirtyFields !== dirtyFields ||
this.state.dirtyLineFields !== dirtyLineFields ||
this.state.dirtySummary !== dirtySummary
) {
this.setState({ isDirty, dirtyFields, dirtyLineKeys, dirtySummary });
this.setState({ isDirty, dirtyFields, dirtyLineKeys, dirtyLineFields, dirtySummary });
}
}
}
@@ -297,6 +300,7 @@ class ManifestForm extends PureComponent {
isDirty: Boolean(this.editAutomat.state.isDirty),
dirtyFields: this.editAutomat.state.dirtyFields,
dirtyLineKeys: this.editAutomat.state.dirtyLineKeys,
dirtyLineFields: this.editAutomat.state.dirtyLineFields,
dirtySummary: this.editAutomat.state.dirtySummary,
date: this.editAutomat.state.date,
partyId: this.editAutomat.state.partyId,
@@ -349,6 +353,7 @@ class ManifestForm extends PureComponent {
isDirty: false,
dirtyFields: null,
dirtyLineKeys: [],
dirtyLineFields: {},
dirtySummary: [],
});
} catch (err) {
@@ -380,6 +385,7 @@ class ManifestForm extends PureComponent {
isDirty: false,
dirtyFields: state.dirtyFields,
dirtyLineKeys: state.dirtyLineKeys,
dirtyLineFields: state.dirtyLineFields,
dirtySummary: state.dirtySummary,
});
enqueueSnackbar('Änderungen verworfen und ursprünglicher Stand wiederhergestellt.', { variant: 'info' });
@@ -874,6 +880,7 @@ class ManifestForm extends PureComponent {
isDirty: false,
dirtyFields: null,
dirtyLineKeys: [],
dirtyLineFields: {},
dirtySummary: [],
saving: false,
});
@@ -887,7 +894,7 @@ class ManifestForm extends PureComponent {
renderArticles() {
const cfg = this.cfg;
const { lines, saving, dirtyFields, dirtyLineKeys } = this.state;
const { lines, saving, dirtyLineFields } = this.state;
return (
<ManifestLines
@@ -897,8 +904,7 @@ class ManifestForm extends PureComponent {
saving={saving}
wide={4}
linesColor={cfg.linesColor}
isLinesDirty={Boolean(dirtyFields?.lines)}
dirtyLineKeys={dirtyLineKeys || []}
dirtyLineFields={dirtyLineFields || {}}
onLineChange={this.handleLineChange}
onSkuBlur={this.handleSkuBlur}
onAddLine={this.handleAddLine}

View File

@@ -267,6 +267,11 @@ class ManifestFormLine extends PureComponent {
const isFirstInput = hasPosCol ? colIdx === 1 : colIdx === 0;
const isLast = colIdx === totalCols - 1;
const { dirtyFields } = this.props;
const isFieldDirty = Boolean(
dirtyFields && (dirtyFields.__all__ || dirtyFields[id])
);
return (
<TextField
size="small"
@@ -290,6 +295,9 @@ class ManifestFormLine extends PureComponent {
'& .MuiOutlinedInput-root': {
borderRadius: isFirstInput ? '4px 0 0 4px' : isLast ? '0 4px 4px 0' : 0,
ml: isFirstInput ? 0 : '-1px',
...(isFieldDirty && {
bgcolor: 'rgba(237, 108, 2, 0.08)',
}),
'&:hover': {
zIndex: 1,
},
@@ -297,6 +305,16 @@ class ManifestFormLine extends PureComponent {
zIndex: 2,
},
},
...(isFieldDirty && {
zIndex: 1,
'& .MuiOutlinedInput-notchedOutline': {
borderColor: 'warning.main',
borderWidth: 2,
},
'&:hover .MuiOutlinedInput-notchedOutline': {
borderColor: 'warning.main',
},
}),
'& input[type=number]': {
MozAppearance: 'textfield',
},
@@ -838,19 +856,13 @@ class ManifestFormLine extends PureComponent {
}
render() {
const { columns = LINE_COLUMNS, saving, isDirty } = this.props;
const { columns = LINE_COLUMNS, saving } = this.props;
const secondLine = this.renderSecondLine();
return (
<Fragment>
{/* Row 1: Editable Line Inputs */}
<TableRow
hover
sx={{
'& > td': { borderBottom: 'none', p: 0 },
...(isDirty ? { bgcolor: 'rgba(237, 108, 2, 0.08)' } : {}),
}}
>
<TableRow hover sx={{ '& > td': { borderBottom: 'none', p: 0 } }}>
{columns.map((col, colIdx) => (
<TableCell
key={col.id}
@@ -859,7 +871,6 @@ class ManifestFormLine extends PureComponent {
p: 0,
width: col.width,
verticalAlign: 'middle',
...(isDirty && colIdx === 0 ? { borderLeft: '3px solid', borderColor: 'warning.main' } : {}),
}}
>
{this.renderField(col, colIdx, columns.length)}
@@ -879,19 +890,13 @@ class ManifestFormLine extends PureComponent {
{/* Row 2: Matched Supplier Article Details */}
{secondLine && (
<TableRow
sx={{
'& > td': { pt: 0.25, pb: 0.75, borderBottom: 'none' },
...(isDirty ? { bgcolor: 'rgba(237, 108, 2, 0.04)' } : {}),
}}
>
<TableRow sx={{ '& > td': { pt: 0.25, pb: 0.75, borderBottom: 'none' } }}>
<TableCell
colSpan={columns.length + 1}
sx={{
py: 0.4,
px: 1,
bgcolor: 'transparent',
...(isDirty ? { borderLeft: '3px solid', borderColor: 'warning.main' } : {}),
}}
>
{secondLine}

View File

@@ -6,7 +6,6 @@ import CircularProgress from '@mui/material/CircularProgress';
import Stack from '@mui/material/Stack';
import TextField from '@mui/material/TextField';
import Chip from '@mui/material/Chip';
import Typography from '@mui/material/Typography';
import UploadFileIcon from '@mui/icons-material/UploadFile';
import Inventory2OutlinedIcon from '@mui/icons-material/Inventory2Outlined';
import CheckCircleOutlineOutlinedIcon from '@mui/icons-material/CheckCircleOutlineOutlined';
@@ -486,33 +485,6 @@ class ManifestHeader extends PureComponent {
Wiederherstellen
</Button>
)}
{isDirty && dirtySummary && dirtySummary.length > 0 && (
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 0.5, pt: 0.25 }}>
<Typography variant="caption" sx={{ color: 'warning.dark', fontWeight: 700, fontSize: '0.72rem' }}>
Geänderte Felder:
</Typography>
<Box sx={{ display: 'flex', flexWrap: 'wrap', gap: 0.5 }}>
{dirtySummary.map((item) => (
<Chip
key={item}
size="small"
color="warning"
variant="filled"
label={item}
sx={{
height: 20,
fontSize: '0.68rem',
fontWeight: 700,
bgcolor: 'rgba(237, 108, 2, 0.15)',
color: 'warning.dark',
border: '1px solid',
borderColor: 'warning.main',
}}
/>
))}
</Box>
</Box>
)}
{docId != null && kind === 'delivery' && onOpenBookDialog && (
<Button
variant={ledgerSummary?.status === 'booked' ? 'outlined' : 'contained'}

View File

@@ -9,7 +9,6 @@ import TableContainer from '@mui/material/TableContainer';
import TableHead from '@mui/material/TableHead';
import TableRow from '@mui/material/TableRow';
import Typography from '@mui/material/Typography';
import Chip from '@mui/material/Chip';
import AddIcon from '@mui/icons-material/Add';
import SearchIcon from '@mui/icons-material/Search';
import DeleteSweepOutlinedIcon from '@mui/icons-material/DeleteSweepOutlined';
@@ -25,8 +24,7 @@ class ManifestLines extends PureComponent {
lines,
saving,
linesColor,
isLinesDirty = false,
dirtyLineKeys = [],
dirtyLineFields = {},
onLineChange,
onAddLine,
onRemoveLine,
@@ -68,28 +66,7 @@ class ManifestLines extends PureComponent {
wide={wide}
minHeight={280}
color={linesColor}
title={
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
<span>Artikel</span>
{isLinesDirty && (
<Chip
size="small"
color="warning"
variant="filled"
label="Geändert"
sx={{
height: 20,
fontSize: '0.68rem',
fontWeight: 700,
bgcolor: 'rgba(237, 108, 2, 0.15)',
color: 'warning.dark',
border: '1px solid',
borderColor: 'warning.main',
}}
/>
)}
</Box>
}
title="Artikel"
sx={{
...(wide >= 4 ? { gridColumn: { xs: '1 / -1', sm: '1 / -1', md: 'span 4' } } : {}),
...(!hasArticles
@@ -139,11 +116,12 @@ class ManifestLines extends PureComponent {
(supplierArticlesLoading && !matched)
: false;
const ledgerLine = line.id != null ? ledgerLinesById[line.id] : null;
const isDirty =
dirtyLineKeys.includes(lineKey) ||
(line.key != null && dirtyLineKeys.includes(line.key)) ||
(line.id != null && dirtyLineKeys.includes(`id-${line.id}`)) ||
dirtyLineKeys.includes(`idx-${index}`);
const lineDirtyFields =
dirtyLineFields[lineKey] ||
(line.key != null ? dirtyLineFields[line.key] : null) ||
(line.id != null ? dirtyLineFields[`id-${line.id}`] : null) ||
dirtyLineFields[`idx-${index}`] ||
null;
return (
<ManifestFormLine
@@ -154,7 +132,7 @@ class ManifestLines extends PureComponent {
line={line.key != null ? line : { ...line, key: index }}
columns={columns}
saving={saving}
isDirty={Boolean(isDirty)}
dirtyFields={lineDirtyFields}
supplierArticle={matched}
loading={Boolean(isLineLoading)}
supplierArticleBusy={Boolean(busySupplierArticleLineKeys[lineKey])}