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

@@ -40,16 +40,13 @@ import { preserveSearchFocus } from '../components/article/searchFocus';
import { artikelDetailPath } from '../components/article/articleRoute';
import { buildCategoryPath } from '../components/category/categoryRoute';
import withSearchParams from '../components/article/withSearchParams';
import {
import navigationAutomat, {
setLastArticleSku,
setLastSearchTerm,
setLastCategoryId,
navigationAutomat,
categoryAutomat,
companyAutomat,
brandAutomat,
supplierAutomat,
} from '../automats';
} from '../automats/navigationAutomat';
import categoryAutomat from '../automats/categoryAutomat';
import companyAutomat from '../automats/companyAutomat';
import { BrandLabel, BrandThumb } from '../components/brand';
import { SCRIM_LABEL } from '../colors';
// #endregion
@@ -358,12 +355,14 @@ class ArtikelSearchPage extends Component {
// Push search results into local component state.
this.unsubSearch = articleSearchAutomat.subscribe(this, (state) => state.result);
this.unsubBrand = brandAutomat.subscribe(this, () => ({}));
this.unsubSupplier = supplierAutomat.subscribe(this, () => ({}));
this.unsubCompany = companyAutomat.subscribe(this, (state) => ({
_brands: state.brands,
_suppliers: state.suppliers,
}));
void brandAutomat.actions.load().catch(() => {});
void supplierAutomat.actions.load().catch(() => {});
void supplierAutomat.actions.loadAllSupplierArticles().catch(() => {});
void companyAutomat.actions.loadBrands().catch(() => {});
void companyAutomat.actions.loadSuppliers().catch(() => {});
void companyAutomat.actions.loadAllSupplierArticles().catch(() => {});
// Initial search: kicks off index loading if idle and derives current items
const {
@@ -410,10 +409,8 @@ class ArtikelSearchPage extends Component {
document.removeEventListener('mouseup', preserveSearchFocus, true);
this.unsubSearch?.();
this.unsubSearch = null;
this.unsubBrand?.();
this.unsubBrand = null;
this.unsubSupplier?.();
this.unsubSupplier = null;
this.unsubCompany?.();
this.unsubCompany = null;
this.persistQuery();
const query = queryFromParams(this.props.searchParams);
const target = this.state.input;
@@ -711,7 +708,7 @@ class ArtikelSearchPage extends Component {
{selectedBrands.map((brandId) => {
const label =
brandFacets?.[brandId]?.name ||
brandAutomat.state.brands?.find((b) => String(b.id) === String(brandId) || b.name === brandId)?.name ||
companyAutomat.state.brands?.find((b) => String(b.id) === String(brandId) || b.name === brandId)?.name ||
brandId;
return (
<Chip
@@ -737,7 +734,7 @@ class ArtikelSearchPage extends Component {
{selectedSuppliers.map((supplierId) => {
const label =
supplierFacets?.[supplierId]?.name ||
supplierAutomat.state.suppliers?.find((s) => String(s.id) === String(supplierId))?.name ||
companyAutomat.state.suppliers?.find((s) => String(s.id) === String(supplierId))?.name ||
`Lieferant #${supplierId}`;
return (
<Chip

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 {

View File

@@ -12,14 +12,14 @@ import { PanelTile, PanelTileGrid } from 'dashgui/panels';
import withNavigate from '../../components/withNavigate';
import { backendErrorFrom } from '../../utils/backendError';
import { notifyError } from '../../utils/notify';
import carrierAutomat from '../../automats/carrierAutomat';
import companyAutomat from '../../automats/companyAutomat';
import { CarrierItem } from '../../components/carrier';
import { GREEN_PANEL } from '../../colors';
class VersandartenSearchField extends PureComponent {
constructor(props) {
super(props);
const initial = carrierAutomat.state.filter || '';
const initial = companyAutomat.state.carrierFilter || '';
this.state = {
input: initial,
submitting: false,
@@ -28,8 +28,8 @@ class VersandartenSearchField extends PureComponent {
}
componentDidMount() {
this.unsub = carrierAutomat.subscribe(this, (state) => ({
input: state.filter,
this.unsub = companyAutomat.subscribe(this, (state) => ({
input: state.carrierFilter,
}));
}
@@ -39,7 +39,7 @@ class VersandartenSearchField extends PureComponent {
onInputChange(input) {
this.setState({ input });
carrierAutomat.actions.filter(input);
companyAutomat.actions.filterCarriers(input);
}
async handleSubmit() {
@@ -48,14 +48,14 @@ class VersandartenSearchField extends PureComponent {
this.setState({ submitting: true });
try {
const row = await carrierAutomat.actions.create({
const row = await companyAutomat.actions.createCarrier({
name,
hasPackages: true,
isReverse: false,
});
enqueueSnackbar(`Versandart „${row.name || name}“ angelegt.`, { variant: 'success' });
this.setState({ input: '', submitting: false });
carrierAutomat.actions.filter('');
companyAutomat.actions.filterCarriers('');
} catch (err) {
this.setState({ submitting: false });
notifyError(err);
@@ -118,12 +118,12 @@ class AuftragVersandartenPage extends PureComponent {
constructor(props) {
super(props);
const initialCarriers =
carrierAutomat.state.filteredCarriers ?? carrierAutomat.state.carriers ?? [];
companyAutomat.state.filteredCarriers ?? companyAutomat.state.carriers ?? [];
this.state = {
status: carrierAutomat.state.status === 'ready' ? 'ready' : 'loading',
error: carrierAutomat.state.error ? backendErrorFrom(carrierAutomat.state.error) : null,
status: companyAutomat.state.carriersStatus === 'ready' ? 'ready' : 'loading',
error: companyAutomat.state.carriersError ? backendErrorFrom(companyAutomat.state.carriersError) : null,
carriers: initialCarriers,
filter: carrierAutomat.state.filter ?? '',
filter: companyAutomat.state.carrierFilter ?? '',
};
this.searchRef = createRef();
this.listRef = createRef();
@@ -137,15 +137,15 @@ class AuftragVersandartenPage extends PureComponent {
componentDidMount() {
this._cancelled = false;
this.unsub = carrierAutomat.subscribe(this, (state) => ({
this.unsub = companyAutomat.subscribe(this, (state) => ({
carriers: state.filteredCarriers ?? state.carriers,
filter: state.filter ?? '',
status: state.status,
error: state.error ? backendErrorFrom(state.error) : null,
filter: state.carrierFilter ?? '',
status: state.carriersStatus,
error: state.carriersError ? backendErrorFrom(state.carriersError) : null,
}));
if (carrierAutomat.state.status !== 'ready') {
void carrierAutomat.actions.load().catch((err) => notifyError(err));
if (companyAutomat.state.carriersStatus !== 'ready') {
void companyAutomat.actions.loadCarriers().catch((err) => notifyError(err));
} else {
this._initSortable();
}
@@ -209,16 +209,16 @@ class AuftragVersandartenPage extends PureComponent {
async _persistOrder(carrierIds) {
try {
await carrierAutomat.actions.reorder(carrierIds);
await companyAutomat.actions.reorderCarriers(carrierIds);
} catch (err) {
if (this._cancelled) return;
notifyError(err);
void carrierAutomat.actions.reload();
void companyAutomat.actions.reloadCarriers();
}
}
handleRetry() {
void carrierAutomat.actions.load().catch((err) => notifyError(err));
void companyAutomat.actions.loadCarriers().catch((err) => notifyError(err));
}
render() {

View File

@@ -13,7 +13,7 @@ import withNavigate from '../components/withNavigate';
import { backendErrorFrom } from '../utils/backendError';
import { notifyError } from '../utils/notify';
import entityAutomat from '../automats/entityAutomat';
import customergroupAutomat from '../automats/customergroupAutomat';
import companyAutomat from '../automats/companyAutomat';
import { getLowestSortNonSupplierCustomerGroup } from '../components/manifest/manifestConfig';
import { Kunde } from '../components/kunde';
import { BLUE_PANEL } from '../colors';
@@ -69,8 +69,8 @@ class KundeSearchField extends PureComponent {
this.setState({ submitting: true });
try {
await customergroupAutomat.actions.ensureLoaded();
const groups = customergroupAutomat.state.items ?? [];
await companyAutomat.actions.ensureCustomergroupsLoaded();
const groups = companyAutomat.state.customergroups ?? [];
const defaultGroup = getLowestSortNonSupplierCustomerGroup(groups) ?? groups[0];
if (!defaultGroup) {
throw new Error('Keine Kundengruppe vorhanden.');
@@ -190,7 +190,7 @@ class KundeListePage extends PureComponent {
status: entityAutomat.state.status === 'ready' ? 'ready' : 'loading',
error: entityAutomat.state.error ? backendErrorFrom(entityAutomat.state.error) : null,
entities: initialEntities,
groups: customergroupAutomat.state.items ?? [],
groups: companyAutomat.state.customergroups ?? [],
filter: entityAutomat.state.filter ?? '',
};
this.searchRef = createRef();
@@ -206,15 +206,15 @@ class KundeListePage extends PureComponent {
error: state.error ? backendErrorFrom(state.error) : null,
}));
this.unsubGroups = customergroupAutomat.subscribe(this, (state) => ({
groups: state.items,
this.unsubGroups = companyAutomat.subscribe(this, (state) => ({
groups: state.customergroups,
}));
if (entityAutomat.state.status !== 'ready') {
void entityAutomat.actions.load().catch((err) => notifyError(err));
}
if (customergroupAutomat.state.status !== 'ready') {
void customergroupAutomat.actions.load().catch(() => { });
if (companyAutomat.state.customergroupsStatus !== 'ready') {
void companyAutomat.actions.loadCustomergroups().catch(() => { });
}
}

View File

@@ -14,7 +14,7 @@ import SingleLineTextEdit from 'dashgui/SingleLineTextEdit';
import { PanelTile, PanelTileGrid } from 'dashgui/panels';
import { entity as entityApi } from '../../api';
import entityAutomat from '../../automats/entityAutomat';
import customergroupAutomat from '../../automats/customergroupAutomat';
import companyAutomat from '../../automats/companyAutomat';
import { requireArray, requireDefined, requireObject } from '../../utils/apiShape';
import { backendErrorFrom } from '../../utils/backendError';
import { notifyError } from '../../utils/notify';
@@ -137,7 +137,7 @@ class KundeEditPage extends PureComponent {
entityApi.get(entityId),
entityApi.listAddresses(entityId),
entityApi.listContacts(entityId),
customergroupAutomat.actions.ensureLoaded(),
companyAutomat.actions.ensureCustomergroupsLoaded(),
]);
if (this._cancelled) return;

View File

@@ -13,7 +13,7 @@ import { PanelTile, PanelTileGrid } from 'dashgui/panels';
import withNavigate from '../../components/withNavigate';
import { backendErrorFrom } from '../../utils/backendError';
import { notifyError } from '../../utils/notify';
import customergroupAutomat from '../../automats/customergroupAutomat';
import companyAutomat from '../../automats/companyAutomat';
import { KundeGruppe } from '../../components/kunde';
import { PURPLE_BG } from '../../colors';
@@ -36,20 +36,20 @@ function getInitialParams(props) {
class KundeGruppenSearchField extends PureComponent {
constructor(props) {
super(props);
const initial = customergroupAutomat.state.filter || props.prefill || '';
const initial = companyAutomat.state.customergroupFilter || props.prefill || '';
this.state = {
input: initial,
submitting: false,
};
if (props.prefill && !customergroupAutomat.state.filter) {
customergroupAutomat.actions.filter(props.prefill);
if (props.prefill && !companyAutomat.state.customergroupFilter) {
companyAutomat.actions.filterCustomergroups(props.prefill);
}
this.handleSubmit = this.handleSubmit.bind(this);
}
componentDidMount() {
this.unsub = customergroupAutomat.subscribe(this, (state) => ({
input: state.filter,
this.unsub = companyAutomat.subscribe(this, (state) => ({
input: state.customergroupFilter,
}));
}
@@ -59,7 +59,7 @@ class KundeGruppenSearchField extends PureComponent {
onInputChange(input) {
this.setState({ input });
customergroupAutomat.actions.filter(input);
companyAutomat.actions.filterCustomergroups(input);
}
async handleSubmit() {
@@ -68,10 +68,10 @@ class KundeGruppenSearchField extends PureComponent {
this.setState({ submitting: true });
try {
const row = await customergroupAutomat.actions.create({ name });
const row = await companyAutomat.actions.createCustomergroup({ name });
enqueueSnackbar(`Kundengruppe „${row.name || name}“ angelegt.`, { variant: 'success' });
this.setState({ input: '', submitting: false });
customergroupAutomat.actions.filter('');
companyAutomat.actions.filterCustomergroups('');
if (this.props.returnTo && this.props.navigate) {
this.props.navigate(this.props.returnTo);
}
@@ -157,12 +157,12 @@ class KundeGruppenPage extends PureComponent {
constructor(props) {
super(props);
const initialGroups =
customergroupAutomat.state.filteredItems ?? customergroupAutomat.state.items ?? [];
companyAutomat.state.filteredCustomergroups ?? companyAutomat.state.customergroups ?? [];
this.state = {
status: customergroupAutomat.state.status === 'ready' ? 'ready' : 'loading',
error: customergroupAutomat.state.error ? backendErrorFrom(customergroupAutomat.state.error) : null,
status: companyAutomat.state.customergroupsStatus === 'ready' ? 'ready' : 'loading',
error: companyAutomat.state.customergroupsError ? backendErrorFrom(companyAutomat.state.customergroupsError) : null,
groups: initialGroups,
filter: customergroupAutomat.state.filter ?? '',
filter: companyAutomat.state.customergroupFilter ?? '',
};
this.searchRef = createRef();
this.listRef = createRef();
@@ -176,15 +176,15 @@ class KundeGruppenPage extends PureComponent {
componentDidMount() {
this._cancelled = false;
this.unsub = customergroupAutomat.subscribe(this, (state) => ({
groups: state.filteredItems ?? state.items,
filter: state.filter ?? '',
status: state.status,
error: state.error ? backendErrorFrom(state.error) : null,
this.unsub = companyAutomat.subscribe(this, (state) => ({
groups: state.filteredCustomergroups ?? state.customergroups,
filter: state.customergroupFilter ?? '',
status: state.customergroupsStatus,
error: state.customergroupsError ? backendErrorFrom(state.customergroupsError) : null,
}));
if (customergroupAutomat.state.status !== 'ready') {
void customergroupAutomat.actions.load().catch((err) => notifyError(err));
if (companyAutomat.state.customergroupsStatus !== 'ready') {
void companyAutomat.actions.loadCustomergroups().catch((err) => notifyError(err));
} else {
this._initSortable();
}
@@ -248,16 +248,16 @@ class KundeGruppenPage extends PureComponent {
async _persistOrder(customergroupIds) {
try {
await customergroupAutomat.actions.reorder(customergroupIds);
await companyAutomat.actions.reorderCustomergroups(customergroupIds);
} catch (err) {
if (this._cancelled) return;
notifyError(err);
void customergroupAutomat.actions.reload();
void companyAutomat.actions.reloadCustomergroups();
}
}
handleRetry() {
void customergroupAutomat.actions.load().catch((err) => notifyError(err));
void companyAutomat.actions.loadCustomergroups().catch((err) => notifyError(err));
}
render() {

View File

@@ -10,7 +10,7 @@ import SingleLineTextEdit from 'dashgui/SingleLineTextEdit';
import { PanelTile, PanelTileGrid } from 'dashgui/panels';
import { entity as entityApi } from '../../api';
import entityAutomat from '../../automats/entityAutomat';
import customergroupAutomat from '../../automats/customergroupAutomat';
import companyAutomat from '../../automats/companyAutomat';
import { getLowestSortNonSupplierCustomerGroup } from '../../components/manifest/manifestConfig';
import { router } from '../../appRouter';
import { requireDefined, requireObject } from '../../utils/apiShape';
@@ -45,7 +45,7 @@ function getInitialPrefill(props) {
class KundeNeuPage extends PureComponent {
constructor(props) {
super(props);
const groups = customergroupAutomat.state.items ?? [];
const groups = companyAutomat.state.customergroups ?? [];
const defaultGroup = getLowestSortNonSupplierCustomerGroup(groups) ?? groups[0];
const prefill = getInitialPrefill(props);
this.state = {
@@ -62,7 +62,7 @@ class KundeNeuPage extends PureComponent {
componentDidMount() {
void this.loadNumber();
if (this.state.customergroupId == null) {
void customergroupAutomat.actions.ensureLoaded().then((groups) => {
void companyAutomat.actions.ensureCustomergroupsLoaded().then((groups) => {
const defaultGroup = getLowestSortNonSupplierCustomerGroup(groups) ?? groups?.[0];
if (defaultGroup && this.state.customergroupId == null) {
this.setState({ customergroupId: defaultGroup.id });
@@ -125,7 +125,7 @@ class KundeNeuPage extends PureComponent {
render() {
const { customergroupId, number, name, firstName, saving } = this.state;
const groups = customergroupAutomat.state.items ?? [];
const groups = companyAutomat.state.customergroups ?? [];
const canSave =
customergroupId != null && name.trim() !== '' && !saving;

View File

@@ -1,6 +1,6 @@
import { PureComponent } from 'react';
import { DeliveryList } from '../components/manifest';
import { setLastDeliveryPath } from '../automats';
import { setLastDeliveryPath } from '../automats/navigationAutomat';
class LieferungListePage extends PureComponent {
componentDidMount() {

View File

@@ -18,8 +18,8 @@ import { PanelTile, PanelTileGrid } from 'dashgui/panels';
import withNavigate from '../../components/withNavigate';
import { backendErrorFrom } from '../../utils/backendError';
import { notifyError } from '../../utils/notify';
import { setLastDeliveryPath } from '../../automats';
import supplierAutomat from '../../automats/supplierAutomat';
import { setLastDeliveryPath } from '../../automats/navigationAutomat';
import companyAutomat from '../../automats/companyAutomat';
import { deliveryDraftAutomat } from '../../automats/deliveryEditorAutomat';
import {
GREEN_PANEL,
@@ -109,7 +109,7 @@ class LieferungLieferantenPage extends PureComponent {
async loadSuppliers() {
this.setState({ status: 'loading', error: null });
try {
const list = await supplierAutomat.actions.load();
const list = await companyAutomat.actions.loadSuppliers();
if (this._cancelled) return;
this.applySuppliers(list);
} catch (err) {
@@ -123,7 +123,7 @@ class LieferungLieferantenPage extends PureComponent {
}
async refreshFromServer() {
const list = await supplierAutomat.actions.reload();
const list = await companyAutomat.actions.reloadSuppliers();
if (this._cancelled) return;
this.applySuppliers(list);
}
@@ -136,7 +136,7 @@ class LieferungLieferantenPage extends PureComponent {
this.setState({ busyKey: 'new' });
try {
const newSupplier = await supplierAutomat.actions.create({ name });
const newSupplier = await companyAutomat.actions.createSupplier({ name });
// Assign the new supplier to the active delivery draft & clear unmatched name
deliveryDraftAutomat.actions.setDeliveryEntity(newSupplier.id);
@@ -170,7 +170,7 @@ class LieferungLieferantenPage extends PureComponent {
this.setState({ busyKey: supplier.id });
try {
await supplierAutomat.actions.update(supplier.id, { name: draft });
await companyAutomat.actions.updateSupplier(supplier.id, { name: draft });
await this.refreshFromServer();
if (this._cancelled) return;
this.setState({ busyKey: null });
@@ -193,7 +193,7 @@ class LieferungLieferantenPage extends PureComponent {
this.setState({ busyKey: supplier.id });
try {
await supplierAutomat.actions.remove(supplier.id);
await companyAutomat.actions.removeSupplier(supplier.id);
await this.refreshFromServer();
if (this._cancelled) return;
this.setState({ busyKey: null });

View File

@@ -38,8 +38,7 @@ import {
BookDeliveryDialog,
} from '../../components/manifest';
import { loadParties, apiFor, resolveLineSkus, sortSuppliers } from '../../components/manifest/manifestConfig';
import supplierAutomat from '../../automats/supplierAutomat';
import warehouseAutomat from '../../automats/warehouseAutomat';
import companyAutomat, { setViewerPosition } from '../../automats/companyAutomat';
import { article as articleApi, delivery as deliveryApi } from '../../api';
import { getCategoryState } from '../../automats/categoryAutomat';
import { requireArray, requireDefined, requireObject } from '../../utils/apiShape';
@@ -49,7 +48,7 @@ import { generatePdfThumbnail } from '../../utils/pdfThumbnail';
import { generateTextThumbnail } from '../../utils/textThumbnail';
import { extractPdfText } from '../../utils/pdfText';
import { getDeliveryEditorAutomat } from '../../automats/deliveryEditorAutomat';
import { setLastDeliveryPath, userSettingsAutomat, setViewerPosition } from '../../automats';
import { setLastDeliveryPath } from '../../automats/navigationAutomat';
import chatAutomat from '../../automats/chatAutomat';
import { fetchDeliveryLedgerSummary } from '../../utils/deliveryLedger';
@@ -110,10 +109,10 @@ class LieferungNeuPage extends PureComponent {
this.cfg = manifestConfig('delivery');
this.automat = getDeliveryEditorAutomat(props.docId);
if (
supplierAutomat.state.status === 'ready' &&
companyAutomat.state.suppliersStatus === 'ready' &&
(!this.automat.state.deliveryEntities || this.automat.state.deliveryEntities.length === 0)
) {
this.automat.actions.setDeliveryEntities(sortSuppliers(supplierAutomat.state.suppliers));
this.automat.actions.setDeliveryEntities(sortSuppliers(companyAutomat.state.suppliers));
}
const initialDate = this.automat.state.date || (props.docId == null ? todayInputValue() : null);
if (props.docId == null && !this.automat.state.date) {
@@ -129,7 +128,7 @@ class LieferungNeuPage extends PureComponent {
pdfUploading: false,
textEditorOpen: false,
textEditorAttachment: null,
viewerPosition: userSettingsAutomat.state.viewerPosition,
viewerPosition: companyAutomat.state.viewerPosition,
pdfViewerOpen: false,
pdfViewerAttachment: null,
articleSearchDialogOpen: false,
@@ -139,7 +138,7 @@ class LieferungNeuPage extends PureComponent {
bookDeliveryDialogOpen: false,
bookDeliveryPrefillLineId: null,
pdfCreating: false,
warehouses: warehouseAutomat.state.warehouses || [],
warehouses: companyAutomat.state.warehouses || [],
};
this._cancelled = false;
this.handleRetry = this.handleRetry.bind(this);
@@ -183,18 +182,16 @@ class LieferungNeuPage extends PureComponent {
componentDidMount() {
this.unsubscribe = this.automat.subscribe(this);
this._settingsUnsub = userSettingsAutomat.subscribe(this, (state) => ({
viewerPosition: state.viewerPosition,
}));
this._warehouseUnsub = warehouseAutomat.subscribe(this, (state) => ({
warehouses: state.warehouses,
}));
this._supplierUnsub = supplierAutomat.subscribe(this, (state) => {
if (state.status === 'ready' && Array.isArray(state.suppliers)) {
this._companyUnsub = companyAutomat.subscribe(this, (state) => {
if (state.suppliersStatus === 'ready' && Array.isArray(state.suppliers)) {
this.automat.actions.setDeliveryEntities(sortSuppliers(state.suppliers));
}
return {
viewerPosition: state.viewerPosition,
warehouses: state.warehouses,
};
});
void warehouseAutomat.actions.load().catch(() => { });
void companyAutomat.actions.loadWarehouses().catch(() => { });
this._cancelled = false;
if (this.props.docId != null) {
setLastDeliveryPath(`/lieferung/${this.props.docId}`);
@@ -237,9 +234,7 @@ class LieferungNeuPage extends PureComponent {
this._skuDebounceTimers = null;
}
this.unsubscribe?.();
this._settingsUnsub?.();
this._warehouseUnsub?.();
this._supplierUnsub?.();
this._companyUnsub?.();
}
async loadPartiesOnly() {