Fix manifest list create/edit navigation after Vite HMR.
Keep a single browser router across hot reloads and drive ManifestList/Form via withNavigate instead of a stale router.navigate singleton.
This commit is contained in:
@@ -26,7 +26,7 @@ const KundeGruppenPage = lazy(() => import('./pages/kunde/gruppen'));
|
|||||||
const KundeEditPage = lazy(() => import('./pages/kunde/edit'));
|
const KundeEditPage = lazy(() => import('./pages/kunde/edit'));
|
||||||
const InfosPage = lazy(() => import('./pages/infos/index'));
|
const InfosPage = lazy(() => import('./pages/infos/index'));
|
||||||
|
|
||||||
export const router = createBrowserRouter([
|
const routes = [
|
||||||
{
|
{
|
||||||
path: '/',
|
path: '/',
|
||||||
element: <AppShell />,
|
element: <AppShell />,
|
||||||
@@ -64,14 +64,9 @@ export const router = createBrowserRouter([
|
|||||||
children: [
|
children: [
|
||||||
{ index: true, element: <AuftragAngebotPage /> },
|
{ index: true, element: <AuftragAngebotPage /> },
|
||||||
{ path: 'neu', element: <AuftragAngebotNeuPage /> },
|
{ path: 'neu', element: <AuftragAngebotNeuPage /> },
|
||||||
{
|
{ path: 'bestellung', element: <AuftragBestellungPage /> },
|
||||||
path: 'bestellung',
|
{ path: 'bestellung/neu', element: <AuftragBestellungNeuPage /> },
|
||||||
children: [
|
{ path: 'bestellung/:orderId', element: <AuftragBestellungEditPage /> },
|
||||||
{ index: true, element: <AuftragBestellungPage /> },
|
|
||||||
{ path: 'neu', element: <AuftragBestellungNeuPage /> },
|
|
||||||
{ path: ':orderId', element: <AuftragBestellungEditPage /> },
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{ path: 'ausliefern', element: <AuftragAusliefernPage /> },
|
{ path: 'ausliefern', element: <AuftragAusliefernPage /> },
|
||||||
{ path: 'retoure', element: <AuftragRetourePage /> },
|
{ path: 'retoure', element: <AuftragRetourePage /> },
|
||||||
{ path: ':quoteId', element: <AuftragAngebotEditPage /> },
|
{ path: ':quoteId', element: <AuftragAngebotEditPage /> },
|
||||||
@@ -90,4 +85,12 @@ export const router = createBrowserRouter([
|
|||||||
{ path: '*', element: <Navigate to="/artikel" replace /> },
|
{ path: '*', element: <Navigate to="/artikel" replace /> },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
]);
|
];
|
||||||
|
|
||||||
|
/** Keep one router across Vite HMR — recreating breaks navigate()/Link mid-session. */
|
||||||
|
export const router =
|
||||||
|
import.meta.hot?.data?.router ?? createBrowserRouter(routes);
|
||||||
|
|
||||||
|
if (import.meta.hot) {
|
||||||
|
import.meta.hot.data.router = router;
|
||||||
|
}
|
||||||
|
|||||||
@@ -6,10 +6,10 @@ import { enqueueSnackbar } from 'notistack';
|
|||||||
import BackendError from '../BackendError';
|
import BackendError from '../BackendError';
|
||||||
import { PanelTile, PanelTileGrid } from '../panels';
|
import { PanelTile, PanelTileGrid } from '../panels';
|
||||||
import { StorageManagerContext } from '../../api/storageManagerContext';
|
import { StorageManagerContext } from '../../api/storageManagerContext';
|
||||||
import { router } from '../../appRouter';
|
|
||||||
import { requireArray, requireDefined, requireObject } from '../../utils/apiShape';
|
import { requireArray, requireDefined, requireObject } from '../../utils/apiShape';
|
||||||
import { backendErrorFrom } from '../../utils/backendError';
|
import { backendErrorFrom } from '../../utils/backendError';
|
||||||
import { notifyError } from '../../utils/notify';
|
import { notifyError } from '../../utils/notify';
|
||||||
|
import withNavigate from '../withNavigate';
|
||||||
import ManifestHeader from './ManifestHeader';
|
import ManifestHeader from './ManifestHeader';
|
||||||
import ManifestLines from './ManifestLines';
|
import ManifestLines from './ManifestLines';
|
||||||
import {
|
import {
|
||||||
@@ -209,7 +209,7 @@ class ManifestForm extends PureComponent {
|
|||||||
await this.context[cfg.updateCache]();
|
await this.context[cfg.updateCache]();
|
||||||
if (this._cancelled) return;
|
if (this._cancelled) return;
|
||||||
enqueueSnackbar(cfg.createdMsg, { variant: 'success' });
|
enqueueSnackbar(cfg.createdMsg, { variant: 'success' });
|
||||||
void router.navigate(cfg.editPath(data[cfg.docField].id));
|
this.props.navigate(cfg.editPath(data[cfg.docField].id));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -318,4 +318,4 @@ class ManifestForm extends PureComponent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default ManifestForm;
|
export default withNavigate(ManifestForm);
|
||||||
|
|||||||
@@ -17,9 +17,9 @@ import { enqueueSnackbar } from 'notistack';
|
|||||||
import BackendError from '../BackendError';
|
import BackendError from '../BackendError';
|
||||||
import { PanelTile, PanelTileGrid } from '../panels';
|
import { PanelTile, PanelTileGrid } from '../panels';
|
||||||
import { StorageManagerContext } from '../../api/storageManagerContext';
|
import { StorageManagerContext } from '../../api/storageManagerContext';
|
||||||
import { router } from '../../appRouter';
|
|
||||||
import { backendErrorFrom } from '../../utils/backendError';
|
import { backendErrorFrom } from '../../utils/backendError';
|
||||||
import { notifyError } from '../../utils/notify';
|
import { notifyError } from '../../utils/notify';
|
||||||
|
import withNavigate from '../withNavigate';
|
||||||
import {
|
import {
|
||||||
formatDate,
|
formatDate,
|
||||||
loadParties,
|
loadParties,
|
||||||
@@ -79,12 +79,22 @@ class ManifestList extends PureComponent {
|
|||||||
void this.load();
|
void this.load();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Same path as AppShell sub-nav: live useNavigate via withNavigate. */
|
||||||
|
go(to) {
|
||||||
|
const { navigate } = this.props;
|
||||||
|
if (typeof navigate === 'function') {
|
||||||
|
navigate(to);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
window.location.assign(to);
|
||||||
|
}
|
||||||
|
|
||||||
handleCreate() {
|
handleCreate() {
|
||||||
void router.navigate(this.cfg.createPath);
|
this.go(this.cfg.createPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
handleEdit(doc) {
|
handleEdit(doc) {
|
||||||
void router.navigate(this.cfg.editPath(doc.id));
|
this.go(this.cfg.editPath(doc.id));
|
||||||
}
|
}
|
||||||
|
|
||||||
async handleDelete(doc) {
|
async handleDelete(doc) {
|
||||||
@@ -139,7 +149,12 @@ class ManifestList extends PureComponent {
|
|||||||
<PanelTile wide={3} minHeight={240} color={cfg.listColor}>
|
<PanelTile wide={3} minHeight={240} color={cfg.listColor}>
|
||||||
<Stack spacing={2}>
|
<Stack spacing={2}>
|
||||||
<Box sx={{ display: 'flex', justifyContent: 'flex-end' }}>
|
<Box sx={{ display: 'flex', justifyContent: 'flex-end' }}>
|
||||||
<Button variant="contained" size="small" onClick={this.handleCreate}>
|
<Button
|
||||||
|
type="button"
|
||||||
|
variant="contained"
|
||||||
|
size="small"
|
||||||
|
onClick={this.handleCreate}
|
||||||
|
>
|
||||||
{cfg.createButton}
|
{cfg.createButton}
|
||||||
</Button>
|
</Button>
|
||||||
</Box>
|
</Box>
|
||||||
@@ -175,6 +190,7 @@ class ManifestList extends PureComponent {
|
|||||||
onClick={(e) => e.stopPropagation()}
|
onClick={(e) => e.stopPropagation()}
|
||||||
>
|
>
|
||||||
<IconButton
|
<IconButton
|
||||||
|
type="button"
|
||||||
size="small"
|
size="small"
|
||||||
aria-label={`„${row.number}“ bearbeiten`}
|
aria-label={`„${row.number}“ bearbeiten`}
|
||||||
onClick={() => this.handleEdit(row)}
|
onClick={() => this.handleEdit(row)}
|
||||||
@@ -182,6 +198,7 @@ class ManifestList extends PureComponent {
|
|||||||
<EditOutlinedIcon fontSize="small" />
|
<EditOutlinedIcon fontSize="small" />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
<IconButton
|
<IconButton
|
||||||
|
type="button"
|
||||||
size="small"
|
size="small"
|
||||||
aria-label={`„${row.number}“ löschen`}
|
aria-label={`„${row.number}“ löschen`}
|
||||||
disabled={busyId != null}
|
disabled={busyId != null}
|
||||||
@@ -203,4 +220,4 @@ class ManifestList extends PureComponent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default ManifestList;
|
export default withNavigate(ManifestList);
|
||||||
|
|||||||
Reference in New Issue
Block a user