This commit is contained in:
seb
2026-08-03 05:11:50 +02:00
parent 5b5c77f870
commit 4db4948090
14 changed files with 1410 additions and 1178 deletions

View File

@@ -0,0 +1,96 @@
import Autocomplete from '@mui/material/Autocomplete';
import TextField from '@mui/material/TextField';
import Typography from '@mui/material/Typography';
import Box from '@mui/material/Box';
import { EditablePanelTile } from '../../panels';
import { article } from '../../../api';
import { requireObject } from '../../../utils/apiShape';
import { articleEans } from '../../../utils/articleDetail';
import { PANEL_TILE_KEYS } from '../../../theme';
function PanelValue({ label, children }) {
if (children == null || children === '') return null;
return (
<Box sx={{ mb: 1 }}>
{label ? (
<Typography variant="caption" color="text.secondary" display="block">
{label}
</Typography>
) : null}
<Typography variant="body2" component="div">
{children}
</Typography>
</Box>
);
}
function eansDraftValue(article) {
return { eans: articleEans(article) };
}
function eansDraftDirty(draft, saved) {
return JSON.stringify(draft.eans ?? []) !== JSON.stringify(saved.eans ?? []);
}
function eansDraftValid(draft) {
return (draft.eans ?? []).every(
(ean) => typeof ean === 'string' && ean.trim().length > 0,
);
}
const SECOND_ROW_MIN_HEIGHT = 220;
export default function ArticleViewEANs({ article: articleData, onArticleUpdated }) {
const handleSave = async (draft) => {
const eans = (draft.eans ?? [])
.map((ean) => String(ean).trim())
.filter((ean) => ean.length > 0);
const res = await article.setEansBySku(articleData.sku, eans);
requireObject(res, 'PUT /api/article/:sku/eans');
requireObject(res.article, 'article');
onArticleUpdated?.(res.article);
};
return (
<EditablePanelTile
wide={1}
tileKey={PANEL_TILE_KEYS.identifiers}
title="SKU / EAN"
minHeight={SECOND_ROW_MIN_HEIGHT}
contentAlignItems="flex-start"
value={eansDraftValue(articleData)}
onSave={handleSave}
isDirty={eansDraftDirty}
canSave={eansDraftValid}
renderDisplay={(saved) => (
<>
<PanelValue label="SKU">{articleData.sku}</PanelValue>
{(saved.eans ?? []).map((ean) => (
<PanelValue key={ean} label="EAN">
{ean}
</PanelValue>
))}
</>
)}
renderEdit={(draft, onChange, inputRef) => (
<Autocomplete
fullWidth
multiple
freeSolo
options={[]}
value={draft.eans ?? []}
onChange={(_event, eans) => onChange({ eans })}
renderInput={(params) => (
<TextField
{...params}
inputRef={inputRef}
label="EANs (Enter zum Hinzufügen)"
size="small"
slotProps={{ inputLabel: { shrink: true } }}
/>
)}
/>
)}
/>
);
}