admin: fix back behavior to not rely on history object

This commit is contained in:
dswbx
2025-07-05 09:42:53 +02:00
parent 109c72e84f
commit b35ee36fb1
4 changed files with 30 additions and 36 deletions

View File

@@ -4,6 +4,7 @@ import { Link, useLocation } from "wouter";
import { IconButton } from "../../components/buttons/IconButton"; import { IconButton } from "../../components/buttons/IconButton";
import { Dropdown } from "../../components/overlay/Dropdown"; import { Dropdown } from "../../components/overlay/Dropdown";
import { useEvent } from "../../hooks/use-event"; import { useEvent } from "../../hooks/use-event";
import { useNavigate } from "ui/lib/routes";
type Breadcrumb = { type Breadcrumb = {
label: string | Element; label: string | Element;
@@ -17,26 +18,11 @@ export type Breadcrumbs2Props = {
}; };
export const Breadcrumbs2 = ({ path: _path, backTo, onBack }: Breadcrumbs2Props) => { export const Breadcrumbs2 = ({ path: _path, backTo, onBack }: Breadcrumbs2Props) => {
const [_, navigate] = useLocation(); const [, , _goBack] = useNavigate();
const location = window.location.pathname;
const path = Array.isArray(_path) ? _path : [_path]; const path = Array.isArray(_path) ? _path : [_path];
const loc = location.split("/").filter((v) => v !== "");
const hasBack = path.length > 1; const hasBack = path.length > 1;
const goBack = onBack const goBack = onBack ? onBack : () => _goBack({ fallback: backTo });
? onBack
: useEvent(() => {
if (backTo) {
navigate(backTo, { replace: true });
return;
} else if (_path.length > 0 && _path[0]?.href) {
navigate(_path[0].href, { replace: true });
return;
}
const href = loc.slice(0, path.length + 1).join("/");
navigate(`~/${href}`, { replace: true });
});
const crumbs = useMemo( const crumbs = useMemo(
() => () =>

View File

@@ -102,13 +102,29 @@ export function useNavigate() {
} }
const _url = options?.absolute ? `~/${basepath}${url}`.replace(/\/+/g, "/") : url; const _url = options?.absolute ? `~/${basepath}${url}`.replace(/\/+/g, "/") : url;
const state = {
...options?.state,
referrer: location,
};
navigate(options?.query ? withQuery(_url, options?.query) : _url, { navigate(options?.query ? withQuery(_url, options?.query) : _url, {
replace: options?.replace, replace: options?.replace,
state: options?.state, state,
}); });
}); });
}, },
location, location,
(opts?: { fallback?: string }) => {
const state = window.history.state;
if (state?.referrer) {
//window.history.replaceState(state, "", state.referrer);
navigate(state.referrer, { replace: true });
} else if (opts?.fallback) {
navigate(opts.fallback, { replace: true });
} else {
window.history.back();
}
},
] as const; ] as const;
} }

View File

@@ -31,7 +31,7 @@ function DataEntityUpdateImpl({ params }) {
const entityId = params.id as PrimaryFieldType; const entityId = params.id as PrimaryFieldType;
const [error, setError] = useState<string | null>(null); const [error, setError] = useState<string | null>(null);
const [navigate] = useNavigate(); const [navigate, _, _goBack] = useNavigate();
useBrowserTitle(["Data", entity.label, `#${entityId}`]); useBrowserTitle(["Data", entity.label, `#${entityId}`]);
const targetRelations = relations.listableRelationsOf(entity); const targetRelations = relations.listableRelationsOf(entity);
@@ -52,9 +52,8 @@ function DataEntityUpdateImpl({ params }) {
}, },
); );
function goBack() { const backHref = routes.data.entity.list(entity.name);
window.history.go(-1); const goBack = () => _goBack({ fallback: backHref });
}
async function onSubmitted(changeSet?: EntityData) { async function onSubmitted(changeSet?: EntityData) {
//return; //return;
@@ -162,10 +161,8 @@ function DataEntityUpdateImpl({ params }) {
className="pl-3" className="pl-3"
> >
<Breadcrumbs2 <Breadcrumbs2
path={[ backTo={backHref}
{ label: entity.label, href: routes.data.entity.list(entity.name) }, path={[{ label: entity.label, href: backHref }, { label: `Edit #${entityId}` }]}
{ label: `Edit #${entityId}` },
]}
/> />
</AppShell.SectionHeader> </AppShell.SectionHeader>
{$q.isLoading ? ( {$q.isLoading ? (

View File

@@ -8,13 +8,14 @@ import { useBrowserTitle } from "ui/hooks/use-browser-title";
import { useSearch } from "ui/hooks/use-search"; import { useSearch } from "ui/hooks/use-search";
import * as AppShell from "ui/layouts/AppShell/AppShell"; import * as AppShell from "ui/layouts/AppShell/AppShell";
import { Breadcrumbs2 } from "ui/layouts/AppShell/Breadcrumbs2"; import { Breadcrumbs2 } from "ui/layouts/AppShell/Breadcrumbs2";
import { routes } from "ui/lib/routes"; import { routes, useNavigate } from "ui/lib/routes";
import { EntityForm } from "ui/modules/data/components/EntityForm"; import { EntityForm } from "ui/modules/data/components/EntityForm";
import { useEntityForm } from "ui/modules/data/hooks/useEntityForm"; import { useEntityForm } from "ui/modules/data/hooks/useEntityForm";
import { s } from "core/object/schema"; import { s } from "core/object/schema";
export function DataEntityCreate({ params }) { export function DataEntityCreate({ params }) {
const { $data } = useBkndData(); const { $data } = useBkndData();
const [navigate, _, _goBack] = useNavigate();
const entity = $data.entity(params.entity as string); const entity = $data.entity(params.entity as string);
if (!entity) { if (!entity) {
return <Message.NotFound description={`Entity "${params.entity}" doesn't exist.`} />; return <Message.NotFound description={`Entity "${params.entity}" doesn't exist.`} />;
@@ -30,9 +31,8 @@ export function DataEntityCreate({ params }) {
// @todo: use entity schema for prefilling // @todo: use entity schema for prefilling
const search = useSearch(s.object({}), {}); const search = useSearch(s.object({}), {});
function goBack() { const backHref = routes.data.entity.list(entity.name);
window.history.go(-1); const goBack = () => _goBack({ fallback: backHref });
}
async function onSubmitted(changeSet?: EntityData) { async function onSubmitted(changeSet?: EntityData) {
console.log("create:changeSet", changeSet); console.log("create:changeSet", changeSet);
@@ -80,12 +80,7 @@ export function DataEntityCreate({ params }) {
</> </>
} }
> >
<Breadcrumbs2 <Breadcrumbs2 backTo={backHref} path={[{ label: entity.label }, { label: "Create" }]} />
path={[
{ label: entity.label, href: routes.data.entity.list(entity.name) },
{ label: "Create" },
]}
/>
</AppShell.SectionHeader> </AppShell.SectionHeader>
<AppShell.Scrollable key={entity.name}> <AppShell.Scrollable key={entity.name}>
{error && ( {error && (