From 8a30141e622f009beccf4575a1a0507cf28619a9 Mon Sep 17 00:00:00 2001 From: AviPeltz Date: Mon, 17 Aug 2026 16:25:15 -0700 Subject: [PATCH 1/5] feat(desktop): show GitHub star pill on the new workspace screen Reuses the existing GitHubStarPill (already shown on the empty paneless views) under the heading of the new full-screen "new workspace" screen. It hides itself once the user has starred superset-sh/superset, so no additional not-starred check was needed. Adds a `surface` prop to GitHubStarPill so its analytics events can distinguish this placement ("new_workspace") from the original two. --- .../GitHubStarPill/GitHubStarPill.tsx | 31 +++++++++++-------- .../NewWorkspaceScreen/NewWorkspaceScreen.tsx | 2 ++ 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/apps/desktop/src/renderer/components/GitHubStarPill/GitHubStarPill.tsx b/apps/desktop/src/renderer/components/GitHubStarPill/GitHubStarPill.tsx index e334180d667..9957055164d 100644 --- a/apps/desktop/src/renderer/components/GitHubStarPill/GitHubStarPill.tsx +++ b/apps/desktop/src/renderer/components/GitHubStarPill/GitHubStarPill.tsx @@ -11,21 +11,26 @@ import { track } from "renderer/lib/analytics"; interface GitHubStarPillProps { className?: string; + /** Analytics surface tag; defaults to "empty_state" for the original callers. */ + surface?: "empty_state" | "new_workspace"; } /** * Small, always-optional "Star Superset on GitHub" pill for the empty - * "no pane open" screens (v1 EmptyTabView and v2 WorkspaceEmptyState). - * Renders straight from live `state`, with no nag-suppression layer — unlike - * the sidebar card/toast, this is a low-key status indicator, not an - * interruptive campaign, so it's allowed to be fully truthful: it hides the - * instant `state` is "starred" and reappears the instant a later unstar is - * confirmed, without waiting on any mute grace window. It briefly stays - * mounted past that point so the confetti/label animation on a fresh star - * has time to play, then dissolves out (fade + soft blur) instead of - * vanishing instantly. + * "no pane open" screens (v1 EmptyTabView and v2 WorkspaceEmptyState) and + * the new-workspace screen. Renders straight from live `state`, with no + * nag-suppression layer — unlike the sidebar card/toast, this is a low-key + * status indicator, not an interruptive campaign, so it's allowed to be + * fully truthful: it hides the instant `state` is "starred" and reappears + * the instant a later unstar is confirmed, without waiting on any mute + * grace window. It briefly stays mounted past that point so the + * confetti/label animation on a fresh star has time to play, then + * dissolves out (fade + soft blur) instead of vanishing instantly. */ -export function GitHubStarPill({ className }: GitHubStarPillProps) { +export function GitHubStarPill({ + className, + surface = "empty_state", +}: GitHubStarPillProps) { const { state, activate, isBusy } = useGithubStarAction(); const prevStateRef = useRef(null); @@ -81,8 +86,8 @@ export function GitHubStarPill({ className }: GitHubStarPillProps) { if (trackedShownRef.current) return; if (state !== "not_starred" && state !== "unknown") return; trackedShownRef.current = true; - track("star_nag_shown", { surface: "empty_state" }); - }, [state]); + track("star_nag_shown", { surface }); + }, [state, surface]); if (state === "loading") return null; @@ -94,7 +99,7 @@ export function GitHubStarPill({ className }: GitHubStarPillProps) { const handleClick = () => { track(state === "unknown" ? "star_nag_opened_web" : "star_nag_starred", { - surface: "empty_state", + surface, }); activate(); }; diff --git a/apps/desktop/src/renderer/routes/_authenticated/components/DashboardNewWorkspaceModal/components/NewWorkspaceScreen/NewWorkspaceScreen.tsx b/apps/desktop/src/renderer/routes/_authenticated/components/DashboardNewWorkspaceModal/components/NewWorkspaceScreen/NewWorkspaceScreen.tsx index 538fd454504..a0e8d448fb4 100644 --- a/apps/desktop/src/renderer/routes/_authenticated/components/DashboardNewWorkspaceModal/components/NewWorkspaceScreen/NewWorkspaceScreen.tsx +++ b/apps/desktop/src/renderer/routes/_authenticated/components/DashboardNewWorkspaceModal/components/NewWorkspaceScreen/NewWorkspaceScreen.tsx @@ -29,6 +29,7 @@ import { LuGitPullRequest } from "react-icons/lu"; import { SiLinear } from "react-icons/si"; import { AgentModelSelect } from "renderer/components/AgentModelSelect"; import { AgentSelect } from "renderer/components/AgentSelect"; +import { GitHubStarPill } from "renderer/components/GitHubStarPill"; import { IssueLinkCommand } from "renderer/components/IssueLinkCommand"; import { LinkedIssuePill } from "renderer/components/LinkedIssuePill"; import { MarkdownEditor } from "renderer/components/MarkdownEditor"; @@ -655,6 +656,7 @@ export function NewWorkspaceScreen({

What should we build next?

+
From 8ef7e96d3a5009c2a43cd595efe1c1b56b80bb67 Mon Sep 17 00:00:00 2001 From: AviPeltz Date: Mon, 17 Aug 2026 16:34:59 -0700 Subject: [PATCH 2/5] fix(desktop): reserve layout space for the new-workspace star pill MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GitHubStarPill previously unmounted on hide, collapsing its height. On the empty paneless views that's harmless, but the new-workspace screen centers its content with justify-center, so the collapse re-centered everything above it whenever the pill hid (e.g. once already starred). Adds an opt-in `reserveSpace` prop that keeps the pill's wrapper permanently mounted and only fades its opacity/pointer-events, so its box keeps occupying the same slot. Off by default — the two existing empty-state callers are unaffected. Verified live over CDP: wrapper stays at its full height (38px) with opacity 0 and pointer-events none once starred. --- .../GitHubStarPill/GitHubStarPill.tsx | 40 ++++++++++++++++--- .../NewWorkspaceScreen/NewWorkspaceScreen.tsx | 2 +- 2 files changed, 35 insertions(+), 7 deletions(-) diff --git a/apps/desktop/src/renderer/components/GitHubStarPill/GitHubStarPill.tsx b/apps/desktop/src/renderer/components/GitHubStarPill/GitHubStarPill.tsx index 9957055164d..b652eb71ee1 100644 --- a/apps/desktop/src/renderer/components/GitHubStarPill/GitHubStarPill.tsx +++ b/apps/desktop/src/renderer/components/GitHubStarPill/GitHubStarPill.tsx @@ -13,6 +13,15 @@ interface GitHubStarPillProps { className?: string; /** Analytics surface tag; defaults to "empty_state" for the original callers. */ surface?: "empty_state" | "new_workspace"; + /** + * Keep the pill's layout box mounted (just faded to invisible) instead of + * unmounting it once starred. The empty-state screens sit at the bottom of + * a plain block, so a height collapse there is harmless; the new-workspace + * screen centers its content with `justify-center`, where that same + * collapse re-centers everything above it. Off by default so the two + * existing callers keep their original unmount-on-hide behavior. + */ + reserveSpace?: boolean; } /** @@ -30,6 +39,7 @@ interface GitHubStarPillProps { export function GitHubStarPill({ className, surface = "empty_state", + reserveSpace = false, }: GitHubStarPillProps) { const { state, activate, isBusy } = useGithubStarAction(); const prevStateRef = useRef(null); @@ -89,13 +99,11 @@ export function GitHubStarPill({ track("star_nag_shown", { surface }); }, [state, surface]); - if (state === "loading") return null; + if (state === "loading" && !reserveSpace) return null; - const isVisible = !( - state === "starred" && - !justStarred && - !staysVisibleForAnimation - ); + const isVisible = + state !== "loading" && + !(state === "starred" && !justStarred && !staysVisibleForAnimation); const handleClick = () => { track(state === "unknown" ? "star_nag_opened_web" : "star_nag_starred", { @@ -104,6 +112,26 @@ export function GitHubStarPill({ activate(); }; + if (reserveSpace) { + // Always mounted so the button's box keeps occupying its slot — only + // opacity/interactivity change, never the layout. + return ( + + + + ); + } + return ( {isVisible && ( diff --git a/apps/desktop/src/renderer/routes/_authenticated/components/DashboardNewWorkspaceModal/components/NewWorkspaceScreen/NewWorkspaceScreen.tsx b/apps/desktop/src/renderer/routes/_authenticated/components/DashboardNewWorkspaceModal/components/NewWorkspaceScreen/NewWorkspaceScreen.tsx index a0e8d448fb4..68b2d9a0816 100644 --- a/apps/desktop/src/renderer/routes/_authenticated/components/DashboardNewWorkspaceModal/components/NewWorkspaceScreen/NewWorkspaceScreen.tsx +++ b/apps/desktop/src/renderer/routes/_authenticated/components/DashboardNewWorkspaceModal/components/NewWorkspaceScreen/NewWorkspaceScreen.tsx @@ -656,7 +656,7 @@ export function NewWorkspaceScreen({

What should we build next?

- +
From b7ded7a5e177ad918ef8ac33bca929480e04cc90 Mon Sep 17 00:00:00 2001 From: AviPeltz Date: Mon, 17 Aug 2026 16:37:00 -0700 Subject: [PATCH 3/5] fix(desktop): reset star-nag impression guard per surface Addresses CodeRabbit review on #6575: the shown-impression guard was a single boolean, so a mounted pill whose `surface` prop changed would inherit the prior surface's "already shown" state and silently skip the star_nag_shown event for the new surface. Track the last surface instead. --- .../GitHubStarPill/GitHubStarPill.tsx | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/apps/desktop/src/renderer/components/GitHubStarPill/GitHubStarPill.tsx b/apps/desktop/src/renderer/components/GitHubStarPill/GitHubStarPill.tsx index b652eb71ee1..416d3b330a0 100644 --- a/apps/desktop/src/renderer/components/GitHubStarPill/GitHubStarPill.tsx +++ b/apps/desktop/src/renderer/components/GitHubStarPill/GitHubStarPill.tsx @@ -84,18 +84,22 @@ export function GitHubStarPill({ } }, [state]); - // Fire at most once per showing — reset once starred so a later unstar - // that re-shows the pill tracks a fresh "shown" impression instead of - // staying silent forever after the first one. - const trackedShownRef = useRef(false); + // Fire at most once per showing per surface — reset once starred so a + // later unstar re-shows the pill and tracks a fresh "shown" impression, + // and reset again if `surface` itself changes so a re-purposed mounted + // instance still gets its own impression instead of inheriting the prior + // surface's guard. + const trackedShownSurfaceRef = useRef< + NonNullable | null + >(null); useEffect(() => { if (state === "starred") { - trackedShownRef.current = false; + trackedShownSurfaceRef.current = null; return; } - if (trackedShownRef.current) return; + if (trackedShownSurfaceRef.current === surface) return; if (state !== "not_starred" && state !== "unknown") return; - trackedShownRef.current = true; + trackedShownSurfaceRef.current = surface; track("star_nag_shown", { surface }); }, [state, surface]); From 42e1433613646e5d5a4f01df8c848f82884712ba Mon Sep 17 00:00:00 2001 From: AviPeltz Date: Mon, 17 Aug 2026 16:39:12 -0700 Subject: [PATCH 4/5] style(desktop): fix biome formatting in GitHubStarPill CI lint caught a formatting mismatch on the type annotation from the previous commit. --- .../renderer/components/GitHubStarPill/GitHubStarPill.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/desktop/src/renderer/components/GitHubStarPill/GitHubStarPill.tsx b/apps/desktop/src/renderer/components/GitHubStarPill/GitHubStarPill.tsx index 416d3b330a0..11a24f4b15c 100644 --- a/apps/desktop/src/renderer/components/GitHubStarPill/GitHubStarPill.tsx +++ b/apps/desktop/src/renderer/components/GitHubStarPill/GitHubStarPill.tsx @@ -89,9 +89,9 @@ export function GitHubStarPill({ // and reset again if `surface` itself changes so a re-purposed mounted // instance still gets its own impression instead of inheriting the prior // surface's guard. - const trackedShownSurfaceRef = useRef< - NonNullable | null - >(null); + const trackedShownSurfaceRef = useRef | null>(null); useEffect(() => { if (state === "starred") { trackedShownSurfaceRef.current = null; From 0fbc0e5ec617614e4d1d3ce5a17ad3a5d72b846c Mon Sep 17 00:00:00 2001 From: AviPeltz Date: Mon, 17 Aug 2026 16:40:51 -0700 Subject: [PATCH 5/5] fix(desktop): make the hidden reserved star pill non-focusable Addresses CodeRabbit review on #6575: pointerEvents:"none" and aria-hidden don't remove a hidden descendant button from the tab order, so a keyboard user could still Tab to and activate the invisible, already-starred pill. inert removes it from focus, hit testing, and the accessibility tree together. --- .../src/renderer/components/GitHubStarPill/GitHubStarPill.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/desktop/src/renderer/components/GitHubStarPill/GitHubStarPill.tsx b/apps/desktop/src/renderer/components/GitHubStarPill/GitHubStarPill.tsx index 11a24f4b15c..7ad1e08199f 100644 --- a/apps/desktop/src/renderer/components/GitHubStarPill/GitHubStarPill.tsx +++ b/apps/desktop/src/renderer/components/GitHubStarPill/GitHubStarPill.tsx @@ -125,6 +125,7 @@ export function GitHubStarPill({ transition={{ duration: 0.32, ease: "easeOut" }} style={{ pointerEvents: isVisible ? "auto" : "none" }} aria-hidden={!isVisible} + inert={!isVisible} className={cn("flex items-center justify-center", className)} >