This commit is contained in:
seb
2026-10-28 00:08:45 +01:00
parent fab291f68e
commit 96d0ae6742
88 changed files with 3871 additions and 5334 deletions

View File

@@ -6,12 +6,11 @@ import companyAutomat from '../../automats/companyAutomat';
import { bootstrapAuthMe } from '../../automats/authAutomat';
import BackendError from '../../components/BackendError';
import { ArticleView } from '../../components/article';
import {
artikelAutomat,
import artikelAutomat, {
createArticleSelector,
getArticle,
setLastArticleSku,
} from '../../automats';
} from '../../automats/artikelAutomat';
import { setLastArticleSku } from '../../automats/navigationAutomat';
import withSkuRoute from '../../components/article/withSkuRoute';
/** Full-screen loading state while the shared article cache resolves. */

View File

@@ -26,9 +26,8 @@ import {
ROOT_CATEGORY_NAME,
} from '../../components/category/categoryRoute';
import categoryAutomat from '../../automats/categoryAutomat';
import posterminalAutomat from '../../automats/posterminalAutomat';
import companyAutomat from '../../automats/companyAutomat';
import { setLastArticleSku, setLastCategorySlug, setLastCategoryId } from '../../automats';
import { setLastArticleSku, setLastCategorySlug, setLastCategoryId } from '../../automats/navigationAutomat';
import {
categoryDisplayName,
getCategoryBreadcrumbs,
@@ -86,7 +85,7 @@ class ArtikelKategorienPage extends PureComponent {
loaded: view?.loaded ?? false,
loading: view?.loading ?? false,
routeError: view?.error ?? null,
...selectTerminals(posterminalAutomat.state),
...selectTerminals(companyAutomat.state),
companyId: companyAutomat.state.current?.id ?? null,
moveCategory: null,
};
@@ -100,8 +99,8 @@ class ArtikelKategorienPage extends PureComponent {
setLastArticleSku(null);
setLastCategorySlug(this.props.categorySlugPath);
this._unsubCat = categoryAutomat.subscribe(this, selectFromCategory);
this._unsubTerm = posterminalAutomat.subscribe(this, selectTerminals);
this._unsubCompany = companyAutomat.subscribe(this, (s) => ({
terminals: s.terminals,
companyId: s.current?.id ?? null,
}));
this.ensureTreeLoaded();
@@ -138,7 +137,6 @@ class ArtikelKategorienPage extends PureComponent {
componentWillUnmount() {
setLastCategorySlug(this.props.categorySlugPath);
this._unsubCat?.();
this._unsubTerm?.();
this._unsubCompany?.();
this._unsubHandle?.();
this.sortableModule?.destroy();
@@ -197,7 +195,7 @@ class ArtikelKategorienPage extends PureComponent {
ensurePosterminalsLoaded = () => {
const { companyId } = this.state;
if (!companyId) return;
void posterminalAutomat.actions.load();
void companyAutomat.actions.loadTerminals();
};
syncCategoryFromUrl = () => {
@@ -472,8 +470,8 @@ class ArtikelKategorienPage extends PureComponent {
categoryPosterminalIds: item.posterminalIds || [],
onTerminalToggle: (terminalId, enabled) => {
const action = enabled
? posterminalAutomat.actions.enableCategory
: posterminalAutomat.actions.disableCategory;
? companyAutomat.actions.enableCategory
: companyAutomat.actions.disableCategory;
void action({ terminalId, categoryId: item.id })
.then(() => {
categoryAutomat.actions.patchCategoryPosterminalIds({

View File

@@ -13,8 +13,8 @@ import { PanelTile, PanelTileGrid } from 'dashgui/panels';
import withNavigate from '../../components/withNavigate';
import { backendErrorFrom } from '../../utils/backendError';
import { notifyError } from '../../utils/notify';
import { setLastArticleSku } from '../../automats';
import warehouseAutomat from '../../automats/warehouseAutomat';
import { setLastArticleSku } from '../../automats/navigationAutomat';
import companyAutomat from '../../automats/companyAutomat';
import { ArtikelLager } from '../../components/warehouse';
import { GREEN_PANEL } from '../../colors';
@@ -37,20 +37,20 @@ function getInitialParams(props) {
class ArtikelLagerSearchField extends PureComponent {
constructor(props) {
super(props);
const initial = warehouseAutomat.state.filter || props.prefill || '';
const initial = companyAutomat.state.warehouseFilter || props.prefill || '';
this.state = {
input: initial,
submitting: false,
};
if (props.prefill && !warehouseAutomat.state.filter) {
warehouseAutomat.actions.filter(props.prefill);
if (props.prefill && !companyAutomat.state.warehouseFilter) {
companyAutomat.actions.filterWarehouses(props.prefill);
}
this.handleSubmit = this.handleSubmit.bind(this);
}
componentDidMount() {
this.unsub = warehouseAutomat.subscribe(this, (state) => ({
input: state.filter,
this.unsub = companyAutomat.subscribe(this, (state) => ({
input: state.warehouseFilter,
}));
}
@@ -60,7 +60,7 @@ class ArtikelLagerSearchField extends PureComponent {
onInputChange(input) {
this.setState({ input });
warehouseAutomat.actions.filter(input);
companyAutomat.actions.filterWarehouses(input);
}
async handleSubmit() {
@@ -69,10 +69,10 @@ class ArtikelLagerSearchField extends PureComponent {
this.setState({ submitting: true });
try {
const row = await warehouseAutomat.actions.create({ name });
const row = await companyAutomat.actions.createWarehouse({ name });
enqueueSnackbar(`Lager „${row.name || name}“ angelegt.`, { variant: 'success' });
this.setState({ input: '', submitting: false });
warehouseAutomat.actions.filter('');
companyAutomat.actions.filterWarehouses('');
if (this.props.returnTo && this.props.navigate) {
this.props.navigate(this.props.returnTo);
}
@@ -157,12 +157,12 @@ class ArtikelLagerPage extends PureComponent {
constructor(props) {
super(props);
const initialWarehouses =
warehouseAutomat.state.filteredWarehouses ?? warehouseAutomat.state.warehouses ?? [];
companyAutomat.state.filteredWarehouses ?? companyAutomat.state.warehouses ?? [];
this.state = {
status: warehouseAutomat.state.status === 'ready' ? 'ready' : 'loading',
error: warehouseAutomat.state.error ? backendErrorFrom(warehouseAutomat.state.error) : null,
status: companyAutomat.state.warehousesStatus === 'ready' ? 'ready' : 'loading',
error: companyAutomat.state.warehousesError ? backendErrorFrom(companyAutomat.state.warehousesError) : null,
warehouses: initialWarehouses,
filter: warehouseAutomat.state.filter ?? '',
filter: companyAutomat.state.warehouseFilter ?? '',
};
this.searchRef = createRef();
this.listRef = createRef();
@@ -177,15 +177,15 @@ class ArtikelLagerPage extends PureComponent {
setLastArticleSku(null);
this._cancelled = false;
this.unsub = warehouseAutomat.subscribe(this, (state) => ({
this.unsub = companyAutomat.subscribe(this, (state) => ({
warehouses: state.filteredWarehouses ?? state.warehouses,
filter: state.filter ?? '',
status: state.status,
error: state.error ? backendErrorFrom(state.error) : null,
filter: state.warehouseFilter ?? '',
status: state.warehousesStatus,
error: state.warehousesError ? backendErrorFrom(state.warehousesError) : null,
}));
if (warehouseAutomat.state.status !== 'ready') {
void warehouseAutomat.actions.load().catch((err) => notifyError(err));
if (companyAutomat.state.warehousesStatus !== 'ready') {
void companyAutomat.actions.loadWarehouses().catch((err) => notifyError(err));
} else {
this._initSortable();
}
@@ -249,16 +249,16 @@ class ArtikelLagerPage extends PureComponent {
async _persistOrder(warehouseIds) {
try {
await warehouseAutomat.actions.reorder(warehouseIds);
await companyAutomat.actions.reorderWarehouses(warehouseIds);
} catch (err) {
if (this._cancelled) return;
notifyError(err);
void warehouseAutomat.actions.reload();
void companyAutomat.actions.reloadWarehouses();
}
}
handleRetry() {
void warehouseAutomat.actions.load().catch((err) => notifyError(err));
void companyAutomat.actions.loadWarehouses().catch((err) => notifyError(err));
}
render() {

View File

@@ -8,8 +8,8 @@ import FillSpace from 'dashgui/FillSpace';
import { PanelTile, PanelTileGrid } from 'dashgui/panels';
import { backendErrorFrom } from '../../utils/backendError';
import { notifyError } from '../../utils/notify';
import { setLastArticleSku } from '../../automats';
import brandAutomat from '../../automats/brandAutomat';
import { setLastArticleSku } from '../../automats/navigationAutomat';
import companyAutomat from '../../automats/companyAutomat';
import { enqueueSnackbar } from 'notistack';
import {
ArtikelMarke,
@@ -22,9 +22,9 @@ import {
class ArtikelMarkenSearchField extends PureComponent {
constructor(props) {
super(props);
const brands = brandAutomat.state.brands || [];
const brands = companyAutomat.state.brands || [];
this.state = {
input: brandAutomat.state.filter ?? '',
input: companyAutomat.state.brandFilter ?? '',
submitting: false,
deletingUnused: false,
unusedCount: brands.filter((b) => (b.articleCount ?? 0) === 0).length,
@@ -34,8 +34,8 @@ class ArtikelMarkenSearchField extends PureComponent {
}
componentDidMount() {
this.unsub = brandAutomat.subscribe(this, (state) => ({
input: state.filter,
this.unsub = companyAutomat.subscribe(this, (state) => ({
input: state.brandFilter,
unusedCount: (state.brands || []).filter((b) => (b.articleCount ?? 0) === 0).length,
}));
}
@@ -46,7 +46,7 @@ class ArtikelMarkenSearchField extends PureComponent {
onInputChange(input) {
this.setState({ input });
brandAutomat.actions.filter(input);
companyAutomat.actions.filterBrands(input);
}
async handleSubmit() {
@@ -55,10 +55,10 @@ class ArtikelMarkenSearchField extends PureComponent {
this.setState({ submitting: true });
try {
const row = await brandAutomat.actions.create({ name });
const row = await companyAutomat.actions.createBrand({ name });
enqueueSnackbar(`Marke „${row.name || name}“ angelegt.`, { variant: 'success' });
this.setState({ input: '', submitting: false });
brandAutomat.actions.filter('');
companyAutomat.actions.filterBrands('');
} catch (err) {
this.setState({ submitting: false });
notifyError(err);
@@ -67,7 +67,7 @@ class ArtikelMarkenSearchField extends PureComponent {
async handleDeleteUnused() {
if (this.state.deletingUnused) return;
const allBrands = brandAutomat.state.brands || [];
const allBrands = companyAutomat.state.brands || [];
const unused = allBrands.filter((b) => (b.articleCount ?? 0) === 0);
if (!unused.length) return;
@@ -77,7 +77,7 @@ class ArtikelMarkenSearchField extends PureComponent {
this.setState({ deletingUnused: true });
try {
await brandAutomat.actions.removeBrands(unused.map((b) => b.id));
await companyAutomat.actions.removeBrands(unused.map((b) => b.id));
enqueueSnackbar(`${unused.length} ungenutzte Marken gelöscht.`, { variant: 'success' });
} catch (err) {
notifyError(err);
@@ -148,10 +148,10 @@ class ArtikelMarkenPage extends PureComponent {
constructor(props) {
super(props);
this.state = {
status: brandAutomat.state.status,
error: brandAutomat.state.error ? backendErrorFrom({ message: brandAutomat.state.error }) : null,
brands: brandAutomat.state.filteredBrands ?? brandAutomat.state.brands,
totalCount: brandAutomat.state.brands?.length ?? 0,
status: companyAutomat.state.brandsStatus,
error: companyAutomat.state.brandsError ? backendErrorFrom({ message: companyAutomat.state.brandsError }) : null,
brands: companyAutomat.state.filteredBrands ?? companyAutomat.state.brands,
totalCount: companyAutomat.state.brands?.length ?? 0,
};
this.searchRef = createRef();
this.handleRetry = this.handleRetry.bind(this);
@@ -160,11 +160,11 @@ class ArtikelMarkenPage extends PureComponent {
componentDidMount() {
setLastArticleSku(null);
this.unsub = brandAutomat.subscribe(this, (state) => ({
this.unsub = companyAutomat.subscribe(this, (state) => ({
brands: state.filteredBrands,
totalCount: state.brands?.length ?? 0,
status: state.status,
error: state.error ? backendErrorFrom({ message: state.error }) : null,
status: state.brandsStatus,
error: state.brandsError ? backendErrorFrom({ message: state.brandsError }) : null,
}));
}
@@ -173,7 +173,7 @@ class ArtikelMarkenPage extends PureComponent {
}
handleRetry() {
void brandAutomat.actions.load().catch((err) => notifyError(err));
void companyAutomat.actions.loadBrands().catch((err) => notifyError(err));
}
render() {

View File

@@ -4,7 +4,7 @@ import TuneIcon from '@mui/icons-material/Tune';
import StyleIcon from '@mui/icons-material/Style';
import { TabbedPanelTileGrid } from 'dashgui/panels';
import withNavigate from '../../components/withNavigate';
import { setLastArticleSku } from '../../automats';
import { setLastArticleSku } from '../../automats/navigationAutomat';
import {
AuswahlMerkmaleTab,
TextMerkmaleTab,

View File

@@ -22,7 +22,7 @@ import BackendError from '../../components/BackendError';
import { PanelTile, PanelTileGrid } from 'dashgui/panels';
import { backendErrorFrom } from '../../utils/backendError';
import { notifyError } from '../../utils/notify';
import { setLastArticleSku } from '../../automats';
import { setLastArticleSku } from '../../automats/navigationAutomat';
import { labeltemplate } from '../../api';
import { enqueueSnackbar } from 'notistack';
import {