mirror of
https://github.com/okieselbach/AutopilotMonitor.git
synced 2026-10-24 12:42:38 +00:00
fix(web): a What's new link opens the panel after the sign-in round trip too
A portal link with ?whats-new= opened without a session flashed the panel, went through the sign-in, and came back without it: MSAL lands on the origin root and AuthGate reaches the saved link by a client-side navigation, while WhatsNewPanelHost (root layout, stays mounted) read the parameter only once on mount. It now follows the search parameter and opens once per arrival; a protected page waits for the session, so the panel no longer flashes before the redirect or counts the open twice. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,12 +1,13 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect } from "react";
|
||||
import { usePathname } from "next/navigation";
|
||||
import { Suspense, useEffect, useRef } from "react";
|
||||
import { usePathname, useSearchParams } from "next/navigation";
|
||||
import { WhatsNewPanel } from "./WhatsNewPanel";
|
||||
import { useWhatsNewState, openWhatsNew } from "@/lib/whatsNewStore";
|
||||
import { trackEvent } from "@/lib/appInsights";
|
||||
import { isPublicPath } from "@/lib/hostRouting";
|
||||
import { WHATS_NEW_CHANNELS, type WhatsNewChannel } from "@/lib/whatsNew";
|
||||
import { useAuth } from "@/contexts/AuthContext";
|
||||
|
||||
/**
|
||||
* Mounts the What's new panel once, in the root layout, so the portal navbar, the landing
|
||||
@@ -24,16 +25,43 @@ export function WhatsNewPanelHost() {
|
||||
const pathname = usePathname();
|
||||
const onPublicPage = isPublicPath(pathname);
|
||||
|
||||
return (
|
||||
<>
|
||||
{/* useSearchParams() needs a Suspense boundary for the static prerender. */}
|
||||
<Suspense fallback={null}>
|
||||
<WhatsNewDeepLink onPublicPage={onPublicPage} />
|
||||
</Suspense>
|
||||
{panelOpen && <WhatsNewPanel rootClassName={onPublicPage ? "landing-v2" : undefined} />}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens the panel once each time `?whats-new=` arrives, not only on the first mount: a portal
|
||||
* link opened without a session goes through the sign-in, which lands on the origin root and
|
||||
* reaches the link again by a client-side navigation (AuthGate), where this layout stays
|
||||
* mounted. A protected page waits for the session, so the panel neither flashes before the
|
||||
* sign-in redirect nor counts the open twice.
|
||||
*/
|
||||
function WhatsNewDeepLink({ onPublicPage }: { onPublicPage: boolean }) {
|
||||
const requested = useSearchParams()?.get("whats-new") ?? null;
|
||||
const { isAuthenticated, isLoading } = useAuth();
|
||||
const ready = onPublicPage || (isAuthenticated && !isLoading);
|
||||
const handled = useRef(false);
|
||||
|
||||
useEffect(() => {
|
||||
const requested = new URLSearchParams(window.location.search).get("whats-new");
|
||||
if (requested === null) return;
|
||||
if (requested === null) {
|
||||
handled.current = false;
|
||||
return;
|
||||
}
|
||||
if (handled.current || !ready) return;
|
||||
handled.current = true;
|
||||
const channel = (WHATS_NEW_CHANNELS as readonly string[]).includes(requested)
|
||||
? (requested as WhatsNewChannel)
|
||||
: undefined;
|
||||
trackEvent("whats_new_opened", { source: "deeplink", channel: channel ?? "default" });
|
||||
openWhatsNew("deeplink", channel);
|
||||
}, []);
|
||||
}, [requested, ready]);
|
||||
|
||||
if (!panelOpen) return null;
|
||||
return <WhatsNewPanel rootClassName={onPublicPage ? "landing-v2" : undefined} />;
|
||||
return null;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user