This commit is contained in:
seb
2026-10-04 21:04:40 +02:00
parent 669954b496
commit f765b87336
59 changed files with 1491 additions and 2045 deletions

View File

@@ -20,15 +20,16 @@ import EditOutlinedIcon from '@mui/icons-material/EditOutlined';
import LocalShippingOutlinedIcon from '@mui/icons-material/LocalShippingOutlined';
import { enqueueSnackbar } from 'notistack';
import { StorageManagerContext } from '../../../api/storageManagerContext';
import { article as articleApi } from '../../../api';
import { notifyError } from '../../../utils/notify';
import { formatPrice } from '../../../utils/price';
import supplierAutomat from '../../../automats/supplierAutomat';
import { articleSupplierAutomat } from '../../../automats/articleDetailAutomat';
import sseAutomat from '../../../automats/sseAutomat';
import companyAutomat from '../../../automats/companyAutomat';
import ArticleSupplierDialog from '../ArticleSupplierDialog';
export default class ArticleSupplierTab extends PureComponent {
static contextType = StorageManagerContext;
constructor(props) {
super(props);
this.state = {
@@ -40,10 +41,12 @@ export default class ArticleSupplierTab extends PureComponent {
editItem: null,
busyId: null,
};
this.unwatchSuppliers = null;
}
componentDidMount() {
this.unsubCompany = companyAutomat.subscribe(this, (state) => ({
company: state.current ?? null,
}));
this.initData();
}
@@ -54,46 +57,53 @@ export default class ArticleSupplierTab extends PureComponent {
}
componentWillUnmount() {
this.unwatchSuppliers?.();
this.unwatchSuppliers = null;
this.unsubSuppliers?.();
this.unsubSuppliers = null;
this.unwatchSignal?.();
this.unwatchSignal = null;
this.unsubCompany?.();
this.unsubCompany = null;
}
async initData() {
const sku = this.props.article?.sku;
if (!sku) return;
this.unwatchSuppliers?.();
this.setState({ loading: true });
// 1. Subscribe to SSE-backed supplier updates
const { unwatch, refresh } = this.context.article.supplierWatch(
sku,
(assignedSuppliers) => {
this.setState({
assignedSuppliers: assignedSuppliers ?? [],
loading: false,
});
},
);
this.unwatchSuppliers = unwatch;
this.refreshSuppliers = refresh;
// 2. Fetch available company suppliers and company metadata
try {
const [companySuppliers, company] = await Promise.all([
supplierAutomat.actions.load(),
this.context.company ?? this.context.companyPromise,
]);
// 1. Subscribe to the keyed supplier cache and the article SSE signal
this.unsubSuppliers?.();
const handle = articleSupplierAutomat.key(String(sku));
this.unsubSuppliers = handle.subscribe(this, (item) => {
this.setState({
companySuppliers: companySuppliers ?? [],
company: company ?? null,
assignedSuppliers: Array.isArray(item.data) ? item.data : [],
loading: false,
});
});
void articleSupplierAutomat.load(String(sku)).catch((err) => {
if (this.unsubSuppliers) notifyError(err);
});
this.unwatchSignal?.();
this.unwatchSignal = sseAutomat.actions.watchArticle(String(sku), () => {
void articleSupplierAutomat.reload(String(sku)).catch(() => {});
});
// 2. Fetch available company suppliers
try {
const companySuppliers = await supplierAutomat.actions.load();
this.setState({ companySuppliers: companySuppliers ?? [] });
} catch (err) {
notifyError(err);
this.setState({ loading: false });
}
}
/** Re-fetches the assigned suppliers for the current article. */
refreshSuppliers = async () => {
const sku = this.props.article?.sku;
if (!sku) return;
await articleSupplierAutomat.reload(String(sku));
};
handleOpenAdd = () => {
this.setState({ dialogOpen: true, editItem: null });
};
@@ -112,7 +122,7 @@ export default class ArticleSupplierTab extends PureComponent {
try {
if (payload.id) {
await this.context.article.updateSupplier(sku, payload.id, {
await articleApi.updateSupplier(sku, payload.id, {
sku: payload.sku,
pu: payload.pu,
stock: payload.stock,
@@ -121,7 +131,7 @@ export default class ArticleSupplierTab extends PureComponent {
});
enqueueSnackbar('Lieferantendaten aktualisiert', { variant: 'success' });
} else {
await this.context.article.addSupplier(sku, {
await articleApi.addSupplier(sku, {
entityId: payload.entityId,
sku: payload.sku,
pu: payload.pu,
@@ -132,7 +142,7 @@ export default class ArticleSupplierTab extends PureComponent {
enqueueSnackbar('Lieferant erfolgreich zugewiesen', { variant: 'success' });
}
this.handleCloseDialog();
await this.refreshSuppliers?.();
await this.refreshSuppliers();
} catch (err) {
notifyError(err);
throw err;
@@ -150,9 +160,9 @@ export default class ArticleSupplierTab extends PureComponent {
this.setState({ busyId: item.id });
try {
await this.context.article.deleteSupplier(sku, item.id);
await articleApi.deleteSupplier(sku, item.id);
enqueueSnackbar('Lieferant entfernt', { variant: 'success' });
await this.refreshSuppliers?.();
await this.refreshSuppliers();
} catch (err) {
notifyError(err);
} finally {
@@ -176,11 +186,11 @@ export default class ArticleSupplierTab extends PureComponent {
this.setState({ assignedSuppliers: nextList, busyId: moved.id });
try {
await this.context.article.orderSuppliers(sku, { ids });
await this.refreshSuppliers?.();
await articleApi.orderSuppliers(sku, ids);
await this.refreshSuppliers();
} catch (err) {
notifyError(err);
await this.refreshSuppliers?.();
await this.refreshSuppliers();
} finally {
this.setState({ busyId: null });
}