import { Component } from 'react'; import DeleteOutlineOutlinedIcon from '@mui/icons-material/DeleteOutlineOutlined'; import Box from '@mui/material/Box'; import Button from '@mui/material/Button'; import Chip from '@mui/material/Chip'; import CircularProgress from '@mui/material/CircularProgress'; import AppDialog from '../AppDialog'; import DialogActions from '@mui/material/DialogActions'; import DialogContent from '@mui/material/DialogContent'; import DialogTitle from '@mui/material/DialogTitle'; import IconButton from '@mui/material/IconButton'; import List from '@mui/material/List'; import ListItem from '@mui/material/ListItem'; import ListItemButton from '@mui/material/ListItemButton'; import ListItemText from '@mui/material/ListItemText'; import TextInput from '../TextInput'; import Typography from '@mui/material/Typography'; import companyAutomat from '../../automats/companyAutomat'; import { unit as unitApi } from '../../api'; import { requireObject } from '../../utils/apiShape'; import { notifyError } from '../../utils/notify'; import { parsePriceInput } from '../../utils/price'; import { COMMON_UNITS, DEFAULT_UNIT_SI, unitLabel } from '../../utils/units'; function emptyForm() { return { si: '', basesi: '', basesifactor: '1', symbol: '', name: '', }; } function formFromUnit(row) { // API may return null symbol/name (e.g. default pc). return { si: row.si ?? '', basesi: row.basesi ?? '', basesifactor: String(row.basesifactor ?? '1'), symbol: row.symbol ?? '', name: row.name ?? '', }; } function parseFactor(value) { return parsePriceInput(value); } function formValid(form) { const si = String(form.si ?? '').trim(); const basesi = String(form.basesi ?? '').trim(); const symbol = String(form.symbol ?? '').trim(); const name = String(form.name ?? '').trim(); const factor = parseFactor(form.basesifactor); return ( si.length > 0 && basesi.length > 0 && symbol.length > 0 && name.length > 0 && factor != null && factor > 0 ); } export default class ArticleUnitEditorDialog extends Component { constructor(props) { super(props); this.state = { busy: false, units: companyAutomat.state.units, unitsLoading: companyAutomat.state.unitsStatus === 'loading', form: emptyForm(), selectedSi: null, }; } componentDidMount() { this.unsub = companyAutomat.subscribe(this, (state) => ({ units: state.units, unitsLoading: state.unitsStatus === 'loading', })); } componentWillUnmount() { this.unsub?.(); } componentDidUpdate(prevProps) { if (this.props.open && !prevProps.open) { this.setState({ form: emptyForm(), selectedSi: null }); } } handleSelectUnit = (row) => { this.setState({ form: formFromUnit(row), selectedSi: row.si }); }; handlePreset = (preset) => { this.setState({ form: formFromUnit(preset), selectedSi: preset.si }); }; handleField = (field, value) => { this.setState((state) => { const form = { ...state.form, [field]: value }; if (field === 'si' && (!state.form.basesi || state.form.basesi === state.form.si)) { form.basesi = value; } return { form }; }); }; handleSave = async () => { const { form } = this.state; if (!formValid(form)) return; this.setState({ busy: true }); try { const payload = { si: String(form.si ?? '').trim(), basesi: String(form.basesi ?? '').trim(), basesifactor: parseFactor(form.basesifactor), symbol: String(form.symbol ?? '').trim(), name: String(form.name ?? '').trim(), }; const units = await companyAutomat.actions.upsertUnit(payload); const saved = units.find((u) => u.si === payload.si) ?? payload; this.setState({ busy: false, units, form: formFromUnit(saved), selectedSi: saved.si, }); this.props.onUnitUpserted?.(saved); } catch (err) { this.setState({ busy: false }); notifyError(err); } }; handleDelete = async () => { const { selectedSi } = this.state; if (!selectedSi || selectedSi === DEFAULT_UNIT_SI) return; this.setState({ busy: true }); try { await companyAutomat.actions.deleteUnit(selectedSi); this.setState({ busy: false, units: companyAutomat.state.units, form: emptyForm(), selectedSi: null, }); this.props.onUnitDeleted?.(selectedSi); } catch (err) { this.setState({ busy: false }); notifyError(err); } }; handleNew = () => { this.setState({ form: emptyForm(), selectedSi: null }); }; render() { const { open, onClose } = this.props; const { busy, form, selectedSi, units, unitsLoading } = this.state; const canSave = formValid(form) && !busy; const loading = unitsLoading && units.length === 0; return ( Einheiten Typische Einheiten {COMMON_UNITS.map((preset) => ( this.handlePreset(preset)} disabled={busy} /> ))} Firma {loading ? ( ) : ( {units.map((row) => ( void this.handleDelete()} > ) : null } > this.handleSelectUnit(row)} > ))} {units.length === 0 ? ( Noch keine Einheiten. ) : null} )} this.handleField('name', e.target.value)} fullWidth disabled={busy} /> this.handleField('symbol', e.target.value)} fullWidth disabled={busy} /> this.handleField('si', e.target.value)} fullWidth disabled={busy} /> this.handleField('basesi', e.target.value)} fullWidth disabled={busy} /> this.handleField('basesifactor', e.target.value)} fullWidth disabled={busy} error={ form.basesifactor !== '' && (parseFactor(form.basesifactor) == null || parseFactor(form.basesifactor) <= 0) } slotProps={{ htmlInput: { inputMode: 'decimal' }, }} /> ); } }