Directly patch posterminalIds in Redux instead of reloading the category tree

After toggling a POS category, update the category's posterminalIds array
in-place rather than re-fetching the entire tree. This keeps the settings
cycle open on the same terminal. Also fix off-by-one in terminal cycling
and ensure posterminals load on category page mount.
This commit is contained in:
seb
2026-08-03 07:22:08 +02:00
parent f302eb9e67
commit 4bbe9caf55
4 changed files with 33 additions and 4 deletions

View File

@@ -283,7 +283,7 @@ export class CategoryEditTile extends Component {
const terminalCount = terminals?.length || 0; const terminalCount = terminals?.length || 0;
this.setState((prev) => { this.setState((prev) => {
const next = prev.settingsTab + 1; const next = prev.settingsTab + 1;
const nextTab = next > terminalCount ? -1 : next; const nextTab = next >= terminalCount ? -1 : next;
console.log('[CategoryEditTile] settings toggle', { console.log('[CategoryEditTile] settings toggle', {
terminals: terminals?.length, terminals: terminals?.length,
terminalCount, terminalCount,

View File

@@ -21,7 +21,7 @@ import {
import withCategoryRoute from './withCategoryRoute'; import withCategoryRoute from './withCategoryRoute';
import { artikelDetailPath, articleSku } from './articleRoute'; import { artikelDetailPath, articleSku } from './articleRoute';
import { selectCompanyId } from '../../store/companySlice'; import { selectCompanyId } from '../../store/companySlice';
import { selectHasPosterminals, selectPosterminals } from '../../store/posterminalSlice'; import { selectHasPosterminals, selectPosterminals, loadPosterminals } from '../../store/posterminalSlice';
import { import {
buildCategoryPath, buildCategoryPath,
defaultCategoryPath, defaultCategoryPath,
@@ -47,6 +47,7 @@ import {
selectCategoryTreeStatus, selectCategoryTreeStatus,
selectChildCategories, selectChildCategories,
selectRenameMode, selectRenameMode,
patchCategoryPosterminalIds,
} from '../../store/categorySlice'; } from '../../store/categorySlice';
import { import {
enableTerminalCategory, enableTerminalCategory,
@@ -72,6 +73,7 @@ class ArtikelKategorienPage extends Component {
componentDidMount() { componentDidMount() {
this.ensureTreeLoaded(); this.ensureTreeLoaded();
this.ensurePosterminalsLoaded();
this.syncCategoryFromUrl(); this.syncCategoryFromUrl();
this.ensureArticlesLoaded(); this.ensureArticlesLoaded();
this.syncSortable(); this.syncSortable();
@@ -158,6 +160,12 @@ class ArtikelKategorienPage extends Component {
this.props.loadCategoryTree(); this.props.loadCategoryTree();
}; };
ensurePosterminalsLoaded = () => {
const { companyId } = this.props;
if (!companyId) return;
this.props.loadPosterminals();
};
ensureArticlesLoaded = () => { ensureArticlesLoaded = () => {
const { currentCategoryId, articlesStatus, rootCategoryId, treeStatus } = this.props; const { currentCategoryId, articlesStatus, rootCategoryId, treeStatus } = this.props;
if (treeStatus !== 'succeeded' || !currentCategoryId || articlesStatus !== 'idle') return; if (treeStatus !== 'succeeded' || !currentCategoryId || articlesStatus !== 'idle') return;
@@ -356,7 +364,13 @@ class ArtikelKategorienPage extends Component {
: this.props.disableTerminalCategory; : this.props.disableTerminalCategory;
void thunk({ terminalId, categoryId: item.id }) void thunk({ terminalId, categoryId: item.id })
.unwrap() .unwrap()
.then(() => this.props.loadCategoryTree()) .then(() => {
this.props.patchCategoryPosterminalIds({
categoryId: item.id,
terminalId,
enabled,
});
})
.catch(notifyError); .catch(notifyError);
}} }}
onOpen={() => this.navigateToCategoryById(item.id)} onOpen={() => this.navigateToCategoryById(item.id)}
@@ -456,6 +470,7 @@ const mapStateToProps = (state) => ({
const mapDispatchToProps = { const mapDispatchToProps = {
loadCategoryTree, loadCategoryTree,
loadCategoryArticles, loadCategoryArticles,
loadPosterminals,
navigateToCategory, navigateToCategory,
renameCategory, renameCategory,
deleteCategory, deleteCategory,
@@ -464,6 +479,7 @@ const mapDispatchToProps = {
toggleCategoryPos, toggleCategoryPos,
enableTerminalCategory, enableTerminalCategory,
disableTerminalCategory, disableTerminalCategory,
patchCategoryPosterminalIds,
}; };
export default withCategoryRoute(connect(mapStateToProps, mapDispatchToProps)(ArtikelKategorienPage)); export default withCategoryRoute(connect(mapStateToProps, mapDispatchToProps)(ArtikelKategorienPage));

View File

@@ -291,6 +291,17 @@ const categorySlice = createSlice({
resetCategoryState() { resetCategoryState() {
return initialState; return initialState;
}, },
patchCategoryPosterminalIds(state, action) {
const { categoryId, terminalId, enabled } = action.payload;
const cat = state.categories?.[String(categoryId)];
if (!cat) return;
if (!Array.isArray(cat.posterminalIds)) cat.posterminalIds = [];
if (enabled && !cat.posterminalIds.includes(terminalId)) {
cat.posterminalIds.push(terminalId);
} else if (!enabled) {
cat.posterminalIds = cat.posterminalIds.filter((id) => id !== terminalId);
}
},
setRenameMode(state, action) { setRenameMode(state, action) {
state.renameMode = Boolean(action.payload); state.renameMode = Boolean(action.payload);
}, },
@@ -451,6 +462,7 @@ export const {
setRenameMode, setRenameMode,
removeArticleBySku, removeArticleBySku,
patchArticleInLists, patchArticleInLists,
patchCategoryPosterminalIds,
} = categorySlice.actions; } = categorySlice.actions;
export const selectRenameMode = (state) => state.category.renameMode; export const selectRenameMode = (state) => state.category.renameMode;

View File

@@ -253,8 +253,9 @@ export function posterminalLoadListener(listenerMiddleware) {
loginWithGoogle.fulfilled.match(action) || loginWithGoogle.fulfilled.match(action) ||
selectCompany.fulfilled.match(action) || selectCompany.fulfilled.match(action) ||
createCompany.fulfilled.match(action), createCompany.fulfilled.match(action),
effect: async (_action, api) => { effect: async (action, api) => {
const companyId = api.getState().auth.user?.selectedCompanyId; const companyId = api.getState().auth.user?.selectedCompanyId;
console.log('[posterminalLoadListener]', action.type, { companyId });
if (companyId) { if (companyId) {
api.dispatch(loadPosterminals()); api.dispatch(loadPosterminals());
} }