mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-12 08:19:54 +02:00
fix(plugins): clear overlay account state on local board transitions
Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
1 parent
51eb1e1b4a
commit
3f1fbf39c8
3 files changed
+16
-3
No files matched your search
@@ -71,6 +71,8 @@ The `appShellOverlay` slot requires `ui.action.register`. It receives the usual
|
||||
`PluginWidgetProps` context. It mounts once in both application shells and
|
||||
survives route navigation. It is disposed when the account or selected company
|
||||
changes, during onboarding, and on sign-out. It is not mounted on login pages.
|
||||
Local-trusted mode has no login requirement: its sessionless board may mount
|
||||
overlays, but transitions to or from an account still dispose the prior state.
|
||||
|
||||
The host positions contributions above the mobile navigation and stacks them
|
||||
at the bottom right. Each plugin owns its launcher, panel, keyboard handling,
|
||||
|
||||
@@ -19,9 +19,9 @@ vi.mock("@/plugins/slots", () => ({
|
||||
}));
|
||||
let root: Root | undefined;
|
||||
let container: HTMLDivElement;
|
||||
function render() {
|
||||
function render(localTrusted = false) {
|
||||
if (!root) { container = document.createElement("div"); document.body.append(container); root = createRoot(container); }
|
||||
flushSync(() => root!.render(<PluginAppShellOverlays />));
|
||||
flushSync(() => root!.render(<PluginAppShellOverlays localTrusted={localTrusted} />));
|
||||
}
|
||||
afterEach(() => {
|
||||
if (root) flushSync(() => root!.unmount());
|
||||
@@ -45,4 +45,12 @@ describe("persistent app-shell plugin lifecycle", () => {
|
||||
state.onboarding = true; render(); expect(state.mounts).toBe(0);
|
||||
state.onboarding = false; state.failed = true; render(); expect(container.textContent).toBe("");
|
||||
});
|
||||
it("clears account state when returning to the sessionless local board", () => {
|
||||
render(true); flushSync(() => container.querySelector("button")!.click());
|
||||
state.settled = false; render(true); expect(container.textContent).toBe(""); expect(state.disposals).toBe(1);
|
||||
state.userId = null; state.settled = true; render(true);
|
||||
expect(container.textContent).toBe("empty"); expect(state.mounts).toBe(2);
|
||||
flushSync(() => container.querySelector("button")!.click());
|
||||
state.userId = "bob"; render(true); expect(container.textContent).toBe("empty"); expect(state.disposals).toBe(2);
|
||||
});
|
||||
});
|
||||
@@ -34,7 +34,10 @@ export function PluginAppShellOverlays({ localTrusted = false }: { localTrusted?
|
||||
const { userId, settled } = useAccountIdentity();
|
||||
const { selectedCompanyId, selectedCompany, loading } = useCompany();
|
||||
const { onboardingOpen } = useDialogState();
|
||||
const identity = localTrusted ? "local-board" : settled ? userId : null;
|
||||
// Local-trusted instances intentionally have no login requirement. Still
|
||||
// prefer any real account and wait for identity resolution so account changes
|
||||
// cannot reuse the prior account's in-memory plugin state.
|
||||
const identity = settled ? userId ?? (localTrusted ? "local-board" : null) : null;
|
||||
if (!identity || loading || onboardingOpen) return null;
|
||||
return (
|
||||
<AppShellEntries
|
||||
|
||||
Reference in new issue
Block a user