u
This commit is contained in:
@@ -68,28 +68,27 @@ export default class ArticleUnitEditorDialog extends Component {
|
||||
super(props);
|
||||
this.state = {
|
||||
busy: false,
|
||||
units: [],
|
||||
unitsLoading: 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 });
|
||||
void this.loadUnits();
|
||||
}
|
||||
}
|
||||
|
||||
async loadUnits() {
|
||||
this.setState({ unitsLoading: true });
|
||||
try {
|
||||
const units = await companyAutomat.actions.loadUnits();
|
||||
this.setState({ units, unitsLoading: false });
|
||||
} catch (err) {
|
||||
this.setState({ unitsLoading: false });
|
||||
notifyError(err);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -116,23 +115,22 @@ export default class ArticleUnitEditorDialog extends Component {
|
||||
if (!formValid(form)) return;
|
||||
this.setState({ busy: true });
|
||||
try {
|
||||
const data = await unitApi.upsert({
|
||||
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(),
|
||||
});
|
||||
requireObject(data, 'PUT /api/unit');
|
||||
requireObject(data.unit, 'unit');
|
||||
const units = await companyAutomat.actions.loadUnits();
|
||||
};
|
||||
const units = await companyAutomat.actions.upsertUnit(payload);
|
||||
const saved = units.find((u) => u.si === payload.si) ?? payload;
|
||||
this.setState({
|
||||
busy: false,
|
||||
units,
|
||||
form: formFromUnit(data.unit),
|
||||
selectedSi: data.unit.si,
|
||||
form: formFromUnit(saved),
|
||||
selectedSi: saved.si,
|
||||
});
|
||||
this.props.onUnitUpserted?.(data.unit);
|
||||
this.props.onUnitUpserted?.(saved);
|
||||
} catch (err) {
|
||||
this.setState({ busy: false });
|
||||
notifyError(err);
|
||||
@@ -144,9 +142,13 @@ export default class ArticleUnitEditorDialog extends Component {
|
||||
if (!selectedSi || selectedSi === DEFAULT_UNIT_SI) return;
|
||||
this.setState({ busy: true });
|
||||
try {
|
||||
await unitApi.delete(selectedSi);
|
||||
const units = await companyAutomat.actions.loadUnits();
|
||||
this.setState({ busy: false, units, form: emptyForm(), selectedSi: null });
|
||||
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 });
|
||||
|
||||
@@ -82,9 +82,7 @@ class AuswahlMerkmaleTab extends PureComponent {
|
||||
}
|
||||
}, ['attributes', 'attributesStatus', 'attributesError']);
|
||||
|
||||
if (companyAutomat.state.attributesStatus !== 'succeeded') {
|
||||
void this.load();
|
||||
} else {
|
||||
if (companyAutomat.state.attributesStatus === 'succeeded') {
|
||||
this._initAttrSortable();
|
||||
this._initValSortable();
|
||||
}
|
||||
|
||||
@@ -65,9 +65,7 @@ class TextMerkmaleTab extends PureComponent {
|
||||
}
|
||||
}, ['properties', 'propertiesStatus', 'propertiesError']);
|
||||
|
||||
if (companyAutomat.state.propertiesStatus !== 'succeeded') {
|
||||
void this.load();
|
||||
} else {
|
||||
if (companyAutomat.state.propertiesStatus === 'succeeded') {
|
||||
this._initPropSortable();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,8 +45,6 @@ export default class CompanySettingsPanel extends Component {
|
||||
});
|
||||
if (companyAutomat.state.current) {
|
||||
this.syncFormFromCompany(companyAutomat.state.current);
|
||||
} else {
|
||||
void this.loadCompany();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Component } from 'react';
|
||||
import { PureComponent } from 'react';
|
||||
import Alert from '@mui/material/Alert';
|
||||
import Box from '@mui/material/Box';
|
||||
import CircularProgress from '@mui/material/CircularProgress';
|
||||
@@ -17,7 +17,7 @@ import { enqueueSnackbar } from 'notistack';
|
||||
import BackendError from '../BackendError';
|
||||
import { number as numberApi } from '../../api';
|
||||
import companyAutomat from '../../automats/companyAutomat';
|
||||
import { requireArray, requireDefined, requireObject } from '../../utils/apiShape';
|
||||
import { requireDefined, requireObject } from '../../utils/apiShape';
|
||||
import { backendErrorFrom } from '../../utils/backendError';
|
||||
import { notifyError } from '../../utils/notify';
|
||||
|
||||
@@ -31,44 +31,76 @@ function parseNext(value) {
|
||||
return Number.isInteger(n) && n >= 0 ? n : null;
|
||||
}
|
||||
|
||||
export default class NumberSettingsPanel extends Component {
|
||||
function buildDrafts(numbers, prevDrafts = {}) {
|
||||
return Object.fromEntries(
|
||||
(Array.isArray(numbers) ? numbers : []).map((row) => {
|
||||
const existing = prevDrafts[row.id];
|
||||
return [
|
||||
row.id,
|
||||
existing?.busy
|
||||
? existing
|
||||
: {
|
||||
prefix: row.prefix ?? '',
|
||||
padding: row.padding != null ? String(row.padding) : '',
|
||||
next: row.next != null ? String(row.next) : '',
|
||||
busy: false,
|
||||
saveError: null,
|
||||
},
|
||||
];
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
export default class NumberSettingsPanel extends PureComponent {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
const numbers = Array.isArray(companyAutomat.state.numbers)
|
||||
? companyAutomat.state.numbers
|
||||
: [];
|
||||
const numbersStatus = companyAutomat.state.numbersStatus;
|
||||
this.state = {
|
||||
status: 'loading',
|
||||
error: null,
|
||||
numbers: [],
|
||||
status:
|
||||
numbersStatus === 'ready'
|
||||
? 'ready'
|
||||
: numbersStatus === 'failed'
|
||||
? 'failed'
|
||||
: 'loading',
|
||||
error: companyAutomat.state.numbersError
|
||||
? backendErrorFrom(companyAutomat.state.numbersError)
|
||||
: null,
|
||||
numbers,
|
||||
// id → { prefix, padding, next, busy, saveError }
|
||||
drafts: {},
|
||||
drafts: buildDrafts(numbers),
|
||||
};
|
||||
this.handleRetry = this.handleRetry.bind(this);
|
||||
this.handleSave = this.handleSave.bind(this);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
void this.load();
|
||||
this._unmounted = false;
|
||||
this.unsub = companyAutomat.subscribe(this, (state) => {
|
||||
const numbers = Array.isArray(state.numbers) ? state.numbers : [];
|
||||
return {
|
||||
status:
|
||||
state.numbersStatus === 'ready'
|
||||
? 'ready'
|
||||
: state.numbersStatus === 'failed'
|
||||
? 'failed'
|
||||
: 'loading',
|
||||
error: state.numbersError ? backendErrorFrom(state.numbersError) : null,
|
||||
numbers,
|
||||
drafts:
|
||||
numbers !== this.state.numbers
|
||||
? buildDrafts(numbers, this.state.drafts)
|
||||
: this.state.drafts,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
async load() {
|
||||
this.setState({ status: 'loading', error: null });
|
||||
try {
|
||||
const numbers = requireArray(
|
||||
await companyAutomat.actions.reloadNumbers(),
|
||||
'numbers',
|
||||
);
|
||||
const drafts = Object.fromEntries(
|
||||
numbers.map((row) => [
|
||||
row.id,
|
||||
{
|
||||
prefix: row.prefix ?? '',
|
||||
padding: row.padding != null ? String(row.padding) : '',
|
||||
next: row.next != null ? String(row.next) : '',
|
||||
busy: false,
|
||||
saveError: null,
|
||||
},
|
||||
]),
|
||||
);
|
||||
this.setState({ status: 'ready', numbers, drafts });
|
||||
await companyAutomat.actions.reloadNumbers();
|
||||
} catch (err) {
|
||||
notifyError(err);
|
||||
this.setState({ status: 'failed', error: backendErrorFrom(err) });
|
||||
@@ -145,8 +177,9 @@ export default class NumberSettingsPanel extends Component {
|
||||
requireObject(data.number, 'number');
|
||||
const updated = requireDefined(data.number, 'number');
|
||||
|
||||
const numbers = this.state.numbers.map((n) => (n.id === id ? { ...n, ...body } : n));
|
||||
await companyAutomat.actions.reloadNumbers();
|
||||
const numbers = companyAutomat.actions.replaceNumbers(
|
||||
this.state.numbers.map((n) => (n.id === id ? { ...n, ...updated } : n)),
|
||||
);
|
||||
this.setState({
|
||||
numbers,
|
||||
drafts: {
|
||||
@@ -174,6 +207,7 @@ export default class NumberSettingsPanel extends Component {
|
||||
|
||||
componentWillUnmount() {
|
||||
this._unmounted = true;
|
||||
this.unsub?.();
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
@@ -78,9 +78,6 @@ export default class PosTerminalSettingsPanel extends Component {
|
||||
if (categoryAutomat.state.treeStatus === 'idle') {
|
||||
void categoryAutomat.actions.loadTree();
|
||||
}
|
||||
if (companyAutomat.state.terminalsStatus !== 'succeeded') {
|
||||
void this.loadTerminals();
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
@@ -120,7 +117,6 @@ export default class PosTerminalSettingsPanel extends Component {
|
||||
await whenCategoryTreeReady();
|
||||
}
|
||||
|
||||
await companyAutomat.actions.loadTerminals();
|
||||
this.setState({ newTerminalName: '' });
|
||||
enqueueSnackbar('Terminal hinzugefügt.', { variant: 'success' });
|
||||
} catch (err) {
|
||||
@@ -134,7 +130,6 @@ export default class PosTerminalSettingsPanel extends Component {
|
||||
this.setState({ deletingId: terminal.id });
|
||||
try {
|
||||
await companyAutomat.actions.deleteTerminal(terminal.id);
|
||||
await companyAutomat.actions.loadTerminals();
|
||||
enqueueSnackbar('Terminal gelöscht.', { variant: 'info' });
|
||||
} catch (err) {
|
||||
notifyError(err);
|
||||
|
||||
Reference in New Issue
Block a user