Merge branch 'dev' into claude/dedupe-discord-notifications-exSqa

This commit is contained in:
Nicholas Tindle
2025-12-30 10:06:52 -06:00
committed by GitHub
11 changed files with 369 additions and 385 deletions

View File

@@ -13011,7 +13011,7 @@ snapshots:
minimatch: 3.1.2
node-abort-controller: 3.1.1
schema-utils: 3.3.0
semver: 7.7.2
semver: 7.7.3
tapable: 2.2.3
typescript: 5.9.3
webpack: 5.101.3(esbuild@0.25.9)

View File

@@ -4,19 +4,12 @@ import {
OutputActions,
OutputItem,
} from "@/app/(platform)/library/agents/[id]/components/NewAgentLibraryView/components/selected-views/OutputRenderers";
import { Dialog } from "@/components/molecules/Dialog/Dialog";
import { beautifyString } from "@/lib/utils";
import { Flag, useGetFlag } from "@/services/feature-flags/use-get-flag";
import { Clipboard, Maximize2 } from "lucide-react";
import React, { FC, useMemo, useState } from "react";
import { Button } from "../../../../../components/__legacy__/ui/button";
import {
Dialog,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
} from "../../../../../components/__legacy__/ui/dialog";
import { ContentRenderer } from "../../../../../components/__legacy__/ui/render";
import { ScrollArea } from "../../../../../components/__legacy__/ui/scroll-area";
import { Separator } from "../../../../../components/__legacy__/ui/separator";
@@ -120,138 +113,155 @@ const ExpandableOutputDialog: FC<ExpandableOutputDialogProps> = ({
};
return (
<Dialog open={isOpen} onOpenChange={onClose}>
<DialogContent className="flex h-[90vh] w-[90vw] max-w-4xl flex-col">
<DialogHeader>
<DialogTitle className="flex items-center justify-between pr-8">
<div className="flex items-center gap-2">
<Maximize2 size={20} />
Full Output Preview
</div>
{enableEnhancedOutputHandling && (
<div className="flex items-center gap-3">
<label
htmlFor="enhanced-rendering-toggle"
className="cursor-pointer select-none text-sm font-normal text-gray-600"
>
Enhanced Rendering
</label>
<Switch
id="enhanced-rendering-toggle"
checked={useEnhancedRenderer}
onCheckedChange={setUseEnhancedRenderer}
/>
</div>
)}
</DialogTitle>
<DialogDescription>
Execution ID: <span className="font-mono text-xs">{execId}</span>
<br />
Pin:{" "}
<span className="font-semibold">{beautifyString(pinName)}</span>
</DialogDescription>
</DialogHeader>
<div className="flex-1 overflow-hidden">
{useEnhancedRenderer && outputItems.length > 0 && (
<div className="border-b px-4 py-2">
<OutputActions
items={outputItems.map((item) => ({
value: item.value,
metadata: item.metadata,
renderer: item.renderer,
}))}
<Dialog
title={
<div className="flex items-center justify-between pr-8">
<div className="flex items-center gap-2">
<Maximize2 size={20} />
Full Output Preview
</div>
{enableEnhancedOutputHandling && (
<div className="flex items-center gap-3">
<label
htmlFor="enhanced-rendering-toggle"
className="cursor-pointer select-none text-sm font-normal text-gray-600"
>
Enhanced Rendering
</label>
<Switch
id="enhanced-rendering-toggle"
checked={useEnhancedRenderer}
onCheckedChange={setUseEnhancedRenderer}
/>
</div>
)}
<ScrollArea className="h-full">
<div className="p-4">
{data.length > 0 ? (
useEnhancedRenderer ? (
<div className="space-y-4">
{outputItems.map((item) => (
<OutputItem
key={item.key}
value={item.value}
metadata={item.metadata}
renderer={item.renderer}
label={item.label}
/>
))}
</div>
) : (
<div className="space-y-4">
{data.map((item, index) => (
<div
key={index}
className="rounded-lg border bg-gray-50 p-4"
>
<div className="mb-2 flex items-center justify-between">
<span className="text-sm font-medium text-gray-600">
Item {index + 1} of {data.length}
</span>
<Button
variant="outline"
size="sm"
onClick={() => {
const itemData =
typeof item === "object"
? JSON.stringify(item, null, 2)
: String(item);
navigator.clipboard
.writeText(itemData)
.then(() => {
toast({
title: `Item ${index + 1} copied to clipboard!`,
duration: 2000,
});
});
}}
className="flex items-center gap-1"
>
<Clipboard size={14} />
Copy Item
</Button>
</div>
<Separator className="mb-3" />
<div className="whitespace-pre-wrap break-words font-mono text-sm">
<ContentRenderer
value={item}
truncateLongData={false}
/>
</div>
</div>
))}
</div>
)
) : (
<div className="py-8 text-center text-gray-500">
No data available
</div>
)}
</div>
</ScrollArea>
</div>
}
controlled={{
isOpen,
set: (open) => {
if (!open) onClose();
},
}}
onClose={onClose}
styling={{
maxWidth: "56rem",
width: "90vw",
height: "90vh",
}}
>
<Dialog.Content>
<div className="flex h-full flex-col">
<div className="pb-4">
<p className="text-sm text-zinc-600">
Execution ID: <span className="font-mono text-xs">{execId}</span>
<br />
Pin:{" "}
<span className="font-semibold">{beautifyString(pinName)}</span>
</p>
</div>
<DialogFooter className="flex justify-between">
<div className="text-sm text-gray-600">
{data.length} item{data.length !== 1 ? "s" : ""} total
</div>
<div className="flex gap-2">
{!useEnhancedRenderer && (
<Button
variant="outline"
onClick={copyData}
className="flex items-center gap-1"
>
<Clipboard size={16} />
Copy All
</Button>
<div className="flex flex-1 flex-col overflow-hidden">
{useEnhancedRenderer && outputItems.length > 0 && (
<div className="border-b px-4 py-2">
<OutputActions
items={outputItems.map((item) => ({
value: item.value,
metadata: item.metadata,
renderer: item.renderer,
}))}
/>
</div>
)}
<Button onClick={onClose}>Close</Button>
<ScrollArea className="h-full">
<div className="p-4">
{data.length > 0 ? (
useEnhancedRenderer ? (
<div className="space-y-4">
{outputItems.map((item) => (
<OutputItem
key={item.key}
value={item.value}
metadata={item.metadata}
renderer={item.renderer}
label={item.label}
/>
))}
</div>
) : (
<div className="space-y-4">
{data.map((item, index) => (
<div
key={index}
className="rounded-lg border bg-gray-50 p-4"
>
<div className="mb-2 flex items-center justify-between">
<span className="text-sm font-medium text-gray-600">
Item {index + 1} of {data.length}
</span>
<Button
variant="outline"
size="sm"
onClick={() => {
const itemData =
typeof item === "object"
? JSON.stringify(item, null, 2)
: String(item);
navigator.clipboard
.writeText(itemData)
.then(() => {
toast({
title: `Item ${index + 1} copied to clipboard!`,
duration: 2000,
});
});
}}
className="flex items-center gap-1"
>
<Clipboard size={14} />
Copy Item
</Button>
</div>
<Separator className="mb-3" />
<div className="whitespace-pre-wrap break-words font-mono text-sm">
<ContentRenderer
value={item}
truncateLongData={false}
/>
</div>
</div>
))}
</div>
)
) : (
<div className="py-8 text-center text-gray-500">
No data available
</div>
)}
</div>
</ScrollArea>
</div>
</DialogFooter>
</DialogContent>
<Dialog.Footer className="flex justify-between">
<div className="text-sm text-gray-600">
{data.length} item{data.length !== 1 ? "s" : ""} total
</div>
<div className="flex gap-2">
{!useEnhancedRenderer && (
<Button
variant="outline"
onClick={copyData}
className="flex items-center gap-1"
>
<Clipboard size={16} />
Copy All
</Button>
)}
<Button onClick={onClose}>Close</Button>
</div>
</Dialog.Footer>
</div>
</Dialog.Content>
</Dialog>
);
};

View File

@@ -1,17 +1,11 @@
import React, { useCallback } from "react";
import { useCallback } from "react";
import { AgentRunDraftView } from "@/app/(platform)/library/agents/[id]/components/OldAgentLibraryView/components/agent-run-draft-view";
import { Dialog } from "@/components/molecules/Dialog/Dialog";
import type {
CredentialsMetaInput,
GraphMeta,
} from "@/lib/autogpt-server-api/types";
import {
Dialog,
DialogContent,
DialogHeader,
DialogTitle,
DialogDescription,
} from "@/components/__legacy__/ui/dialog";
import { AgentRunDraftView } from "@/app/(platform)/library/agents/[id]/components/OldAgentLibraryView/components/agent-run-draft-view";
interface RunInputDialogProps {
isOpen: boolean;
@@ -70,21 +64,33 @@ export function RunnerInputDialog({
);
return (
<Dialog open={isOpen} onOpenChange={doClose}>
<DialogContent className="flex w-[90vw] max-w-4xl flex-col p-10">
<DialogHeader>
<DialogTitle className="text-2xl">Run your agent</DialogTitle>
<DialogDescription className="mt-2">{graph.name}</DialogDescription>
</DialogHeader>
<AgentRunDraftView
className="p-0"
graph={graph}
doRun={doRun ? handleRun : undefined}
onRun={doRun ? undefined : doClose}
doCreateSchedule={doCreateSchedule ? handleSchedule : undefined}
onCreateSchedule={doCreateSchedule ? undefined : doClose}
/>
</DialogContent>
<Dialog
title="Run your agent"
controlled={{
isOpen,
set: (open) => {
if (!open) doClose();
},
}}
onClose={doClose}
styling={{
maxWidth: "56rem",
width: "90vw",
}}
>
<Dialog.Content>
<div className="flex flex-col p-10">
<p className="mt-2 text-sm text-zinc-600">{graph.name}</p>
<AgentRunDraftView
className="p-0"
graph={graph}
doRun={doRun ? handleRun : undefined}
onRun={doRun ? undefined : doClose}
doCreateSchedule={doCreateSchedule ? handleSchedule : undefined}
onCreateSchedule={doCreateSchedule ? undefined : doClose}
/>
</div>
</Dialog.Content>
</Dialog>
);
}

View File

@@ -1,11 +1,11 @@
import { Metadata } from "next";
import { Suspense } from "react";
import {
prefetchGetV2ListStoreAgentsQuery,
prefetchGetV2ListStoreCreatorsQuery,
} from "@/app/api/__generated__/endpoints/store/store";
import { getQueryClient } from "@/lib/react-query/queryClient";
import { dehydrate, HydrationBoundary } from "@tanstack/react-query";
import { Metadata } from "next";
import { Suspense } from "react";
import { MainMarkeplacePage } from "./components/MainMarketplacePage/MainMarketplacePage";
import { MainMarketplacePageLoading } from "./components/MainMarketplacePageLoading";
@@ -48,11 +48,6 @@ export const metadata: Metadata = {
description: "Find and use AI Agents created by our community",
images: ["/images/store-twitter.png"],
},
icons: {
icon: "/favicon.ico",
shortcut: "/favicon-16x16.png",
apple: "/apple-touch-icon.png",
},
};
export default async function MarketplacePage(): Promise<React.ReactElement> {

View File

@@ -15,9 +15,21 @@ import { environment } from "@/services/environment";
import { ReactQueryDevtools } from "@tanstack/react-query-devtools";
import { headers } from "next/headers";
const isDev = environment.isDev();
const isLocal = environment.isLocal();
const faviconPath = isDev
? "/favicon-dev.ico"
: isLocal
? "/favicon-local.ico"
: "/favicon.ico";
export const metadata: Metadata = {
title: "AutoGPT Platform",
description: "Your one stop shop to creating AI Agents",
icons: {
icon: faviconPath,
},
};
export default async function RootLayout({
@@ -27,8 +39,6 @@ export default async function RootLayout({
}>) {
const headersList = await headers();
const host = headersList.get("host") || "";
const isDev = environment.isDev();
const isLocal = environment.isLocal();
return (
<html
@@ -37,16 +47,6 @@ export default async function RootLayout({
suppressHydrationWarning
>
<head>
<link
rel="icon"
href={
isLocal
? "/favicon-local.ico"
: isDev
? "/favicon-dev.ico"
: "/favicon.ico"
}
/>
<SetupAnalytics
host={host}
ga={{

View File

@@ -1,13 +1,157 @@
"use client";
import { useGetV2GetUserProfile } from "@/app/api/__generated__/endpoints/store/store";
import { okData } from "@/app/api/helpers";
import { IconAutoGPTLogo, IconType } from "@/components/__legacy__/ui/icons";
import { PreviewBanner } from "@/components/layout/Navbar/components/PreviewBanner/PreviewBanner";
import { useBreakpoint } from "@/lib/hooks/useBreakpoint";
import { useSupabase } from "@/lib/supabase/hooks/useSupabase";
import { environment } from "@/services/environment";
import { Flag, useGetFlag } from "@/services/feature-flags/use-get-flag";
import { AccountMenu } from "./components/AccountMenu/AccountMenu";
import { AgentActivityDropdown } from "./components/AgentActivityDropdown/AgentActivityDropdown";
import { LoginButton } from "./components/LoginButton";
import { MobileNavBar } from "./components/MobileNavbar/MobileNavBar";
import { NavbarLink } from "./components/NavbarLink";
import { NavbarLoading } from "./components/NavbarLoading";
import { Wallet } from "./components/Wallet/Wallet";
import { getAccountMenuItems, loggedInLinks, loggedOutLinks } from "./helpers";
import { NavbarView } from "./components/NavbarView";
import { getNavbarAccountData } from "./data";
export async function Navbar() {
const { isLoggedIn } = await getNavbarAccountData();
export function Navbar() {
const { user, isLoggedIn, isUserLoading } = useSupabase();
const breakpoint = useBreakpoint();
const isSmallScreen = breakpoint === "sm" || breakpoint === "base";
const dynamicMenuItems = getAccountMenuItems(user?.role);
const isChatEnabled = useGetFlag(Flag.CHAT);
const previewBranchName = environment.getPreviewStealingDev();
const { data: profile, isLoading: isProfileLoading } = useGetV2GetUserProfile(
{
query: {
select: okData,
enabled: isLoggedIn && !!user,
// Include user ID in query key to ensure cache invalidation when user changes
queryKey: ["/api/store/profile", user?.id],
},
},
);
const isLoadingProfile = isProfileLoading || isUserLoading;
const shouldShowPreviewBanner = Boolean(isLoggedIn && previewBranchName);
const actualLoggedInLinks =
isChatEnabled === true
? loggedInLinks.concat([{ name: "Chat", href: "/chat" }])
: loggedInLinks;
if (isUserLoading) {
return <NavbarLoading />;
}
return (
<NavbarView isLoggedIn={isLoggedIn} previewBranchName={previewBranchName} />
<>
<div className="sticky top-0 z-40 w-full">
{shouldShowPreviewBanner && previewBranchName ? (
<PreviewBanner branchName={previewBranchName} />
) : null}
<nav className="border-zinc-[#EFEFF0] inline-flex h-[60px] w-full items-center border border-[#EFEFF0] bg-[#F3F4F6]/20 p-3 backdrop-blur-[26px]">
{/* Left section */}
{!isSmallScreen ? (
<div className="flex flex-1 items-center gap-5">
{isLoggedIn
? actualLoggedInLinks.map((link) => (
<NavbarLink
key={link.name}
name={link.name}
href={link.href}
/>
))
: loggedOutLinks.map((link) => (
<NavbarLink
key={link.name}
name={link.name}
href={link.href}
/>
))}
</div>
) : null}
{/* Centered logo */}
<div className="static h-auto w-[4.5rem] md:absolute md:left-1/2 md:top-1/2 md:w-[5.5rem] md:-translate-x-1/2 md:-translate-y-1/2">
<IconAutoGPTLogo className="h-full w-full" />
</div>
{/* Right section */}
{isLoggedIn && !isSmallScreen ? (
<div className="flex flex-1 items-center justify-end gap-4">
<div className="flex items-center gap-4">
<AgentActivityDropdown />
{profile && <Wallet key={profile.username} />}
<AccountMenu
userName={profile?.username}
userEmail={profile?.name}
avatarSrc={profile?.avatar_url ?? ""}
menuItemGroups={dynamicMenuItems}
isLoading={isLoadingProfile}
/>
</div>
</div>
) : !isLoggedIn ? (
<div className="flex w-full items-center justify-end">
<LoginButton />
</div>
) : null}
{/* <ThemeToggle /> */}
</nav>
</div>
{/* Mobile Navbar - Adjust positioning */}
<>
{isLoggedIn && isSmallScreen ? (
<div className="fixed right-0 top-2 z-50 flex items-center gap-0">
<Wallet />
<MobileNavBar
userName={profile?.username}
menuItemGroups={[
{
groupName: "Navigation",
items: actualLoggedInLinks
.map((link) => {
if (link.name === "Chat" && !isChatEnabled) {
return null;
}
return {
icon:
link.name === "Marketplace"
? IconType.Marketplace
: link.name === "Library"
? IconType.Library
: link.name === "Build"
? IconType.Builder
: link.name === "Chat"
? IconType.Chat
: link.name === "Monitor"
? IconType.Library
: IconType.LayoutDashboard,
text: link.name,
href: link.href,
};
})
.filter((item) => item !== null) as Array<{
icon: IconType;
text: string;
href: string;
}>,
},
...dynamicMenuItems,
]}
userEmail={profile?.name}
avatarSrc={profile?.avatar_url ?? ""}
/>
</div>
) : null}
</>
</>
);
}

View File

@@ -6,45 +6,42 @@ import { useSupabase } from "@/lib/supabase/hooks/useSupabase";
import { cn } from "@/lib/utils";
import * as Sentry from "@sentry/nextjs";
import { useRouter } from "next/navigation";
import { useState } from "react";
import { useTransition } from "react";
export function AccountLogoutOption() {
const [isLoggingOut, setIsLoggingOut] = useState(false);
const [isPending, startTransition] = useTransition();
const supabase = useSupabase();
const router = useRouter();
const { toast } = useToast();
async function handleLogout() {
setIsLoggingOut(true);
try {
await supabase.logOut();
router.push("/login");
} catch (e) {
Sentry.captureException(e);
toast({
title: "Error logging out",
description:
"Something went wrong when logging out. Please try again. If the problem persists, please contact support.",
variant: "destructive",
});
} finally {
setTimeout(() => {
setIsLoggingOut(false);
}, 3000);
}
function handleLogout() {
startTransition(async () => {
try {
await supabase.logOut();
router.replace("/login");
} catch (e) {
Sentry.captureException(e);
toast({
title: "Error logging out",
description:
"Something went wrong when logging out. Please try again. If the problem persists, please contact support.",
variant: "destructive",
});
}
});
}
return (
<div
className={cn(
"inline-flex w-full items-center justify-start gap-2.5",
isLoggingOut && "justify-center opacity-50",
isPending && "justify-center opacity-50",
)}
onClick={handleLogout}
role="button"
tabIndex={0}
>
{isLoggingOut ? (
{isPending ? (
<LoadingSpinner className="size-5" />
) : (
<>

View File

@@ -5,16 +5,15 @@ export function NavbarLoading() {
return (
<nav className="sticky top-0 z-40 hidden h-16 items-center rounded-bl-2xl rounded-br-2xl border border-white/50 bg-white/5 p-3 backdrop-blur-[26px] md:inline-flex">
<div className="flex flex-1 items-center gap-6">
<Skeleton className="h-4 w-20 bg-white/20" />
<Skeleton className="h-4 w-16 bg-white/20" />
<Skeleton className="h-4 w-12 bg-white/20" />
<Skeleton className="h-6 w-24 bg-zinc-200/60" />
<Skeleton className="h-6 w-24 bg-zinc-200/60" />
<Skeleton className="h-6 w-16 bg-zinc-200/60" />
</div>
<div className="absolute left-1/2 top-1/2 h-10 w-[88.87px] -translate-x-1/2 -translate-y-1/2">
<IconAutoGPTLogo className="h-full w-full" />
</div>
<div className="flex flex-1 items-center justify-end gap-4">
<Skeleton className="h-8 w-8 rounded-full bg-white/20" />
<Skeleton className="h-8 w-8 rounded-full bg-white/20" />
<Skeleton className="h-8 w-8 rounded-full bg-zinc-200/60" />
</div>
</nav>
);

View File

@@ -1,144 +0,0 @@
"use client";
import { useGetV2GetUserProfile } from "@/app/api/__generated__/endpoints/store/store";
import { IconAutoGPTLogo, IconType } from "@/components/__legacy__/ui/icons";
import { PreviewBanner } from "@/components/layout/Navbar/components/PreviewBanner/PreviewBanner";
import { useBreakpoint } from "@/lib/hooks/useBreakpoint";
import { useSupabase } from "@/lib/supabase/hooks/useSupabase";
import { Flag, useGetFlag } from "@/services/feature-flags/use-get-flag";
import { useMemo } from "react";
import { okData } from "@/app/api/helpers";
import { getAccountMenuItems, loggedInLinks, loggedOutLinks } from "../helpers";
import { AccountMenu } from "./AccountMenu/AccountMenu";
import { AgentActivityDropdown } from "./AgentActivityDropdown/AgentActivityDropdown";
import { LoginButton } from "./LoginButton";
import { MobileNavBar } from "./MobileNavbar/MobileNavBar";
import { NavbarLink } from "./NavbarLink";
import { Wallet } from "./Wallet/Wallet";
interface NavbarViewProps {
isLoggedIn: boolean;
previewBranchName?: string | null;
}
export function NavbarView({ isLoggedIn, previewBranchName }: NavbarViewProps) {
const { user } = useSupabase();
const breakpoint = useBreakpoint();
const isSmallScreen = breakpoint === "sm" || breakpoint === "base";
const dynamicMenuItems = getAccountMenuItems(user?.role);
const isChatEnabled = useGetFlag(Flag.CHAT);
const { data: profile, isLoading: isProfileLoading } = useGetV2GetUserProfile(
{
query: {
select: okData,
enabled: isLoggedIn && !!user,
// Include user ID in query key to ensure cache invalidation when user changes
queryKey: ["/api/store/profile", user?.id],
},
},
);
const { isUserLoading } = useSupabase();
const isLoadingProfile = isProfileLoading || isUserLoading;
const linksWithChat = useMemo(() => {
const chatLink = { name: "Chat", href: "/chat" };
return isChatEnabled ? [...loggedInLinks, chatLink] : loggedInLinks;
}, [isChatEnabled]);
const shouldShowPreviewBanner = Boolean(isLoggedIn && previewBranchName);
return (
<>
<div className="sticky top-0 z-40 w-full">
{shouldShowPreviewBanner && previewBranchName ? (
<PreviewBanner branchName={previewBranchName} />
) : null}
<nav className="border-zinc-[#EFEFF0] inline-flex h-[60px] w-full items-center border border-[#EFEFF0] bg-[#F3F4F6]/20 p-3 backdrop-blur-[26px]">
{/* Left section */}
{!isSmallScreen ? (
<div className="flex flex-1 items-center gap-5">
{isLoggedIn
? linksWithChat.map((link) => (
<NavbarLink
key={link.name}
name={link.name}
href={link.href}
/>
))
: loggedOutLinks.map((link) => (
<NavbarLink
key={link.name}
name={link.name}
href={link.href}
/>
))}
</div>
) : null}
{/* Centered logo */}
<div className="static h-auto w-[4.5rem] md:absolute md:left-1/2 md:top-1/2 md:w-[5.5rem] md:-translate-x-1/2 md:-translate-y-1/2">
<IconAutoGPTLogo className="h-full w-full" />
</div>
{/* Right section */}
{isLoggedIn && !isSmallScreen ? (
<div className="flex flex-1 items-center justify-end gap-4">
<div className="flex items-center gap-4">
<AgentActivityDropdown />
{profile && <Wallet key={profile.username} />}
<AccountMenu
userName={profile?.username}
userEmail={profile?.name}
avatarSrc={profile?.avatar_url ?? ""}
menuItemGroups={dynamicMenuItems}
isLoading={isLoadingProfile}
/>
</div>
</div>
) : !isLoggedIn ? (
<div className="flex w-full items-center justify-end">
<LoginButton />
</div>
) : null}
{/* <ThemeToggle /> */}
</nav>
</div>
{/* Mobile Navbar - Adjust positioning */}
<>
{isLoggedIn && isSmallScreen ? (
<div className="fixed right-0 top-2 z-50 flex items-center gap-0">
<Wallet />
<MobileNavBar
userName={profile?.username}
menuItemGroups={[
{
groupName: "Navigation",
items: linksWithChat.map((link) => ({
icon:
link.name === "Marketplace"
? IconType.Marketplace
: link.name === "Library"
? IconType.Library
: link.name === "Build"
? IconType.Builder
: link.name === "Chat"
? IconType.Chat
: link.name === "Monitor"
? IconType.Library
: IconType.LayoutDashboard,
text: link.name,
href: link.href,
})),
},
...dynamicMenuItems,
]}
userEmail={profile?.name}
avatarSrc={profile?.avatar_url ?? ""}
/>
</div>
) : null}
</>
</>
);
}

View File

@@ -1,25 +0,0 @@
import { prefetchGetV2GetUserProfileQuery } from "@/app/api/__generated__/endpoints/store/store";
import { getQueryClient } from "@/lib/react-query/queryClient";
import { getServerUser } from "@/lib/supabase/server/getServerUser";
export async function getNavbarAccountData() {
const { user } = await getServerUser();
const isLoggedIn = Boolean(user);
const queryClient = getQueryClient();
if (!isLoggedIn) {
return {
profile: null,
isLoggedIn,
};
}
try {
await prefetchGetV2GetUserProfileQuery(queryClient);
} catch (error) {
console.error("Error fetching profile:", error);
}
return {
isLoggedIn,
};
}

View File

@@ -2,7 +2,6 @@
import { DEFAULT_SEARCH_TERMS } from "@/app/(platform)/marketplace/components/HeroSection/helpers";
import { useFlags } from "launchdarkly-react-client-sdk";
import { environment } from "../environment";
export enum Flag {
BETA_BLOCKS = "beta-blocks",
@@ -40,7 +39,7 @@ const mockFlags = {
[Flag.BETA_BLOCKS]: [],
[Flag.NEW_BLOCK_MENU]: false,
[Flag.NEW_AGENT_RUNS]: false,
[Flag.GRAPH_SEARCH]: true,
[Flag.GRAPH_SEARCH]: false,
[Flag.ENABLE_ENHANCED_OUTPUT_HANDLING]: false,
[Flag.NEW_FLOW_EDITOR]: false,
[Flag.BUILDER_VIEW_SWITCH]: false,
@@ -48,17 +47,20 @@ const mockFlags = {
[Flag.AGENT_FAVORITING]: false,
[Flag.MARKETPLACE_SEARCH_TERMS]: DEFAULT_SEARCH_TERMS,
[Flag.ENABLE_PLATFORM_PAYMENT]: false,
[Flag.CHAT]: true,
[Flag.CHAT]: false,
};
export function useGetFlag<T extends Flag>(flag: T): FlagValues[T] | null {
const currentFlags = useFlags<FlagValues>();
const flagValue = currentFlags[flag];
const isCloud = environment.isCloud();
if ((isPwMockEnabled && !isCloud) || flagValue === undefined) {
const envEnabled = process.env.NEXT_PUBLIC_LAUNCHDARKLY_ENABLED === "true";
const clientId = process.env.NEXT_PUBLIC_LAUNCHDARKLY_CLIENT_ID;
const isLaunchDarklyConfigured = envEnabled && clientId;
if (!isLaunchDarklyConfigured || isPwMockEnabled) {
return mockFlags[flag];
}
return flagValue;
return flagValue ?? mockFlags[flag];
}