Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { memo, useMemo, useRef, useState } from "react";
import { useLocation } from "react-router-dom";
import { useHotkeys } from "react-hotkeys-hook";
import { useShallow } from "zustand/react/shallow";
import IconComponent from "@/components/common/genericIconComponent";
Expand Down Expand Up @@ -57,6 +58,7 @@ export const MenuBar = memo((): JSX.Element => {
const onFlowPage = useFlowStore((state) => state.onFlowPage);
const measureRef = useRef<HTMLSpanElement>(null);
const changesNotSaved = useUnsavedChanges();
const location = useLocation();

const { data: folders, isFetched: isFoldersFetched } = useGetFoldersQuery();

Expand Down Expand Up @@ -88,6 +90,21 @@ export const MenuBar = memo((): JSX.Element => {
: getNumberFromString(currentFlowGradient ?? currentFlowId ?? "")) %
swatchColors.length;

// Determine if we should hide the flow name when viewing Marketplace Detail > Flow Visualization
const pathname = location.pathname || "";
const isMarketplaceDetail = pathname.includes("/marketplace/detail");
const routerState = location.state as { hideDetailName?: boolean } | undefined;
let marketplaceDetailActiveTab: string | null = null;
try {
marketplaceDetailActiveTab = typeof window !== "undefined"
? window.sessionStorage.getItem("marketplaceDetailActiveTab")
: null;
} catch {
marketplaceDetailActiveTab = null;
}
const shouldHideFlowName =
isMarketplaceDetail && (routerState?.hideDetailName || marketplaceDetailActiveTab === "flow");

return onFlowPage ? (
<Popover open={openSettings} onOpenChange={setOpenSettings}>
<PopoverAnchor>
Expand Down Expand Up @@ -123,33 +140,37 @@ export const MenuBar = memo((): JSX.Element => {
>

</div>
<div className={cn(`flex rounded p-1`, swatchColors[swatchIndex])}>
{!shouldHideFlowName && <div className={cn(`flex rounded p-1`, swatchColors[swatchIndex])}>
<IconComponent
name={currentFlowIcon ?? "Workflow"}
className="h-3.5 w-3.5"
/>
</div>
</div>}
<PopoverTrigger asChild>
<div
className="group relative -mr-5 flex shrink-0 cursor-pointer items-center gap-2 text-sm sm:whitespace-normal"
data-testid="menu_bar_display"
>
<span
ref={measureRef}
className="w-fit max-w-[35vw] truncate whitespace-pre text-mmd font-semibold sm:max-w-full sm:text-sm text-white"
aria-hidden="true"
data-testid="flow_name"
>
{currentFlowName || "Untitled Flow"}
</span>
<IconComponent
name="pencil"
className={cn(
"h-5 w-3.5 -translate-x-2 opacity-0 transition-all",
!openSettings &&
"sm:group-hover:translate-x-0 sm:group-hover:opacity-100",
)}
/>
{!shouldHideFlowName && (
<>
<span
ref={measureRef}
className="w-fit max-w-[35vw] truncate whitespace-pre text-mmd font-semibold sm:max-w-full sm:text-sm text-white"
aria-hidden="true"
data-testid="flow_name"
>
{currentFlowName || "Untitled Flow"}
</span>
<IconComponent
name="pencil"
className={cn(
"h-5 w-3.5 -translate-x-2 opacity-0 transition-all",
!openSettings &&
"sm:group-hover:translate-x-0 sm:group-hover:opacity-100",
)}
/>
</>
)}
</div>
</PopoverTrigger>
<div className={"ml-5 hidden shrink-0 items-center sm:flex"}>
Expand Down
2 changes: 1 addition & 1 deletion src/frontend/src/modals/publishFlowModal/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,7 @@ export default function PublishFlowModal({
<div className="space-y-4 py-4 overflow-y-auto pr-2">
<div className="space-y-2">
<Label htmlFor="marketplace-name">
Marketplace Flow Name <span className="text-destructive">*</span>
Name <span className="text-destructive">*</span>
</Label>
<div className="relative">
<Input
Expand Down
28 changes: 25 additions & 3 deletions src/frontend/src/pages/MarketplacePage/DetailPage.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useState } from "react";
import { useParams } from "react-router-dom";
import { useEffect, useState } from "react";
import { useLocation, useNavigate, useParams } from "react-router-dom";
import { Prism as SyntaxHighlighter } from "react-syntax-highlighter";
import {
oneDark,
Expand All @@ -23,6 +23,8 @@ export default function MarketplaceDetailPage() {
const dark = useDarkStore((state) => state.dark);
const navigate = useCustomNavigate();
const [activeTab, setActiveTab] = useState("playground");
const location = useLocation();
const navigateRouter = useNavigate();

// Fetch published flow details
const { data: publishedFlowData, isLoading: isLoadingPublishedFlow } =
Expand All @@ -35,6 +37,26 @@ export default function MarketplaceDetailPage() {
const title = publishedFlowData?.flow_name || "Published Flow";
const description = publishedFlowData?.description || "";

// Restore previously selected tab on mount (persisted in sessionStorage)
useEffect(() => {
const saved = sessionStorage.getItem("marketplaceDetailActiveTab");
if (saved === "playground" || saved === "flow" || saved === "spec") {
setActiveTab(saved);
}
}, []);

// Persist tab selection and signal AppHeader to hide the detail name on Flow Visualization
useEffect(() => {
sessionStorage.setItem("marketplaceDetailActiveTab", activeTab);
const hideDetailName = activeTab === "flow";
const prevState = (location.state as any) || {};
// Replace current history entry to avoid changing the URL, only adjust state
navigateRouter(location.pathname, {
state: { ...prevState, hideDetailName },
replace: true,
});
}, [activeTab, navigateRouter, location.pathname]);

// Handle Edit button click - navigate to the original flow (not the clone)
const handleEditClick = () => {
if (publishedFlowData?.flow_cloned_from) {
Expand Down Expand Up @@ -109,7 +131,7 @@ export default function MarketplaceDetailPage() {
>
<div className="flex w-full flex-col gap-4 dark:text-white">
<div className="flex flex-col h-full">
<Tabs defaultValue="playground" className="w-full h-full" onValueChange={setActiveTab}>
<Tabs value={activeTab} className="w-full h-full" onValueChange={(val) => setActiveTab(val)}>
<div className="flex items-center justify-between mt-1 relative">
<TabsList className="justify-start gap-2 border-b border-border dark:border-white/20 p-0">
<TabsTrigger
Expand Down