diff --git a/src/frontend/src/pages/FlowPage/components/flowSidebarComponent/components/sidebarItemsList.tsx b/src/frontend/src/pages/FlowPage/components/flowSidebarComponent/components/sidebarItemsList.tsx
index 945b07c50d39..a93ae9ba0f00 100644
--- a/src/frontend/src/pages/FlowPage/components/flowSidebarComponent/components/sidebarItemsList.tsx
+++ b/src/frontend/src/pages/FlowPage/components/flowSidebarComponent/components/sidebarItemsList.tsx
@@ -1,8 +1,8 @@
-import { useMemo } from "react";
import ShadTooltip from "@/components/common/shadTooltipComponent";
import useFlowStore from "@/stores/flowStore";
import { checkChatInput, checkWebhookInput } from "@/utils/reactflowUtils";
import { removeCountFromString } from "@/utils/utils";
+import { useMemo } from "react";
import { disableItem } from "../helpers/disable-item";
import { getDisabledTooltip } from "../helpers/get-disabled-tooltip";
import type { UniqueInputsComponents } from "../types";
@@ -16,7 +16,7 @@ const SidebarItemsList = ({
sensitiveSort,
}) => {
return (
-
+
{Object.keys(dataFilter[item.name])
.sort((a, b) => {
const itemA = dataFilter[item.name][a];
diff --git a/src/frontend/src/pages/FlowPage/components/flowSidebarComponent/index.tsx b/src/frontend/src/pages/FlowPage/components/flowSidebarComponent/index.tsx
index 60dcf6148ad3..2a321e895fa2 100644
--- a/src/frontend/src/pages/FlowPage/components/flowSidebarComponent/index.tsx
+++ b/src/frontend/src/pages/FlowPage/components/flowSidebarComponent/index.tsx
@@ -1,17 +1,3 @@
-import Fuse from "fuse.js";
-import { cloneDeep } from "lodash";
-import {
- createContext,
- memo,
- useCallback,
- useContext,
- useEffect,
- useMemo,
- useRef,
- useState,
-} from "react";
-import { useHotkeys } from "react-hotkeys-hook";
-import { useShallow } from "zustand/react/shallow";
import {
Sidebar,
SidebarContent,
@@ -30,6 +16,20 @@ import {
SIDEBAR_CATEGORIES,
} from "@/utils/styleUtils";
import { cn, getBooleanFromStorage } from "@/utils/utils";
+import Fuse from "fuse.js";
+import { cloneDeep } from "lodash";
+import {
+ createContext,
+ memo,
+ useCallback,
+ useContext,
+ useEffect,
+ useMemo,
+ useRef,
+ useState,
+} from "react";
+import { useHotkeys } from "react-hotkeys-hook";
+import { useShallow } from "zustand/react/shallow";
import useFlowStore from "../../../../stores/flowStore";
import { useTypesStore } from "../../../../stores/typesStore";
import type { APIClassType } from "../../../../types/api";
@@ -683,7 +683,7 @@ export function FlowSidebarComponent({ isLoading }: FlowSidebarComponentProps) {
{ENABLE_NEW_SIDEBAR &&
activeSection === "mcp" &&
!hasMcpServers ? null : (
-
+
Date: Thu, 4 Sep 2025 21:04:36 +0000
Subject: [PATCH 2/6] [autofix.ci] apply automated fixes
---
.../core/appHeaderComponent/index.tsx | 2 +-
src/frontend/src/components/ui/sidebar.tsx | 5 +--
.../components/McpSidebarGroup.tsx | 2 +-
.../components/categoryDisclouse.tsx | 2 +-
.../components/categoryGroup.tsx | 2 +-
.../components/searchConfigTrigger.tsx | 5 +--
.../components/searchInput.tsx | 6 ++-
.../components/sidebarBundles.tsx | 2 +-
.../components/sidebarDraggableComponent.tsx | 2 +-
.../components/sidebarFooterButtons.tsx | 38 +++++++++----------
.../components/sidebarItemsList.tsx | 2 +-
.../components/flowSidebarComponent/index.tsx | 28 +++++++-------
12 files changed, 47 insertions(+), 49 deletions(-)
diff --git a/src/frontend/src/components/core/appHeaderComponent/index.tsx b/src/frontend/src/components/core/appHeaderComponent/index.tsx
index 8841606ef2c1..7518f418a29e 100644
--- a/src/frontend/src/components/core/appHeaderComponent/index.tsx
+++ b/src/frontend/src/components/core/appHeaderComponent/index.tsx
@@ -1,3 +1,4 @@
+import { useEffect, useRef, useState } from "react";
import AlertDropdown from "@/alerts/alertDropDown";
import DataStaxLogo from "@/assets/DataStaxLogo.svg?react";
import LangflowLogo from "@/assets/LangflowLogo.svg?react";
@@ -13,7 +14,6 @@ import { ENABLE_DATASTAX_LANGFLOW } from "@/customization/feature-flags";
import { useCustomNavigate } from "@/customization/hooks/use-custom-navigate";
import useTheme from "@/customization/hooks/use-custom-theme";
import useAlertStore from "@/stores/alertStore";
-import { useEffect, useRef, useState } from "react";
import FlowMenu from "./components/FlowMenu";
export default function AppHeader(): JSX.Element {
diff --git a/src/frontend/src/components/ui/sidebar.tsx b/src/frontend/src/components/ui/sidebar.tsx
index 6abb66f070a2..05fd30d18cee 100644
--- a/src/frontend/src/components/ui/sidebar.tsx
+++ b/src/frontend/src/components/ui/sidebar.tsx
@@ -1,11 +1,11 @@
"use client";
-import { useIsMobile } from "@/hooks/use-mobile";
import { Slot } from "@radix-ui/react-slot";
import { cva, type VariantProps } from "class-variance-authority";
import { PanelLeft } from "lucide-react";
import * as React from "react";
import { useHotkeys } from "react-hotkeys-hook";
+import { useIsMobile } from "@/hooks/use-mobile";
import isWrappedWithClass from "../../pages/FlowPage/components/PageComponent/utils/is-wrapped-with-class";
import { useShortcutsStore } from "../../stores/shortcuts";
import { cn } from "../../utils/utils";
@@ -865,6 +865,5 @@ export {
SidebarRail,
SidebarSeparator,
SidebarTrigger,
- useSidebar
+ useSidebar,
};
-
diff --git a/src/frontend/src/pages/FlowPage/components/flowSidebarComponent/components/McpSidebarGroup.tsx b/src/frontend/src/pages/FlowPage/components/flowSidebarComponent/components/McpSidebarGroup.tsx
index eb14053c46b8..5f57eeec54f4 100644
--- a/src/frontend/src/pages/FlowPage/components/flowSidebarComponent/components/McpSidebarGroup.tsx
+++ b/src/frontend/src/pages/FlowPage/components/flowSidebarComponent/components/McpSidebarGroup.tsx
@@ -1,3 +1,4 @@
+import { useState } from "react";
import ShadTooltip from "@/components/common/shadTooltipComponent";
import { Button } from "@/components/ui/button";
import {
@@ -12,7 +13,6 @@ import DeleteConfirmationModal from "@/modals/deleteConfirmationModal";
import useAlertStore from "@/stores/alertStore";
import type { APIClassType } from "@/types/api";
import { removeCountFromString } from "@/utils/utils";
-import { useState } from "react";
import { SearchConfigTrigger } from "./searchConfigTrigger";
import SidebarDraggableComponent from "./sidebarDraggableComponent";
diff --git a/src/frontend/src/pages/FlowPage/components/flowSidebarComponent/components/categoryDisclouse.tsx b/src/frontend/src/pages/FlowPage/components/flowSidebarComponent/components/categoryDisclouse.tsx
index 3e6e238acdff..a7158f99ff10 100644
--- a/src/frontend/src/pages/FlowPage/components/flowSidebarComponent/components/categoryDisclouse.tsx
+++ b/src/frontend/src/pages/FlowPage/components/flowSidebarComponent/components/categoryDisclouse.tsx
@@ -1,3 +1,4 @@
+import { memo, useCallback } from "react";
import { ForwardedIconComponent } from "@/components/common/genericIconComponent";
import {
Disclosure,
@@ -6,7 +7,6 @@ import {
} from "@/components/ui/disclosure";
import { SidebarMenuButton, SidebarMenuItem } from "@/components/ui/sidebar";
import type { APIClassType } from "@/types/api";
-import { memo, useCallback } from "react";
import SidebarItemsList from "./sidebarItemsList";
export const CategoryDisclosure = memo(function CategoryDisclosure({
diff --git a/src/frontend/src/pages/FlowPage/components/flowSidebarComponent/components/categoryGroup.tsx b/src/frontend/src/pages/FlowPage/components/flowSidebarComponent/components/categoryGroup.tsx
index 09def1fb6a5c..a631a19e0cb4 100644
--- a/src/frontend/src/pages/FlowPage/components/flowSidebarComponent/components/categoryGroup.tsx
+++ b/src/frontend/src/pages/FlowPage/components/flowSidebarComponent/components/categoryGroup.tsx
@@ -1,3 +1,4 @@
+import { memo } from "react";
import {
SidebarGroup,
SidebarGroupContent,
@@ -6,7 +7,6 @@ import {
} from "@/components/ui/sidebar";
import { ENABLE_NEW_SIDEBAR } from "@/customization/feature-flags";
import { SIDEBAR_BUNDLES } from "@/utils/styleUtils";
-import { memo } from "react";
import type { CategoryGroupProps } from "../types";
import { CategoryDisclosure } from "./categoryDisclouse";
import { SearchConfigTrigger } from "./searchConfigTrigger";
diff --git a/src/frontend/src/pages/FlowPage/components/flowSidebarComponent/components/searchConfigTrigger.tsx b/src/frontend/src/pages/FlowPage/components/flowSidebarComponent/components/searchConfigTrigger.tsx
index 35adc7eb1b43..881b0726555c 100644
--- a/src/frontend/src/pages/FlowPage/components/flowSidebarComponent/components/searchConfigTrigger.tsx
+++ b/src/frontend/src/pages/FlowPage/components/flowSidebarComponent/components/searchConfigTrigger.tsx
@@ -22,10 +22,7 @@ export const SearchConfigTrigger = ({
className="hover:text-primary text-muted-foreground"
style={{ padding: "0px" }}
>
-
+
diff --git a/src/frontend/src/pages/FlowPage/components/flowSidebarComponent/components/searchInput.tsx b/src/frontend/src/pages/FlowPage/components/flowSidebarComponent/components/searchInput.tsx
index 918b9aaf6bf6..99c6cb00642e 100644
--- a/src/frontend/src/pages/FlowPage/components/flowSidebarComponent/components/searchInput.tsx
+++ b/src/frontend/src/pages/FlowPage/components/flowSidebarComponent/components/searchInput.tsx
@@ -1,6 +1,6 @@
+import { memo } from "react";
import { Input } from "@/components/ui/input";
import { ENABLE_NEW_SIDEBAR } from "@/customization/feature-flags";
-import { memo } from "react";
import ShortcutDisplay from "../../nodeToolbarComponent/shortcutDisplay";
export const SearchInput = memo(function SearchInput({
@@ -33,7 +33,9 @@ export const SearchInput = memo(function SearchInput({
value={search}
/>
{!isInputFocused && search === "" && (
-
+
diff --git a/src/frontend/src/pages/FlowPage/components/flowSidebarComponent/components/sidebarBundles.tsx b/src/frontend/src/pages/FlowPage/components/flowSidebarComponent/components/sidebarBundles.tsx
index 6bc770531a4a..9fb2446143d8 100644
--- a/src/frontend/src/pages/FlowPage/components/flowSidebarComponent/components/sidebarBundles.tsx
+++ b/src/frontend/src/pages/FlowPage/components/flowSidebarComponent/components/sidebarBundles.tsx
@@ -1,3 +1,4 @@
+import { memo, useMemo } from "react";
import {
SidebarGroup,
SidebarGroupContent,
@@ -5,7 +6,6 @@ import {
SidebarMenu,
} from "@/components/ui/sidebar";
import { ENABLE_NEW_SIDEBAR } from "@/customization/feature-flags";
-import { memo, useMemo } from "react";
import type { SidebarGroupProps } from "../types";
import { BundleItem } from "./bundleItems";
import { SearchConfigTrigger } from "./searchConfigTrigger";
diff --git a/src/frontend/src/pages/FlowPage/components/flowSidebarComponent/components/sidebarDraggableComponent.tsx b/src/frontend/src/pages/FlowPage/components/flowSidebarComponent/components/sidebarDraggableComponent.tsx
index a15dbf046d83..d5fc796b01ac 100644
--- a/src/frontend/src/pages/FlowPage/components/flowSidebarComponent/components/sidebarDraggableComponent.tsx
+++ b/src/frontend/src/pages/FlowPage/components/flowSidebarComponent/components/sidebarDraggableComponent.tsx
@@ -1,3 +1,4 @@
+import { type DragEventHandler, forwardRef, useRef, useState } from "react";
import IconComponent, {
ForwardedIconComponent,
} from "@/components/common/genericIconComponent";
@@ -22,7 +23,6 @@ import {
getNodeId,
} from "@/utils/reactflowUtils";
import { cn, removeCountFromString } from "@/utils/utils";
-import { type DragEventHandler, forwardRef, useRef, useState } from "react";
export const SidebarDraggableComponent = forwardRef(
(
diff --git a/src/frontend/src/pages/FlowPage/components/flowSidebarComponent/components/sidebarFooterButtons.tsx b/src/frontend/src/pages/FlowPage/components/flowSidebarComponent/components/sidebarFooterButtons.tsx
index 893ed19614f0..eb8f291d3b8f 100644
--- a/src/frontend/src/pages/FlowPage/components/flowSidebarComponent/components/sidebarFooterButtons.tsx
+++ b/src/frontend/src/pages/FlowPage/components/flowSidebarComponent/components/sidebarFooterButtons.tsx
@@ -1,10 +1,10 @@
+import { useState } from "react";
import ForwardedIconComponent from "@/components/common/genericIconComponent";
import { Button } from "@/components/ui/button";
import { SidebarMenuButton, useSidebar } from "@/components/ui/sidebar";
import { ENABLE_NEW_SIDEBAR } from "@/customization/feature-flags";
import { useCustomNavigate } from "@/customization/hooks/use-custom-navigate";
import AddMcpServerModal from "@/modals/addMcpServerModal";
-import { useState } from "react";
const SidebarMenuButtons = ({
customComponent,
@@ -63,25 +63,25 @@ const SidebarMenuButtons = ({
>
) : (
//
-
+ disabled={isLoading}
+ onClick={() => {
+ if (customComponent) {
+ addComponent(customComponent, "CustomComponent");
+ }
+ }}
+ data-testid="sidebar-custom-component-button"
+ className="flex items-center w-full h-full p-3 gap-2 hover:bg-muted"
+ >
+
+
+ New Custom Component
+
+
//
)}
diff --git a/src/frontend/src/pages/FlowPage/components/flowSidebarComponent/components/sidebarItemsList.tsx b/src/frontend/src/pages/FlowPage/components/flowSidebarComponent/components/sidebarItemsList.tsx
index a93ae9ba0f00..7dfde7838838 100644
--- a/src/frontend/src/pages/FlowPage/components/flowSidebarComponent/components/sidebarItemsList.tsx
+++ b/src/frontend/src/pages/FlowPage/components/flowSidebarComponent/components/sidebarItemsList.tsx
@@ -1,8 +1,8 @@
+import { useMemo } from "react";
import ShadTooltip from "@/components/common/shadTooltipComponent";
import useFlowStore from "@/stores/flowStore";
import { checkChatInput, checkWebhookInput } from "@/utils/reactflowUtils";
import { removeCountFromString } from "@/utils/utils";
-import { useMemo } from "react";
import { disableItem } from "../helpers/disable-item";
import { getDisabledTooltip } from "../helpers/get-disabled-tooltip";
import type { UniqueInputsComponents } from "../types";
diff --git a/src/frontend/src/pages/FlowPage/components/flowSidebarComponent/index.tsx b/src/frontend/src/pages/FlowPage/components/flowSidebarComponent/index.tsx
index 2a321e895fa2..05c658935115 100644
--- a/src/frontend/src/pages/FlowPage/components/flowSidebarComponent/index.tsx
+++ b/src/frontend/src/pages/FlowPage/components/flowSidebarComponent/index.tsx
@@ -1,3 +1,17 @@
+import Fuse from "fuse.js";
+import { cloneDeep } from "lodash";
+import {
+ createContext,
+ memo,
+ useCallback,
+ useContext,
+ useEffect,
+ useMemo,
+ useRef,
+ useState,
+} from "react";
+import { useHotkeys } from "react-hotkeys-hook";
+import { useShallow } from "zustand/react/shallow";
import {
Sidebar,
SidebarContent,
@@ -16,20 +30,6 @@ import {
SIDEBAR_CATEGORIES,
} from "@/utils/styleUtils";
import { cn, getBooleanFromStorage } from "@/utils/utils";
-import Fuse from "fuse.js";
-import { cloneDeep } from "lodash";
-import {
- createContext,
- memo,
- useCallback,
- useContext,
- useEffect,
- useMemo,
- useRef,
- useState,
-} from "react";
-import { useHotkeys } from "react-hotkeys-hook";
-import { useShallow } from "zustand/react/shallow";
import useFlowStore from "../../../../stores/flowStore";
import { useTypesStore } from "../../../../stores/typesStore";
import type { APIClassType } from "../../../../types/api";
From a2b03790394c103992565d72932abcf8bb8011ad Mon Sep 17 00:00:00 2001
From: Deon Sanchez <69873175+deon-sanchez@users.noreply.github.com>
Date: Fri, 5 Sep 2025 09:25:34 -0600
Subject: [PATCH 3/6] refactor: update FlowMenu and CanvasControlsDropdown
styles, enhance MemoizedCanvasControls with flow lock status
---
.../components/FlowMenu/index.tsx | 4 --
.../CanvasControlsDropdown.tsx | 4 +-
.../PageComponent/MemoizedComponents.tsx | 57 ++++++++++---------
.../components/flowSidebarComponent/index.tsx | 45 ++++++++++-----
4 files changed, 64 insertions(+), 46 deletions(-)
diff --git a/src/frontend/src/components/core/appHeaderComponent/components/FlowMenu/index.tsx b/src/frontend/src/components/core/appHeaderComponent/components/FlowMenu/index.tsx
index 96daffc21d07..be769e856653 100644
--- a/src/frontend/src/components/core/appHeaderComponent/components/FlowMenu/index.tsx
+++ b/src/frontend/src/components/core/appHeaderComponent/components/FlowMenu/index.tsx
@@ -142,10 +142,6 @@ export const MenuBar = memo((): JSX.Element => {
>
{currentFlowName || "Untitled Flow"}
- {isFlowLocked && (
-
- )}
-
{
title="Canvas Controls"
>
-
+
{formatZoomPercentage(zoom)}
diff --git a/src/frontend/src/pages/FlowPage/components/PageComponent/MemoizedComponents.tsx b/src/frontend/src/pages/FlowPage/components/PageComponent/MemoizedComponents.tsx
index 2d71c2a97aeb..d7eae73b8a7e 100644
--- a/src/frontend/src/pages/FlowPage/components/PageComponent/MemoizedComponents.tsx
+++ b/src/frontend/src/pages/FlowPage/components/PageComponent/MemoizedComponents.tsx
@@ -1,5 +1,6 @@
import { Background, Panel } from "@xyflow/react";
import { memo } from "react";
+import { useShallow } from "zustand/react/shallow";
import ForwardedIconComponent from "@/components/common/genericIconComponent";
import CanvasControlButton from "@/components/core/canvasControlsComponent/CanvasControlButton";
import CanvasControls from "@/components/core/canvasControlsComponent/CanvasControls";
@@ -7,6 +8,7 @@ import LogCanvasControls from "@/components/core/logCanvasControlsComponent";
import { Button } from "@/components/ui/button";
import { SidebarTrigger, useSidebar } from "@/components/ui/sidebar";
import { ENABLE_NEW_SIDEBAR } from "@/customization/feature-flags";
+import useFlowStore from "@/stores/flowStore";
import { cn } from "@/utils/utils";
import { useSearchContext } from "../flowSidebarComponent";
import { NAV_ITEMS } from "../flowSidebarComponent/components/sidebarSegmentedNav";
@@ -30,32 +32,35 @@ export const MemoizedCanvasControls = memo(
position,
shadowBoxWidth,
shadowBoxHeight,
- }: MemoizedCanvasControlsProps) => (
-
-
-
- ),
+ }: MemoizedCanvasControlsProps) => {
+ const isLocked = useFlowStore(
+ useShallow((state) => state.currentFlow?.locked),
+ );
+
+ return (
+
+
+
+ );
+ },
);
export const MemoizedSidebarTrigger = memo(() => {
diff --git a/src/frontend/src/pages/FlowPage/components/flowSidebarComponent/index.tsx b/src/frontend/src/pages/FlowPage/components/flowSidebarComponent/index.tsx
index 05c658935115..6d61291937d9 100644
--- a/src/frontend/src/pages/FlowPage/components/flowSidebarComponent/index.tsx
+++ b/src/frontend/src/pages/FlowPage/components/flowSidebarComponent/index.tsx
@@ -1,17 +1,5 @@
-import Fuse from "fuse.js";
-import { cloneDeep } from "lodash";
-import {
- createContext,
- memo,
- useCallback,
- useContext,
- useEffect,
- useMemo,
- useRef,
- useState,
-} from "react";
-import { useHotkeys } from "react-hotkeys-hook";
-import { useShallow } from "zustand/react/shallow";
+import ForwardedIconComponent from "@/components/common/genericIconComponent";
+import { Button } from "@/components/ui/button";
import {
Sidebar,
SidebarContent,
@@ -30,6 +18,20 @@ import {
SIDEBAR_CATEGORIES,
} from "@/utils/styleUtils";
import { cn, getBooleanFromStorage } from "@/utils/utils";
+import Fuse from "fuse.js";
+import { cloneDeep } from "lodash";
+import {
+ createContext,
+ memo,
+ useCallback,
+ useContext,
+ useEffect,
+ useMemo,
+ useRef,
+ useState,
+} from "react";
+import { useHotkeys } from "react-hotkeys-hook";
+import { useShallow } from "zustand/react/shallow";
import useFlowStore from "../../../../stores/flowStore";
import { useTypesStore } from "../../../../stores/typesStore";
import type { APIClassType } from "../../../../types/api";
@@ -669,6 +671,21 @@ export function FlowSidebarComponent({ isLoading }: FlowSidebarComponentProps) {
setShowConfig={setShowConfig}
/>
)}
+ {showComponents && (
+
+ )}
>
) : (
Date: Fri, 5 Sep 2025 10:08:23 -0600
Subject: [PATCH 4/6] feat: add 'Sticky Notes' functionality to sidebar and
enhance note handling
- Introduced a new 'add_note' section in the sidebar for adding sticky notes.
- Implemented event listeners to manage the add-note flow, allowing for better integration with the sidebar.
- Updated styles and structure in various components to accommodate the new feature.
- Refactored existing components for improved organization and readability.
---
src/frontend/src/components/ui/sidebar.tsx | 7 +-
.../components/PageComponent/index.tsx | 66 ++++++++-----
.../components/sidebarDraggableComponent.tsx | 4 +-
.../components/sidebarSegmentedNav.tsx | 99 ++++++++++++-------
.../components/flowSidebarComponent/index.tsx | 2 +-
5 files changed, 114 insertions(+), 64 deletions(-)
diff --git a/src/frontend/src/components/ui/sidebar.tsx b/src/frontend/src/components/ui/sidebar.tsx
index 05fd30d18cee..d12ec056c2f4 100644
--- a/src/frontend/src/components/ui/sidebar.tsx
+++ b/src/frontend/src/components/ui/sidebar.tsx
@@ -1,11 +1,11 @@
"use client";
+import { useIsMobile } from "@/hooks/use-mobile";
import { Slot } from "@radix-ui/react-slot";
import { cva, type VariantProps } from "class-variance-authority";
import { PanelLeft } from "lucide-react";
import * as React from "react";
import { useHotkeys } from "react-hotkeys-hook";
-import { useIsMobile } from "@/hooks/use-mobile";
import isWrappedWithClass from "../../pages/FlowPage/components/PageComponent/utils/is-wrapped-with-class";
import { useShortcutsStore } from "../../stores/shortcuts";
import { cn } from "../../utils/utils";
@@ -23,7 +23,7 @@ const SIDEBAR_WIDTH = "19rem";
const SIDEBAR_WIDTH_ICON = "4rem";
const SEGMENTED_SIDEBAR_ICON_WIDTH = "40px";
-export type SidebarSection = "search" | "components" | "bundles" | "mcp";
+export type SidebarSection = "search" | "components" | "bundles" | "mcp" | "add_note";
// Helper function to get cookie value
function getCookie(name: string): string | null {
@@ -865,5 +865,6 @@ export {
SidebarRail,
SidebarSeparator,
SidebarTrigger,
- useSidebar,
+ useSidebar
};
+
diff --git a/src/frontend/src/pages/FlowPage/components/PageComponent/index.tsx b/src/frontend/src/pages/FlowPage/components/PageComponent/index.tsx
index 9e65e5f59948..26d8c8d90242 100644
--- a/src/frontend/src/pages/FlowPage/components/PageComponent/index.tsx
+++ b/src/frontend/src/pages/FlowPage/components/PageComponent/index.tsx
@@ -1,3 +1,19 @@
+import { DefaultEdge } from "@/CustomEdges";
+import NoteNode from "@/CustomNodes/NoteNode";
+import FlowToolbar from "@/components/core/flowToolbarComponent";
+import {
+ COLOR_OPTIONS,
+ NOTE_NODE_MIN_HEIGHT,
+ NOTE_NODE_MIN_WIDTH,
+} from "@/constants/constants";
+import { useGetBuildsQuery } from "@/controllers/API/queries/_builds";
+import CustomLoader from "@/customization/components/custom-loader";
+import { track } from "@/customization/utils/analytics";
+import useAutoSaveFlow from "@/hooks/flows/use-autosave-flow";
+import useUploadFlow from "@/hooks/flows/use-upload-flow";
+import { useAddComponent } from "@/hooks/use-add-component";
+import { nodeColorsName } from "@/utils/styleUtils";
+import { isSupportedNodeTypes } from "@/utils/utils";
import {
type Connection,
type Edge,
@@ -19,22 +35,6 @@ import {
} from "react";
import { useHotkeys } from "react-hotkeys-hook";
import { useShallow } from "zustand/react/shallow";
-import { DefaultEdge } from "@/CustomEdges";
-import NoteNode from "@/CustomNodes/NoteNode";
-import FlowToolbar from "@/components/core/flowToolbarComponent";
-import {
- COLOR_OPTIONS,
- NOTE_NODE_MIN_HEIGHT,
- NOTE_NODE_MIN_WIDTH,
-} from "@/constants/constants";
-import { useGetBuildsQuery } from "@/controllers/API/queries/_builds";
-import CustomLoader from "@/customization/components/custom-loader";
-import { track } from "@/customization/utils/analytics";
-import useAutoSaveFlow from "@/hooks/flows/use-autosave-flow";
-import useUploadFlow from "@/hooks/flows/use-upload-flow";
-import { useAddComponent } from "@/hooks/use-add-component";
-import { nodeColorsName } from "@/utils/styleUtils";
-import { isSupportedNodeTypes } from "@/utils/utils";
import GenericNode from "../../../../CustomNodes/GenericNode";
import {
INVALID_SELECTION_ERROR_ALERT,
@@ -63,21 +63,21 @@ import {
validateSelection,
} from "../../../../utils/reactflowUtils";
import ConnectionLineComponent from "../ConnectionLineComponent";
-import FlowBuildingComponent from "../flowBuildingComponent";
import SelectionMenu from "../SelectionMenuComponent";
import UpdateAllComponents from "../UpdateAllComponents";
-import HelperLines from "./components/helper-lines";
-import {
- getHelperLines,
- getSnapPosition,
- type HelperLinesState,
-} from "./helpers/helper-lines";
+import FlowBuildingComponent from "../flowBuildingComponent";
import {
MemoizedBackground,
MemoizedCanvasControls,
MemoizedLogCanvasControls,
MemoizedSidebarTrigger,
} from "./MemoizedComponents";
+import HelperLines from "./components/helper-lines";
+import {
+ getHelperLines,
+ getSnapPosition,
+ type HelperLinesState,
+} from "./helpers/helper-lines";
import getRandomName from "./utils/get-random-name";
import isWrappedWithClass from "./utils/is-wrapped-with-class";
@@ -613,6 +613,8 @@ export default function Page({
};
setNodes((nds) => nds.concat(newNode));
setIsAddingNote(false);
+ // Signal sidebar to revert add_note active state
+ window.dispatchEvent(new Event("lf:end-add-note"));
}
},
[
@@ -657,6 +659,24 @@ export default function Page({
};
}, [isAddingNote, shadowBoxWidth, shadowBoxHeight]);
+ // Listen for a global event to start the add-note flow from outside components
+ useEffect(() => {
+ const handleStartAddNote = () => {
+ setIsAddingNote(true);
+ const shadowBox = document.getElementById("shadow-box");
+ if (shadowBox) {
+ shadowBox.style.display = "block";
+ shadowBox.style.left = `${position.current.x - shadowBoxWidth / 2}px`;
+ shadowBox.style.top = `${position.current.y - shadowBoxHeight / 2}px`;
+ }
+ };
+
+ window.addEventListener("lf:start-add-note", handleStartAddNote);
+ return () => {
+ window.removeEventListener("lf:start-add-note", handleStartAddNote);
+ };
+ }, [shadowBoxWidth, shadowBoxHeight]);
+
const MIN_ZOOM = 0.25;
const MAX_ZOOM = 2;
const fitViewOptions = {
diff --git a/src/frontend/src/pages/FlowPage/components/flowSidebarComponent/components/sidebarDraggableComponent.tsx b/src/frontend/src/pages/FlowPage/components/flowSidebarComponent/components/sidebarDraggableComponent.tsx
index d5fc796b01ac..da89da95d32b 100644
--- a/src/frontend/src/pages/FlowPage/components/flowSidebarComponent/components/sidebarDraggableComponent.tsx
+++ b/src/frontend/src/pages/FlowPage/components/flowSidebarComponent/components/sidebarDraggableComponent.tsx
@@ -1,4 +1,3 @@
-import { type DragEventHandler, forwardRef, useRef, useState } from "react";
import IconComponent, {
ForwardedIconComponent,
} from "@/components/common/genericIconComponent";
@@ -23,6 +22,7 @@ import {
getNodeId,
} from "@/utils/reactflowUtils";
import { cn, removeCountFromString } from "@/utils/utils";
+import { type DragEventHandler, forwardRef, useRef, useState } from "react";
export const SidebarDraggableComponent = forwardRef(
(
@@ -141,7 +141,7 @@ export const SidebarDraggableComponent = forwardRef(
"group/draggable flex cursor-grab items-center gap-2 rounded-md bg-muted p-1 px-2 hover:bg-secondary-hover/75",
error && "cursor-not-allowed select-none",
disabled
- ? "pointer-events-none bg-accent text-placeholder-foreground"
+ ? "pointer-events-none bg-accent text-placeholder-foreground h-8"
: "bg-muted text-foreground",
)}
draggable={!error}
diff --git a/src/frontend/src/pages/FlowPage/components/flowSidebarComponent/components/sidebarSegmentedNav.tsx b/src/frontend/src/pages/FlowPage/components/flowSidebarComponent/components/sidebarSegmentedNav.tsx
index ecc1abc06665..41f5581ea52a 100644
--- a/src/frontend/src/pages/FlowPage/components/flowSidebarComponent/components/sidebarSegmentedNav.tsx
+++ b/src/frontend/src/pages/FlowPage/components/flowSidebarComponent/components/sidebarSegmentedNav.tsx
@@ -1,5 +1,6 @@
import ForwardedIconComponent from "@/components/common/genericIconComponent";
import ShadTooltip from "@/components/common/shadTooltipComponent";
+import { Separator } from "@/components/ui/separator";
import {
SidebarMenu,
SidebarMenuButton,
@@ -8,6 +9,7 @@ import {
useSidebar,
} from "@/components/ui/sidebar";
import { cn } from "@/utils/utils";
+import { useEffect, useState } from "react";
import { useSearchContext } from "../index";
export type { SidebarSection };
@@ -44,51 +46,78 @@ export const NAV_ITEMS: NavItem[] = [
label: "Bundles",
tooltip: "Bundles",
},
+ {
+ id: "add_note",
+ icon: "sticky-note",
+ label: "Sticky Notes",
+ tooltip: "Add Sticky Notes",
+ },
];
-export default function SidebarSegmentedNav() {
+const SidebarSegmentedNav = () => {
const { activeSection, setActiveSection, toggleSidebar, open } = useSidebar();
const { focusSearch, setSearch } = useSearchContext();
+ const [isAddNoteActive, setIsAddNoteActive] = useState(false);
+ const handleAddNote = () => {
+ window.dispatchEvent(new Event("lf:start-add-note"));
+ setIsAddNoteActive(true);
+ };
+
+ useEffect(() => {
+ const onEnd = () => setIsAddNoteActive(false);
+ window.addEventListener("lf:end-add-note", onEnd);
+ return () => window.removeEventListener("lf:end-add-note", onEnd);
+ }, []);
+
return (
-
+
{NAV_ITEMS.map((item) => (
-
-
- {
- setSearch?.("");
- if (activeSection === item.id && open) {
- toggleSidebar();
- } else {
- setActiveSection(item.id);
- if (!open) {
- toggleSidebar();
+ <>
+ {item.id === "add_note" && }
+
+
+ {
+ if (item.id === "add_note") {
+ e.stopPropagation();
+ handleAddNote();
+ return;
}
- // Focus search input when search section is selected
- if (item.id === "search") {
- // Add a small delay to ensure the sidebar is open and input is rendered
- setTimeout(() => focusSearch(), 100);
+
+ setSearch?.("");
+ if (activeSection === item.id && open) {
+ toggleSidebar();
+ } else {
+ setActiveSection(item.id);
+ if (!open) {
+ toggleSidebar();
+ }
+ if (item.id === "search") {
+ setTimeout(() => focusSearch(), 100);
+ }
}
- }
- }}
- isActive={activeSection === item.id}
- className={cn(
- "flex h-8 w-8 items-center justify-center rounded-md p-0 transition-all duration-200",
- activeSection === item.id
- ? "bg-accent text-accent-foreground"
- : "text-muted-foreground hover:bg-accent hover:text-accent-foreground",
- )}
- data-testid={`sidebar-nav-${item.id}`}
- >
-
- {item.label}
-
-
-
+ }}
+ isActive={item.id === "add_note" ? isAddNoteActive : activeSection === item.id}
+ className={cn(
+ "flex h-8 w-8 items-center justify-center rounded-md p-0 transition-all duration-200",
+ (item.id === "add_note" ? isAddNoteActive : activeSection === item.id)
+ ? "bg-accent text-accent-foreground"
+ : "text-muted-foreground hover:bg-accent hover:text-accent-foreground",
+ )}
+ data-testid={`sidebar-nav-${item.id}`}
+ >
+
+ {item.label}
+
+
+
+ >
))}
);
-}
+};
+
+export default SidebarSegmentedNav;
diff --git a/src/frontend/src/pages/FlowPage/components/flowSidebarComponent/index.tsx b/src/frontend/src/pages/FlowPage/components/flowSidebarComponent/index.tsx
index 6d61291937d9..e204b41ea603 100644
--- a/src/frontend/src/pages/FlowPage/components/flowSidebarComponent/index.tsx
+++ b/src/frontend/src/pages/FlowPage/components/flowSidebarComponent/index.tsx
@@ -675,7 +675,7 @@ export function FlowSidebarComponent({ isLoading }: FlowSidebarComponentProps) {