u
This commit is contained in:
@@ -40,11 +40,14 @@ class ManifestFormLine extends PureComponent {
|
||||
cachedArticle: sku ? getArticle(sku) : null,
|
||||
loadingArticle: false,
|
||||
fallbackSuppliers: [],
|
||||
editingField: null,
|
||||
};
|
||||
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.handleKeyDown = this.handleKeyDown.bind(this);
|
||||
this.handleStartEdit = this.handleStartEdit.bind(this);
|
||||
this.handleCreateArticle = this.handleCreateArticle.bind(this);
|
||||
this.handleSearchArticle = this.handleSearchArticle.bind(this);
|
||||
this.handleRemoveSupplierArticle = this.handleRemoveSupplierArticle.bind(this);
|
||||
@@ -134,7 +137,25 @@ class ManifestFormLine extends PureComponent {
|
||||
this.props.onMove?.(this.props.line.key, 1);
|
||||
}
|
||||
|
||||
handleStartEdit(columnId) {
|
||||
const { saving } = this.props;
|
||||
const isDisabled = saving || (columnId === 'sku' && Boolean(this.props.isOnShipment));
|
||||
if (isDisabled) return;
|
||||
if (this.state.editingField !== columnId) {
|
||||
this.setState({ editingField: columnId });
|
||||
}
|
||||
}
|
||||
|
||||
handleKeyDown(e) {
|
||||
if (e.key === 'Enter' || e.key === 'Escape') {
|
||||
e.target.blur();
|
||||
}
|
||||
}
|
||||
|
||||
handleBlur(e, columnId) {
|
||||
if (this.state.editingField === columnId) {
|
||||
this.setState({ editingField: null });
|
||||
}
|
||||
if (columnId === 'sku' && this.props.onSkuBlur) {
|
||||
this.props.onSkuBlur(this.props.line.key, e.target.value);
|
||||
}
|
||||
@@ -229,6 +250,8 @@ class ManifestFormLine extends PureComponent {
|
||||
renderField(column, colIdx, totalCols) {
|
||||
const { id, align, type } = column;
|
||||
const { line, saving, onChange, columns } = this.props;
|
||||
const isFirstLine = Boolean(this.props.isFirstLine ?? (this.props.index === 0));
|
||||
const isLastLine = Boolean(this.props.isLastLine);
|
||||
|
||||
if (id === 'pos') {
|
||||
const posVal =
|
||||
@@ -240,8 +263,10 @@ class ManifestFormLine extends PureComponent {
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
height: '100%',
|
||||
minHeight: 38,
|
||||
height: isFirstLine ? 40 : 41,
|
||||
minHeight: isFirstLine ? 40 : 41,
|
||||
maxHeight: isFirstLine ? 40 : 41,
|
||||
mt: isFirstLine ? 0 : '-1px',
|
||||
fontWeight: 700,
|
||||
fontSize: '0.82rem',
|
||||
color: 'text.secondary',
|
||||
@@ -297,65 +322,197 @@ class ManifestFormLine extends PureComponent {
|
||||
const isFirstInput = hasPosCol ? colIdx === 1 : colIdx === 0;
|
||||
const isLast = colIdx === totalCols - 1;
|
||||
|
||||
const topLeftRadius = isFirstInput && isFirstLine ? 4 : 0;
|
||||
const topRightRadius = isLast && isFirstLine ? 4 : 0;
|
||||
const bottomRightRadius = isLast && isLastLine ? 4 : 0;
|
||||
const bottomLeftRadius = isFirstInput && isLastLine ? 4 : 0;
|
||||
const borderRadius = `${topLeftRadius}px ${topRightRadius}px ${bottomRightRadius}px ${bottomLeftRadius}px`;
|
||||
|
||||
const { dirtyFields } = this.props;
|
||||
const isFieldDirty = Boolean(
|
||||
dirtyFields && (dirtyFields.__all__ || dirtyFields[id])
|
||||
);
|
||||
|
||||
return (
|
||||
<TextField
|
||||
size="small"
|
||||
fullWidth
|
||||
type={type}
|
||||
value={val ?? ''}
|
||||
error={isError}
|
||||
disabled={saving || (id === 'sku' && Boolean(this.props.isOnShipment))}
|
||||
title={id === 'sku' && this.props.isOnShipment ? 'Artikel ist bereits auf einem Lieferschein und kann nicht geändert werden' : undefined}
|
||||
autoComplete="off"
|
||||
onChange={(e) => onChange(line.key, id, e.target.value)}
|
||||
onBlur={(e) => this.handleBlur(e, id)}
|
||||
slotProps={{
|
||||
htmlInput: {
|
||||
inputMode: type === 'number' ? 'decimal' : 'text',
|
||||
style: { textAlign: align },
|
||||
autoComplete: 'off',
|
||||
step: type === 'number' ? 'any' : undefined,
|
||||
},
|
||||
}}
|
||||
sx={{
|
||||
'& .MuiOutlinedInput-root': {
|
||||
borderRadius: isFirstInput ? '4px 0 0 4px' : isLast ? '0 4px 4px 0' : 0,
|
||||
const isEditing = this.state.editingField === id;
|
||||
const isDisabled = saving || (id === 'sku' && Boolean(this.props.isOnShipment));
|
||||
const titleText = id === 'sku' && this.props.isOnShipment
|
||||
? 'Artikel ist bereits auf einem Lieferschein und kann nicht geändert werden'
|
||||
: undefined;
|
||||
|
||||
if (isEditing) {
|
||||
return (
|
||||
<TextField
|
||||
autoFocus
|
||||
size="small"
|
||||
type={type}
|
||||
value={val ?? ''}
|
||||
error={isError}
|
||||
disabled={isDisabled}
|
||||
title={titleText}
|
||||
autoComplete="off"
|
||||
onChange={(e) => onChange(line.key, id, e.target.value)}
|
||||
onBlur={(e) => this.handleBlur(e, id)}
|
||||
onKeyDown={this.handleKeyDown}
|
||||
slotProps={{
|
||||
htmlInput: {
|
||||
inputMode: type === 'number' ? 'decimal' : 'text',
|
||||
style: { textAlign: align },
|
||||
autoComplete: 'off',
|
||||
step: type === 'number' ? 'any' : undefined,
|
||||
},
|
||||
}}
|
||||
sx={{
|
||||
position: 'relative',
|
||||
ml: isFirstInput ? 0 : '-1px',
|
||||
...(isFieldDirty && {
|
||||
bgcolor: 'rgba(237, 108, 2, 0.08)',
|
||||
}),
|
||||
'&:hover': {
|
||||
zIndex: 1,
|
||||
width: isFirstInput ? '100%' : 'calc(100% + 1px)',
|
||||
mt: isFirstLine ? 0 : '-1px',
|
||||
height: isFirstLine ? 40 : 41,
|
||||
zIndex: 3,
|
||||
'& .MuiOutlinedInput-root': {
|
||||
height: isFirstLine ? 40 : 41,
|
||||
borderRadius,
|
||||
width: '100%',
|
||||
...(isFieldDirty && {
|
||||
bgcolor: 'rgba(237, 108, 2, 0.08)',
|
||||
}),
|
||||
'&:hover': {
|
||||
zIndex: 4,
|
||||
},
|
||||
'&.Mui-focused': {
|
||||
zIndex: 5,
|
||||
},
|
||||
},
|
||||
'&.Mui-focused': {
|
||||
zIndex: 2,
|
||||
},
|
||||
},
|
||||
...(isFieldDirty && {
|
||||
zIndex: 1,
|
||||
'& .MuiOutlinedInput-notchedOutline': {
|
||||
borderColor: 'warning.main',
|
||||
borderWidth: 2,
|
||||
borderWidth: '1px !important',
|
||||
borderColor: isFieldDirty
|
||||
? 'warning.main'
|
||||
: isError
|
||||
? 'error.main'
|
||||
: 'rgba(0, 0, 0, 0.23)',
|
||||
},
|
||||
'&.Mui-focused .MuiOutlinedInput-notchedOutline': {
|
||||
borderWidth: '1px !important',
|
||||
borderColor: isFieldDirty
|
||||
? 'warning.main'
|
||||
: isError
|
||||
? 'error.main'
|
||||
: 'primary.main',
|
||||
},
|
||||
'&:hover .MuiOutlinedInput-notchedOutline': {
|
||||
borderColor: 'warning.main',
|
||||
borderWidth: '1px !important',
|
||||
borderColor: isFieldDirty
|
||||
? 'warning.main'
|
||||
: isError
|
||||
? 'error.main'
|
||||
: 'rgba(0, 0, 0, 0.87)',
|
||||
},
|
||||
'& input[type=number]': {
|
||||
MozAppearance: 'textfield',
|
||||
},
|
||||
'& input[type=number]::-webkit-outer-spin-button, & input[type=number]::-webkit-inner-spin-button':
|
||||
{
|
||||
WebkitAppearance: 'none',
|
||||
margin: 0,
|
||||
},
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
const hasValue = val != null && String(val).trim() !== '';
|
||||
|
||||
return (
|
||||
<Box
|
||||
tabIndex={isDisabled ? -1 : 0}
|
||||
role={isDisabled ? undefined : 'button'}
|
||||
onClick={() => this.handleStartEdit(id)}
|
||||
onFocus={() => this.handleStartEdit(id)}
|
||||
onKeyDown={(e) => {
|
||||
if (e.key === 'Enter' || e.key === ' ') {
|
||||
e.preventDefault();
|
||||
this.handleStartEdit(id);
|
||||
}
|
||||
}}
|
||||
title={titleText}
|
||||
sx={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: align === 'right' ? 'flex-end' : align === 'center' ? 'center' : 'flex-start',
|
||||
height: isFirstLine ? 40 : 41,
|
||||
minHeight: isFirstLine ? 40 : 41,
|
||||
maxHeight: isFirstLine ? 40 : 41,
|
||||
boxSizing: 'border-box',
|
||||
position: 'relative',
|
||||
ml: isFirstInput ? 0 : '-1px',
|
||||
width: isFirstInput ? '100%' : 'calc(100% + 1px)',
|
||||
mt: isFirstLine ? 0 : '-1px',
|
||||
px: '14px',
|
||||
py: 0,
|
||||
borderRadius,
|
||||
border: '1px solid',
|
||||
borderColor: isFieldDirty
|
||||
? 'warning.main'
|
||||
: isError
|
||||
? 'error.main'
|
||||
: 'rgba(0, 0, 0, 0.23)',
|
||||
cursor: isDisabled ? 'default' : 'text',
|
||||
touchAction: 'manipulation',
|
||||
userSelect: 'none',
|
||||
zIndex: 1,
|
||||
...(isFieldDirty && {
|
||||
bgcolor: 'rgba(237, 108, 2, 0.08)',
|
||||
zIndex: 2,
|
||||
}),
|
||||
'& input[type=number]': {
|
||||
MozAppearance: 'textfield',
|
||||
},
|
||||
'& input[type=number]::-webkit-outer-spin-button, & input[type=number]::-webkit-inner-spin-button':
|
||||
{
|
||||
WebkitAppearance: 'none',
|
||||
margin: 0,
|
||||
...(isError && !isFieldDirty && {
|
||||
bgcolor: 'rgba(211, 47, 47, 0.04)',
|
||||
borderColor: 'error.main',
|
||||
zIndex: 2,
|
||||
}),
|
||||
'&:hover': isDisabled
|
||||
? undefined
|
||||
: {
|
||||
bgcolor: isFieldDirty
|
||||
? 'rgba(237, 108, 2, 0.14)'
|
||||
: isError
|
||||
? 'rgba(211, 47, 47, 0.08)'
|
||||
: 'action.hover',
|
||||
borderColor: isFieldDirty
|
||||
? 'warning.main'
|
||||
: isError
|
||||
? 'error.main'
|
||||
: 'rgba(0, 0, 0, 0.87)',
|
||||
zIndex: 3,
|
||||
},
|
||||
'&:focus-visible': {
|
||||
outline: '2px solid',
|
||||
outlineColor: 'primary.main',
|
||||
outlineOffset: -2,
|
||||
zIndex: 4,
|
||||
},
|
||||
}}
|
||||
/>
|
||||
>
|
||||
<Typography
|
||||
variant="body2"
|
||||
sx={{
|
||||
textAlign: align,
|
||||
width: '100%',
|
||||
overflow: 'hidden',
|
||||
textOverflow: 'ellipsis',
|
||||
whiteSpace: 'nowrap',
|
||||
fontSize: '0.875rem',
|
||||
lineHeight: '20px',
|
||||
fontWeight: id === 'sku' ? 600 : 400,
|
||||
color: isError
|
||||
? 'error.main'
|
||||
: hasValue
|
||||
? 'text.primary'
|
||||
: 'text.disabled',
|
||||
fontStyle: 'normal',
|
||||
}}
|
||||
>
|
||||
{hasValue ? String(val) : '—'}
|
||||
</Typography>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -979,7 +1136,11 @@ class ManifestFormLine extends PureComponent {
|
||||
sx={{
|
||||
p: 0,
|
||||
width: col.width,
|
||||
verticalAlign: 'middle',
|
||||
minWidth: col.width,
|
||||
height: 40,
|
||||
verticalAlign: 'top',
|
||||
position: 'relative',
|
||||
overflow: 'visible',
|
||||
}}
|
||||
>
|
||||
{this.renderField(col, colIdx, columns.length)}
|
||||
|
||||
Reference in New Issue
Block a user