mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-21 15:26:43 +02:00
fix(settings): react to anchor deep-links when already mounted
When clicking "KI-Einstellungen öffnen" from the companion chat while settings is already open on a different tab, the settings panel now correctly switches to the right tab and scrolls to the anchor. The workbench deep-link $effect dispatches a custom workbench:navigate-anchor event after opening/focusing the target panel. The settings ListView listens for both this event and native hashchange, then calls navigateToHash() to switch activeCategory and scroll. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
1cfd05939e
commit
4aafbf6f6d
2 changed files with 39 additions and 2 deletions
|
|
@ -20,8 +20,7 @@
|
||||||
|
|
||||||
let activeCategory = $state<CategoryId>('general');
|
let activeCategory = $state<CategoryId>('general');
|
||||||
|
|
||||||
onMount(() => {
|
function navigateToHash(hash: string) {
|
||||||
const hash = window.location.hash?.slice(1);
|
|
||||||
if (!hash) return;
|
if (!hash) return;
|
||||||
const cat = categories.find((c) => c.anchors.includes(hash));
|
const cat = categories.find((c) => c.anchors.includes(hash));
|
||||||
if (cat) activeCategory = cat.id;
|
if (cat) activeCategory = cat.id;
|
||||||
|
|
@ -29,6 +28,33 @@
|
||||||
const el = document.getElementById(hash);
|
const el = document.getElementById(hash);
|
||||||
if (el) el.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
if (el) el.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
const hash = window.location.hash?.slice(1);
|
||||||
|
if (hash) navigateToHash(hash);
|
||||||
|
});
|
||||||
|
|
||||||
|
// React to anchor navigations while already mounted (e.g. deep-link
|
||||||
|
// from companion chat "KI-Einstellungen öffnen" when settings is
|
||||||
|
// already open on a different tab). Listens for both native hashchange
|
||||||
|
// and the custom workbench:navigate-anchor event dispatched by the
|
||||||
|
// workbench deep-link handler.
|
||||||
|
$effect(() => {
|
||||||
|
const onHashChange = () => {
|
||||||
|
const hash = window.location.hash?.slice(1);
|
||||||
|
if (hash) navigateToHash(hash);
|
||||||
|
};
|
||||||
|
const onAnchor = (e: Event) => {
|
||||||
|
const anchor = (e as CustomEvent<{ anchor: string }>).detail?.anchor;
|
||||||
|
if (anchor) navigateToHash(anchor);
|
||||||
|
};
|
||||||
|
window.addEventListener('hashchange', onHashChange);
|
||||||
|
window.addEventListener('workbench:navigate-anchor', onAnchor);
|
||||||
|
return () => {
|
||||||
|
window.removeEventListener('hashchange', onHashChange);
|
||||||
|
window.removeEventListener('workbench:navigate-anchor', onAnchor);
|
||||||
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
function jumpTo(entry: SearchEntry) {
|
function jumpTo(entry: SearchEntry) {
|
||||||
|
|
@ -68,6 +94,7 @@
|
||||||
gap: 1rem;
|
gap: 1rem;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
|
overflow-x: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.settings-content {
|
.settings-content {
|
||||||
|
|
|
||||||
|
|
@ -89,15 +89,25 @@
|
||||||
$effect(() => {
|
$effect(() => {
|
||||||
const target = $page.url.searchParams.get('app');
|
const target = $page.url.searchParams.get('app');
|
||||||
if (!target || !getApp(target)) return;
|
if (!target || !getApp(target)) return;
|
||||||
|
const hash = $page.url.hash?.slice(1) || '';
|
||||||
// Use queueMicrotask so we don't mutate state during the effect's first run
|
// Use queueMicrotask so we don't mutate state during the effect's first run
|
||||||
queueMicrotask(async () => {
|
queueMicrotask(async () => {
|
||||||
const already = workbenchScenesStore.openApps.find((a) => a.appId === target);
|
const already = workbenchScenesStore.openApps.find((a) => a.appId === target);
|
||||||
if (!already) await workbenchScenesStore.addApp(target);
|
if (!already) await workbenchScenesStore.addApp(target);
|
||||||
await tick();
|
await tick();
|
||||||
scrollToPage(target);
|
scrollToPage(target);
|
||||||
|
// Clean the ?app= param but preserve the hash for the target panel
|
||||||
const clean = new URL($page.url);
|
const clean = new URL($page.url);
|
||||||
clean.searchParams.delete('app');
|
clean.searchParams.delete('app');
|
||||||
history.replaceState({}, '', clean);
|
history.replaceState({}, '', clean);
|
||||||
|
// Notify the target panel about the hash anchor (e.g. settings
|
||||||
|
// needs to switch to the right tab and scroll to the section)
|
||||||
|
if (hash) {
|
||||||
|
await tick();
|
||||||
|
window.dispatchEvent(
|
||||||
|
new CustomEvent('workbench:navigate-anchor', { detail: { anchor: hash } })
|
||||||
|
);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue