This commit is contained in:
seb
2026-10-15 00:20:54 +02:00
parent 7ce2e3216f
commit 39aa898324
6 changed files with 126 additions and 10 deletions

View File

@@ -375,6 +375,24 @@ export function createDeliveryEditorAutomat(options = {}) {
automat.actions.removeLineitem(payload); automat.actions.removeLineitem(payload);
}, },
/**
* Moves a lineitem from one index to another.
* @param {number} fromIndex Source index.
* @param {number} toIndex Target index.
* @returns {void}
*/
moveLineitem(fromIndex, toIndex) {
const currentLines = automat.state.lines ?? [];
if (fromIndex < 0 || fromIndex >= currentLines.length || toIndex < 0 || toIndex >= currentLines.length) return;
const nextLines = [...currentLines];
const [item] = nextLines.splice(fromIndex, 1);
nextLines.splice(toIndex, 0, item);
automat.setState({
lines: nextLines,
lineitems: nextLines,
});
},
/** Clears all lines from the editor. @returns {void} */ /** Clears all lines from the editor. @returns {void} */
clearLineitems() { clearLineitems() {
automat.setState({ automat.setState({

View File

@@ -284,6 +284,17 @@ export function getManifestDirtyDetails(current, baseline) {
if (curLines.length !== baseLines.length) { if (curLines.length !== baseLines.length) {
fields.lines = true; fields.lines = true;
} else {
for (let i = 0; i < curLines.length; i++) {
const cl = curLines[i];
const bl = baseLines[i];
const clIdentifier = cl?.key ?? (cl?.id != null ? `id-${cl.id}` : null);
const blIdentifier = bl?.key ?? (bl?.id != null ? `id-${bl.id}` : null);
if (clIdentifier && blIdentifier && clIdentifier !== blIdentifier) {
fields.lines = true;
break;
}
}
} }
for (let i = 0; i < curLines.length; i++) { for (let i = 0; i < curLines.length; i++) {

View File

@@ -96,6 +96,7 @@ class ManifestForm extends PureComponent {
this.handleCloseArticleSearch = this.handleCloseArticleSearch.bind(this); this.handleCloseArticleSearch = this.handleCloseArticleSearch.bind(this);
this.handleAssignArticleForLine = this.handleAssignArticleForLine.bind(this); this.handleAssignArticleForLine = this.handleAssignArticleForLine.bind(this);
this.handleRemoveLine = this.handleRemoveLine.bind(this); this.handleRemoveLine = this.handleRemoveLine.bind(this);
this.handleMoveLine = this.handleMoveLine.bind(this);
this.handleRemoveAllLines = this.handleRemoveAllLines.bind(this); this.handleRemoveAllLines = this.handleRemoveAllLines.bind(this);
this.handleSave = this.handleSave.bind(this); this.handleSave = this.handleSave.bind(this);
this.handlePdfUpload = this.handlePdfUpload.bind(this); this.handlePdfUpload = this.handlePdfUpload.bind(this);
@@ -701,6 +702,19 @@ class ManifestForm extends PureComponent {
}); });
} }
handleMoveLine(key, delta) {
this.setState((prev) => {
const fromIndex = prev.lines.findIndex((l) => l.key === key);
if (fromIndex < 0) return null;
const toIndex = fromIndex + delta;
if (toIndex < 0 || toIndex >= prev.lines.length) return null;
const next = [...prev.lines];
const [item] = next.splice(fromIndex, 1);
next.splice(toIndex, 0, item);
return { lines: next, isDirty: true };
});
}
handleRemoveAllLines() { handleRemoveAllLines() {
this.setState({ lines: [] }); this.setState({ lines: [] });
} }
@@ -998,6 +1012,7 @@ class ManifestForm extends PureComponent {
onAddArticleLine={this.handleAddArticleLine} onAddArticleLine={this.handleAddArticleLine}
onSearchArticle={this.handleOpenArticleSearchForLine} onSearchArticle={this.handleOpenArticleSearchForLine}
onRemoveLine={this.handleRemoveLine} onRemoveLine={this.handleRemoveLine}
onMoveLine={this.handleMoveLine}
onRemoveAllLines={this.handleRemoveAllLines} onRemoveAllLines={this.handleRemoveAllLines}
onSave={() => void this.handleSave()} onSave={() => void this.handleSave()}
/> />

View File

@@ -11,6 +11,8 @@ import TextField from '@mui/material/TextField';
import Tooltip from '@mui/material/Tooltip'; import Tooltip from '@mui/material/Tooltip';
import Typography from '@mui/material/Typography'; import Typography from '@mui/material/Typography';
import DeleteOutlinedIcon from '@mui/icons-material/DeleteOutlined'; import DeleteOutlinedIcon from '@mui/icons-material/DeleteOutlined';
import ArrowUpwardIcon from '@mui/icons-material/ArrowUpward';
import ArrowDownwardIcon from '@mui/icons-material/ArrowDownward';
import HelpOutlineIcon from '@mui/icons-material/HelpOutlineOutlined'; import HelpOutlineIcon from '@mui/icons-material/HelpOutlineOutlined';
import Inventory2OutlinedIcon from '@mui/icons-material/Inventory2Outlined'; import Inventory2OutlinedIcon from '@mui/icons-material/Inventory2Outlined';
import CheckCircleOutlineOutlinedIcon from '@mui/icons-material/CheckCircleOutlineOutlined'; import CheckCircleOutlineOutlinedIcon from '@mui/icons-material/CheckCircleOutlineOutlined';
@@ -40,6 +42,8 @@ class ManifestFormLine extends PureComponent {
fallbackSuppliers: [], fallbackSuppliers: [],
}; };
this.handleRemove = this.handleRemove.bind(this); this.handleRemove = this.handleRemove.bind(this);
this.handleMoveUp = this.handleMoveUp.bind(this);
this.handleMoveDown = this.handleMoveDown.bind(this);
this.handleBlur = this.handleBlur.bind(this); this.handleBlur = this.handleBlur.bind(this);
this.handleCreateArticle = this.handleCreateArticle.bind(this); this.handleCreateArticle = this.handleCreateArticle.bind(this);
this.handleSearchArticle = this.handleSearchArticle.bind(this); this.handleSearchArticle = this.handleSearchArticle.bind(this);
@@ -121,6 +125,14 @@ class ManifestFormLine extends PureComponent {
this.props.onRemove(this.props.line.key); this.props.onRemove(this.props.line.key);
} }
handleMoveUp() {
this.props.onMove?.(this.props.line.key, -1);
}
handleMoveDown() {
this.props.onMove?.(this.props.line.key, 1);
}
handleBlur(e, columnId) { handleBlur(e, columnId) {
if (columnId === 'sku' && this.props.onSkuBlur) { if (columnId === 'sku' && this.props.onSkuBlur) {
this.props.onSkuBlur(this.props.line.key, e.target.value); this.props.onSkuBlur(this.props.line.key, e.target.value);
@@ -971,15 +983,62 @@ class ManifestFormLine extends PureComponent {
{this.renderField(col, colIdx, columns.length)} {this.renderField(col, colIdx, columns.length)}
</TableCell> </TableCell>
))} ))}
<TableCell padding="none" sx={{ py: 0.25, pl: 0.75, pr: 0, verticalAlign: 'middle', width: 40 }}> <TableCell
padding="none"
sx={{
py: 0.25,
pl: 0.5,
pr: 0.5,
verticalAlign: 'middle',
width: this.props.onMove ? 92 : 40,
whiteSpace: 'nowrap',
}}
>
<Box sx={{ display: 'flex', alignItems: 'center', gap: 0.25 }}>
{this.props.onMove && (
<>
<Tooltip title="Nach oben">
<span>
<IconButton
size="small"
aria-label="Nach oben verschieben"
disabled={saving || this.props.isFirstLine}
onClick={this.handleMoveUp}
sx={{ p: 0.35 }}
>
<ArrowUpwardIcon sx={{ fontSize: 16 }} />
</IconButton>
</span>
</Tooltip>
<Tooltip title="Nach unten">
<span>
<IconButton
size="small"
aria-label="Nach unten verschieben"
disabled={saving || this.props.isLastLine}
onClick={this.handleMoveDown}
sx={{ p: 0.35 }}
>
<ArrowDownwardIcon sx={{ fontSize: 16 }} />
</IconButton>
</span>
</Tooltip>
</>
)}
<Tooltip title="Zeile entfernen">
<span>
<IconButton <IconButton
size="small" size="small"
aria-label="Zeile entfernen" aria-label="Zeile entfernen"
disabled={saving} disabled={saving}
onClick={this.handleRemove} onClick={this.handleRemove}
sx={{ p: 0.35 }}
> >
<DeleteOutlinedIcon fontSize="small" /> <DeleteOutlinedIcon sx={{ fontSize: 18 }} />
</IconButton> </IconButton>
</span>
</Tooltip>
</Box>
</TableCell> </TableCell>
</TableRow> </TableRow>

View File

@@ -28,6 +28,7 @@ class ManifestLines extends PureComponent {
onLineChange, onLineChange,
onAddLine, onAddLine,
onRemoveLine, onRemoveLine,
onMoveLine,
onRemoveAllLines, onRemoveAllLines,
columns = LINE_COLUMNS, columns = LINE_COLUMNS,
supplierArticlesMap = {}, supplierArticlesMap = {},
@@ -98,7 +99,7 @@ class ManifestLines extends PureComponent {
{col.label} {col.label}
</TableCell> </TableCell>
))} ))}
<TableCell padding="none" sx={{ bgcolor: linesColor, borderBottom: 'none', width: 40 }} /> <TableCell padding="none" sx={{ bgcolor: linesColor, borderBottom: 'none', width: onMoveLine ? 92 : 40 }} />
</TableRow> </TableRow>
</TableHead> </TableHead>
<TableBody> <TableBody>
@@ -138,6 +139,9 @@ class ManifestLines extends PureComponent {
supplierArticleBusy={Boolean(busySupplierArticleLineKeys[lineKey])} supplierArticleBusy={Boolean(busySupplierArticleLineKeys[lineKey])}
onChange={onLineChange} onChange={onLineChange}
onRemove={onRemoveLine} onRemove={onRemoveLine}
onMove={onMoveLine}
isFirstLine={index === 0}
isLastLine={index === lines.length - 1}
onSkuBlur={onSkuBlur} onSkuBlur={onSkuBlur}
onCreateArticle={onCreateArticle} onCreateArticle={onCreateArticle}
onSearchArticle={onSearchArticle} onSearchArticle={onSearchArticle}

View File

@@ -99,6 +99,7 @@ class LieferungNeuPage extends PureComponent {
this.handleAddLine = this.handleAddLine.bind(this); this.handleAddLine = this.handleAddLine.bind(this);
this.handleAddArticleLine = this.handleAddArticleLine.bind(this); this.handleAddArticleLine = this.handleAddArticleLine.bind(this);
this.handleRemoveLine = this.handleRemoveLine.bind(this); this.handleRemoveLine = this.handleRemoveLine.bind(this);
this.handleMoveLine = this.handleMoveLine.bind(this);
this.handleRemoveAllLines = this.handleRemoveAllLines.bind(this); this.handleRemoveAllLines = this.handleRemoveAllLines.bind(this);
this.handleSave = this.handleSave.bind(this); this.handleSave = this.handleSave.bind(this);
this.handlePdfUpload = this.handlePdfUpload.bind(this); this.handlePdfUpload = this.handlePdfUpload.bind(this);
@@ -541,6 +542,13 @@ class LieferungNeuPage extends PureComponent {
this.automat.actions.removeLineitem(index >= 0 ? index : key); this.automat.actions.removeLineitem(index >= 0 ? index : key);
} }
handleMoveLine(key, delta) {
const fromIndex = this.findLineIndex(key);
if (fromIndex < 0) return;
const toIndex = fromIndex + delta;
this.automat.actions.moveLineitem(fromIndex, toIndex);
}
handleRemoveAllLines() { handleRemoveAllLines() {
this.automat.actions.clearLineitems(); this.automat.actions.clearLineitems();
} }
@@ -1340,6 +1348,7 @@ class LieferungNeuPage extends PureComponent {
onAddLine={this.handleAddLine} onAddLine={this.handleAddLine}
onAddArticleLine={this.handleAddArticleLine} onAddArticleLine={this.handleAddArticleLine}
onRemoveLine={this.handleRemoveLine} onRemoveLine={this.handleRemoveLine}
onMoveLine={this.handleMoveLine}
onRemoveAllLines={this.handleRemoveAllLines} onRemoveAllLines={this.handleRemoveAllLines}
onSave={() => void this.handleSave()} onSave={() => void this.handleSave()}
onCreateArticle={this.handleCreateArticleForLine} onCreateArticle={this.handleCreateArticleForLine}