This commit is contained in:
seb
2026-08-05 08:40:12 +02:00
parent a9e942df7a
commit 66f88e395b
12 changed files with 176 additions and 140 deletions

View File

@@ -1,5 +1,4 @@
import { Component } from 'react';
import { connect } from 'react-redux';
import DeleteOutlineOutlinedIcon from '@mui/icons-material/DeleteOutlineOutlined';
import Box from '@mui/material/Box';
import Button from '@mui/material/Button';
@@ -16,16 +15,11 @@ import ListItemButton from '@mui/material/ListItemButton';
import ListItemText from '@mui/material/ListItemText';
import TextField from '@mui/material/TextField';
import Typography from '@mui/material/Typography';
import { StorageManagerContext } from '../../api/storageManager';
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';
import {
deleteUnit,
loadUnits,
selectUnits,
selectUnitsStatus,
upsertUnit,
} from '../../store/unitSlice';
function emptyForm() {
return {
@@ -68,11 +62,15 @@ function formValid(form) {
);
}
class ArticleUnitEditorDialog extends Component {
export default class ArticleUnitEditorDialog extends Component {
static contextType = StorageManagerContext;
constructor(props) {
super(props);
this.state = {
busy: false,
units: [],
unitsLoading: false,
form: emptyForm(),
selectedSi: null,
};
@@ -81,9 +79,18 @@ class ArticleUnitEditorDialog extends Component {
componentDidUpdate(prevProps) {
if (this.props.open && !prevProps.open) {
this.setState({ form: emptyForm(), selectedSi: null });
if (this.props.status !== 'succeeded') {
void this.props.loadUnits().catch((err) => notifyError(err));
}
void this.loadUnits();
}
}
async loadUnits() {
this.setState({ unitsLoading: true });
try {
const units = await this.context.unitPromise;
this.setState({ units, unitsLoading: false });
} catch (err) {
this.setState({ unitsLoading: false });
notifyError(err);
}
}
@@ -110,19 +117,23 @@ class ArticleUnitEditorDialog extends Component {
if (!formValid(form)) return;
this.setState({ busy: true });
try {
const unit = await this.props.upsertUnit({
const data = await this.context.unit.upsert({
si: String(form.si ?? '').trim(),
basesi: String(form.basesi ?? '').trim(),
basesifactor: parseFactor(form.basesifactor),
symbol: String(form.symbol ?? '').trim(),
name: String(form.name ?? '').trim(),
}).unwrap();
});
requireObject(data, 'PUT /api/unit');
requireObject(data.unit, 'unit');
const units = await this.context.updateUnit();
this.setState({
busy: false,
form: formFromUnit(unit),
selectedSi: unit.si,
units,
form: formFromUnit(data.unit),
selectedSi: data.unit.si,
});
this.props.onUnitUpserted?.(unit);
this.props.onUnitUpserted?.(data.unit);
} catch (err) {
this.setState({ busy: false });
notifyError(err);
@@ -134,8 +145,9 @@ class ArticleUnitEditorDialog extends Component {
if (!selectedSi || selectedSi === DEFAULT_UNIT_SI) return;
this.setState({ busy: true });
try {
await this.props.deleteUnit(selectedSi).unwrap();
this.setState({ busy: false, form: emptyForm(), selectedSi: null });
await this.context.unit.delete(selectedSi);
const units = await this.context.updateUnit();
this.setState({ busy: false, units, form: emptyForm(), selectedSi: null });
this.props.onUnitDeleted?.(selectedSi);
} catch (err) {
this.setState({ busy: false });
@@ -148,10 +160,10 @@ class ArticleUnitEditorDialog extends Component {
};
render() {
const { open, onClose, units, status } = this.props;
const { busy, form, selectedSi } = this.state;
const { open, onClose } = this.props;
const { busy, form, selectedSi, units, unitsLoading } = this.state;
const canSave = formValid(form) && !busy;
const loading = status === 'loading' && units.length === 0;
const loading = unitsLoading && units.length === 0;
return (
<Dialog open={open} onClose={busy ? undefined : onClose} maxWidth="md" fullWidth>
@@ -302,16 +314,3 @@ class ArticleUnitEditorDialog extends Component {
);
}
}
const mapStateToProps = (state) => ({
units: selectUnits(state),
status: selectUnitsStatus(state),
});
const mapDispatchToProps = (dispatch) => ({
loadUnits: () => dispatch(loadUnits()),
upsertUnit: (body) => dispatch(upsertUnit(body)),
deleteUnit: (si) => dispatch(deleteUnit(si)),
});
export default connect(mapStateToProps, mapDispatchToProps)(ArticleUnitEditorDialog);