merge fix
This commit is contained in:
commit
c3ff98c499
40 changed files with 480 additions and 317 deletions
|
|
@ -301,3 +301,10 @@ def get_top_level_vertices(graph, vertices_ids):
|
|||
else:
|
||||
top_level_vertices.append(vertex_id)
|
||||
return top_level_vertices
|
||||
|
||||
|
||||
def parse_exception(exc):
|
||||
"""Parse the exception message."""
|
||||
if hasattr(exc, "body"):
|
||||
return exc.body["message"]
|
||||
return str(exc)
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ from langflow.api.utils import (
|
|||
format_elapsed_time,
|
||||
format_exception_message,
|
||||
get_top_level_vertices,
|
||||
parse_exception,
|
||||
)
|
||||
from langflow.api.v1.schemas import (
|
||||
InputValueRequest,
|
||||
|
|
@ -314,7 +315,10 @@ async def build_vertex_stream(
|
|||
|
||||
except Exception as exc:
|
||||
logger.exception(f"Error building vertex: {exc}")
|
||||
yield str(StreamData(event="error", data={"error": str(exc)}))
|
||||
exc_message = parse_exception(exc)
|
||||
if exc_message == "The message must be an iterator or an async iterator.":
|
||||
exc_message = "This stream has already been closed."
|
||||
yield str(StreamData(event="error", data={"error": exc_message}))
|
||||
finally:
|
||||
logger.debug("Closing stream")
|
||||
yield str(StreamData(event="close", data={"message": "Stream closed"}))
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ from langflow.schema import Record
|
|||
|
||||
|
||||
class FileComponent(CustomComponent):
|
||||
display_name = "Files"
|
||||
display_name = "File"
|
||||
description = "A generic file loader."
|
||||
|
||||
def build_config(self) -> Dict[str, Any]:
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ from langflow.schema import Record
|
|||
|
||||
class URLComponent(CustomComponent):
|
||||
display_name = "URL"
|
||||
description = "Fetch text content given one or more URLs."
|
||||
description = "Fetch content from one or more URLs."
|
||||
|
||||
def build_config(self) -> Dict[str, Any]:
|
||||
return {
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ from langflow.schema import Record
|
|||
|
||||
class CreateRecordComponent(CustomComponent):
|
||||
display_name = "Create Record"
|
||||
description = "A component to create a record."
|
||||
description = "Create a Record structure using text-based key/value pairs."
|
||||
beta: bool = True
|
||||
|
||||
def build_config(self):
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
from langflow.field_typing import Data
|
||||
# from langflow.field_typing import Data
|
||||
from langflow.schema import Record
|
||||
from langflow.interface.custom.custom_component import CustomComponent
|
||||
|
||||
|
||||
|
|
@ -11,5 +12,5 @@ class Component(CustomComponent):
|
|||
def build_config(self):
|
||||
return {"param": {"display_name": "Parameter"}}
|
||||
|
||||
def build(self, param: Data) -> Data:
|
||||
return param
|
||||
def build(self, param: str) -> Record:
|
||||
return Record(data=param)
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ from langflow.schema import Record
|
|||
|
||||
class MessageHistoryComponent(CustomComponent):
|
||||
display_name = "Message History"
|
||||
description = "Used to retrieve stored chat messages."
|
||||
description = "Retrieves stored chat messages given a specific Session ID."
|
||||
beta: bool = True
|
||||
|
||||
def build_config(self):
|
||||
|
|
|
|||
|
|
@ -6,7 +6,8 @@ from langflow.schema import Record
|
|||
|
||||
class RecordsToTextComponent(CustomComponent):
|
||||
display_name = "Records To Text"
|
||||
description = "Convert Records into plain text using a pre-defined template."
|
||||
description = "Convert Records into plain text following a specified template."
|
||||
|
||||
|
||||
def build_config(self):
|
||||
return {
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ from langflow.schema import Record
|
|||
|
||||
class UpdateRecordComponent(CustomComponent):
|
||||
display_name = "Update Record"
|
||||
description = "Updates a Record with new data. Akin to a Python dictionary update."
|
||||
description = "Update Record with text-based key/value pairs, similar to updating a Python dictionary."
|
||||
|
||||
def build_config(self):
|
||||
return {
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ from langflow.schema import Record
|
|||
|
||||
class ChatInput(ChatComponent):
|
||||
display_name = "Chat Input"
|
||||
description = "Capture user inputs from the chat interface."
|
||||
description = "Get chat inputs from the Interaction Panel."
|
||||
icon = "ChatInput"
|
||||
|
||||
def build(
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ from langflow.interface.custom.custom_component import CustomComponent
|
|||
|
||||
class PromptComponent(CustomComponent):
|
||||
display_name: str = "Prompt"
|
||||
description: str = "A component for creating prompt templates using dynamic variables."
|
||||
description: str = "Create prompt templates with dynamic variables. Prompts can help guide the behavior of a Language Model."
|
||||
icon = "terminal-square"
|
||||
|
||||
def build_config(self):
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ from langflow.field_typing import Text
|
|||
|
||||
class TextInput(TextComponent):
|
||||
display_name = "Text Input"
|
||||
description = "Capture Text or Record and send text inputs."
|
||||
description = "Get text inputs from the Interaction Panel."
|
||||
|
||||
def build_config(self):
|
||||
return {
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ from langflow.field_typing import Text
|
|||
|
||||
class AmazonBedrockComponent(LCModelComponent):
|
||||
display_name: str = "Amazon Bedrock"
|
||||
description: str = "Generate text using LLM model from Amazon Bedrock."
|
||||
description: str = "Generate text using Amazon Bedrock LLMs."
|
||||
icon = "Amazon"
|
||||
field_order = [
|
||||
"model_id",
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ from langflow.field_typing import Text
|
|||
|
||||
class AnthropicLLM(LCModelComponent):
|
||||
display_name: str = "Anthropic"
|
||||
description: str = "Generate text using Anthropic Chat&Completion large language models."
|
||||
description: str = "Generate text using Anthropic Chat&Completion LLMs."
|
||||
icon = "Anthropic"
|
||||
|
||||
def build_config(self):
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ from langflow.field_typing import Text
|
|||
|
||||
class AzureChatOpenAIComponent(LCModelComponent):
|
||||
display_name: str = "Azure OpenAI"
|
||||
description: str = "Generate text using LLM model from Azure OpenAI."
|
||||
description: str = "Generate text using Azure OpenAI LLMs."
|
||||
documentation: str = "https://python.langchain.com/docs/integrations/llms/azure_openai"
|
||||
beta = False
|
||||
icon = "Azure"
|
||||
|
|
|
|||
|
|
@ -9,10 +9,8 @@ from langflow.field_typing import Text
|
|||
|
||||
class QianfanChatEndpointComponent(LCModelComponent):
|
||||
display_name: str = "Qianfan"
|
||||
description: str = (
|
||||
"Generate text using Baidu Qianfan chat models. Get more detail from "
|
||||
"https://python.langchain.com/docs/integrations/chat/baidu_qianfan_endpoint."
|
||||
)
|
||||
description: str = "Generate text using Baidu Qianfan LLMs."
|
||||
documentation: str = "https://python.langchain.com/docs/integrations/chat/baidu_qianfan_endpoint."
|
||||
icon = "BaiduQianfan"
|
||||
|
||||
def build_config(self):
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ from langflow.field_typing import Text
|
|||
|
||||
class CohereComponent(LCModelComponent):
|
||||
display_name = "Cohere"
|
||||
description = "Generate text using Cohere large language models."
|
||||
description = "Generate text using Cohere LLMs."
|
||||
documentation = "https://python.langchain.com/docs/modules/model_io/models/llms/integrations/cohere"
|
||||
|
||||
icon = "Cohere"
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ from langflow.field_typing import RangeSpec, Text
|
|||
|
||||
class GoogleGenerativeAIComponent(LCModelComponent):
|
||||
display_name: str = "Google Generative AI"
|
||||
description: str = "Generate text using Google Generative AI to generate text."
|
||||
description: str = "Generate text using Google Generative AI."
|
||||
icon = "GoogleGenerativeAI"
|
||||
icon = "Google"
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ from langflow.field_typing import Text
|
|||
|
||||
class HuggingFaceEndpointsComponent(LCModelComponent):
|
||||
display_name: str = "Hugging Face API"
|
||||
description: str = "Generate text using LLM model from Hugging Face Inference API."
|
||||
description: str = "Generate text using Hugging Face Inference APIs."
|
||||
icon = "HuggingFace"
|
||||
|
||||
def build_config(self):
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ from langflow.field_typing import Text
|
|||
|
||||
class ChatOllamaComponent(LCModelComponent):
|
||||
display_name = "Ollama"
|
||||
description = "Generate text using Local LLM for chat with Ollama."
|
||||
description = "Generate text using Ollama Local LLMs."
|
||||
icon = "Ollama"
|
||||
|
||||
def build_config(self) -> dict:
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ from langflow.field_typing import NestedDict, Text
|
|||
|
||||
class OpenAIModelComponent(LCModelComponent):
|
||||
display_name = "OpenAI"
|
||||
description = "Generates text using OpenAI's models."
|
||||
description = "Generates text using OpenAI LLMs."
|
||||
icon = "OpenAI"
|
||||
|
||||
def build_config(self):
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ from langflow.field_typing import Text
|
|||
|
||||
class ChatVertexAIComponent(LCModelComponent):
|
||||
display_name = "Vertex AI"
|
||||
description = "Generate text using Vertex AI Chat large language models API."
|
||||
description = "Generate text using Vertex AI LLMs."
|
||||
icon = "VertexAI"
|
||||
|
||||
def build_config(self):
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ from langflow.schema import Record
|
|||
|
||||
class ChatOutput(ChatComponent):
|
||||
display_name = "Chat Output"
|
||||
description = "Used to send a chat message."
|
||||
description = "Display a chat message in the Interaction Panel."
|
||||
icon = "ChatOutput"
|
||||
|
||||
def build(
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ from langflow.field_typing import Text
|
|||
|
||||
class TextOutput(TextComponent):
|
||||
display_name = "Text Output"
|
||||
description = "Used to send a text output."
|
||||
description = "Display a text output in the Interaction Panel."
|
||||
|
||||
def build_config(self):
|
||||
return {
|
||||
|
|
|
|||
|
|
@ -10,5 +10,5 @@ class DefaultPromptField(TemplateField):
|
|||
|
||||
advanced: bool = False
|
||||
multiline: bool = True
|
||||
input_types: list[str] = ["Document", "BaseOutputParser", "Text", "Record"]
|
||||
input_types: list[str] = ["Document", "BaseOutputParser", "Record", "Text"]
|
||||
value: str = "" # Set the value to empty string
|
||||
|
|
|
|||
|
|
@ -421,8 +421,8 @@ export default function ParameterComponent({
|
|||
{title}
|
||||
</span>
|
||||
)}
|
||||
<span className={(info === "" ? "" : "ml-1 ") + " text-status-red"}>
|
||||
{required ? " *" : ""}
|
||||
<span className={(info === "" ? "" : "ml-1 ") + " text-status-red pl-1"}>
|
||||
{required ? "*" : ""}
|
||||
</span>
|
||||
<div className="">
|
||||
{info !== "" && (
|
||||
|
|
@ -487,7 +487,7 @@ export default function ParameterComponent({
|
|||
{left === true &&
|
||||
type === "str" &&
|
||||
!data.node?.template[name].options ? (
|
||||
<div className="mt-2 w-full">
|
||||
<div className="w-full">
|
||||
{data.node?.template[name].list ? (
|
||||
<div
|
||||
className={
|
||||
|
|
@ -628,7 +628,7 @@ export default function ParameterComponent({
|
|||
isLoading={isLoading}
|
||||
options={data.node.template[name].options}
|
||||
onSelect={handleOnNewValue}
|
||||
value={data.node.template[name].value ?? "Choose an option"}
|
||||
value={data.node.template[name].value}
|
||||
id={"dropdown-" + name}
|
||||
/>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ export default function AddNewVariableButton({ children }): JSX.Element {
|
|||
}}
|
||||
selectedOption={type}
|
||||
password={false}
|
||||
options={["Variable", "Credential"]}
|
||||
options={["Generic", "Credential"]}
|
||||
placeholder="Choose a type for the variable..."
|
||||
></InputComponent>
|
||||
<Label>Value</Label>
|
||||
|
|
@ -92,7 +92,7 @@ export default function AddNewVariableButton({ children }): JSX.Element {
|
|||
</div>
|
||||
</BaseModal.Content>
|
||||
<BaseModal.Footer>
|
||||
<Button onClick={handleSaveVariable}>Save variable</Button>
|
||||
<Button onClick={handleSaveVariable}>Save Variable</Button>
|
||||
</BaseModal.Footer>
|
||||
</BaseModal>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -52,11 +52,11 @@ export default function Dropdown({
|
|||
editNode ? "input-edit-node" : "py-2"
|
||||
)}
|
||||
>
|
||||
<span data-testid={`value-${id ?? ""}`}>
|
||||
{value
|
||||
? options.find((option) => option === value)
|
||||
: "Choose an option..."}
|
||||
</span>
|
||||
{value &&
|
||||
value !== "" &&
|
||||
options.find((option) => option === value)
|
||||
? options.find((option) => option === value)
|
||||
: "Choose an option..."}
|
||||
<ForwardedIconComponent
|
||||
name="ChevronsUpDown"
|
||||
className="ml-2 h-4 w-4 shrink-0 opacity-50"
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import Robot from "../../../assets/robot.png";
|
|||
import SanitizedHTMLWrapper from "../../../components/SanitizedHTMLWrapper";
|
||||
import CodeTabsComponent from "../../../components/codeTabsComponent";
|
||||
import IconComponent from "../../../components/genericIconComponent";
|
||||
import useAlertStore from "../../../stores/alertStore";
|
||||
import useFlowStore from "../../../stores/flowStore";
|
||||
import { chatMessagePropsType } from "../../../types/components";
|
||||
import { classNames } from "../../../utils/utils";
|
||||
|
|
@ -33,6 +34,7 @@ export default function ChatMessage({
|
|||
const [isStreaming, setIsStreaming] = useState(false);
|
||||
const eventSource = useRef<EventSource | undefined>(undefined);
|
||||
const updateFlowPool = useFlowStore((state) => state.updateFlowPool);
|
||||
const setErrorData = useAlertStore((state) => state.setErrorData);
|
||||
const chatMessageRef = useRef(chatMessage);
|
||||
|
||||
// Sync ref with state
|
||||
|
|
@ -57,7 +59,17 @@ export default function ChatMessage({
|
|||
setIsStreaming(false);
|
||||
eventSource.current?.close();
|
||||
setStreamUrl(undefined);
|
||||
reject(new Error("Streaming failed"));
|
||||
// property data is not available in the event object
|
||||
// so check if the event object has a data property
|
||||
if (event.data) {
|
||||
let parsedData = JSON.parse(event.data);
|
||||
if (parsedData.error) {
|
||||
reject(new Error(parsedData.error));
|
||||
} else
|
||||
reject(new Error("An error occurred while streaming the output"));
|
||||
} else {
|
||||
reject(new Error("An error occurred while streaming the output"));
|
||||
}
|
||||
};
|
||||
eventSource.current.addEventListener("close", (event) => {
|
||||
setStreamUrl(undefined); // Update state to reflect the stream is closed
|
||||
|
|
@ -79,7 +91,10 @@ export default function ChatMessage({
|
|||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error(error);
|
||||
setErrorData({
|
||||
title: "Streaming Error",
|
||||
list: [error.message],
|
||||
});
|
||||
setLockChat(false);
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,14 +41,27 @@ export interface ButtonProps
|
|||
asChild?: boolean;
|
||||
}
|
||||
|
||||
function toTitleCase(text: string) {
|
||||
return text
|
||||
.split(' ')
|
||||
.map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
|
||||
.join(' ');
|
||||
}
|
||||
|
||||
const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
|
||||
({ className, variant, size, asChild = false, ...props }, ref) => {
|
||||
({ className, variant, size, asChild = false,children, ...props }, ref) => {
|
||||
const Comp = asChild ? Slot : "button";
|
||||
let newChildren = children;
|
||||
if (typeof(children)==="string"){
|
||||
newChildren = toTitleCase(children)
|
||||
}
|
||||
return (
|
||||
<Comp
|
||||
className={cn(buttonVariants({ variant, size, className }))}
|
||||
ref={ref}
|
||||
children={newChildren}
|
||||
{...props}
|
||||
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ export const CODE_DIALOG_SUBTITLE =
|
|||
* @constant
|
||||
*/
|
||||
export const CHAT_FORM_DIALOG_SUBTITLE =
|
||||
"Adjust or overwrite input values, inspect outputs or interact through the chat console.";
|
||||
"Set up the input variables defined in prompt templates. Interact with agents and chains.";
|
||||
|
||||
/**
|
||||
* The base text for subtitle of Edit Node Dialog
|
||||
|
|
@ -732,12 +732,14 @@ export const PRIORITY_SIDEBAR_ORDER = [
|
|||
"saved_components",
|
||||
"inputs",
|
||||
"outputs",
|
||||
"prompts",
|
||||
"data",
|
||||
"prompt",
|
||||
"models",
|
||||
"helpers",
|
||||
"vectorstores",
|
||||
"vectorsearch",
|
||||
"helpers",
|
||||
"embeddings",
|
||||
];
|
||||
export const NATIVE_CATEGORIES = [
|
||||
"inputs",
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import { DisclosureComponentType } from "../../../../types/components";
|
|||
|
||||
export default function DisclosureComponent({
|
||||
button: { title, Icon, buttons = [] },
|
||||
isChild = true,
|
||||
children,
|
||||
openDisc,
|
||||
}: DisclosureComponentType): JSX.Element {
|
||||
|
|
@ -13,10 +14,14 @@ export default function DisclosureComponent({
|
|||
<>
|
||||
<div>
|
||||
<Disclosure.Button
|
||||
className="components-disclosure-arrangement"
|
||||
className={
|
||||
isChild
|
||||
? "components-disclosure-arrangement-child"
|
||||
: "components-disclosure-arrangement"
|
||||
}
|
||||
data-testid={`disclosure-${title.toLocaleLowerCase()}`}
|
||||
>
|
||||
<div className="flex gap-4">
|
||||
<div className={"flex gap-4" + (isChild ? " pl-2" : "")}>
|
||||
{/* BUG ON THIS ICON */}
|
||||
<Icon strokeWidth={1.5} size={22} className="text-primary" />
|
||||
<span className="components-disclosure-title">{title}</span>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,41 @@
|
|||
import { Disclosure } from "@headlessui/react";
|
||||
import IconComponent from "../../../../components/genericIconComponent";
|
||||
import { DisclosureComponentType } from "../../../../types/components";
|
||||
|
||||
export default function ParentDisclosureComponent({
|
||||
button: { title, Icon, buttons = [] },
|
||||
children,
|
||||
openDisc,
|
||||
}: DisclosureComponentType): JSX.Element {
|
||||
return (
|
||||
<Disclosure as="div" defaultOpen={openDisc} key={title}>
|
||||
{({ open }) => (
|
||||
<>
|
||||
<div>
|
||||
<Disclosure.Button className="parent-disclosure-arrangement">
|
||||
<div className="flex gap-4">
|
||||
<span className="parent-disclosure-title">{title}</span>
|
||||
</div>
|
||||
<div className="components-disclosure-div">
|
||||
{buttons.map((btn, index) => (
|
||||
<button key={index} onClick={btn.onClick}>
|
||||
{btn.Icon}
|
||||
</button>
|
||||
))}
|
||||
<div>
|
||||
<IconComponent
|
||||
name="ChevronRight"
|
||||
className={`${
|
||||
open || openDisc ? "rotate-90 transform" : ""
|
||||
} h-4 w-4 text-foreground`}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</Disclosure.Button>
|
||||
</div>
|
||||
<Disclosure.Panel as="div">{children}</Disclosure.Panel>
|
||||
</>
|
||||
)}
|
||||
</Disclosure>
|
||||
);
|
||||
}
|
||||
|
|
@ -5,6 +5,7 @@ import ShadTooltip from "../../../../components/ShadTooltipComponent";
|
|||
import IconComponent from "../../../../components/genericIconComponent";
|
||||
import { Input } from "../../../../components/ui/input";
|
||||
import { Separator } from "../../../../components/ui/separator";
|
||||
import { PRIORITY_SIDEBAR_ORDER } from "../../../../constants/constants";
|
||||
import ExportModal from "../../../../modals/exportModal";
|
||||
import ShareModal from "../../../../modals/shareModal";
|
||||
import useAlertStore from "../../../../stores/alertStore";
|
||||
|
|
@ -24,6 +25,7 @@ import {
|
|||
sensitiveSort,
|
||||
} from "../../../../utils/utils";
|
||||
import DisclosureComponent from "../DisclosureComponent";
|
||||
import ParentDisclosureComponent from "../ParentDisclosureComponent";
|
||||
import SidebarDraggableComponent from "./sideBarDraggableComponent";
|
||||
import { sortKeys } from "./utils";
|
||||
|
||||
|
|
@ -271,23 +273,17 @@ export default function ExtraSidebar(): JSX.Element {
|
|||
<div className="side-bar-components-div-arrangement">
|
||||
{Object.keys(dataFilter)
|
||||
.sort(sortKeys)
|
||||
.filter((x) => PRIORITY_SIDEBAR_ORDER.includes(x))
|
||||
.map((SBSectionName: keyof APIObjectType, index) =>
|
||||
Object.keys(dataFilter[SBSectionName]).length > 0 ? (
|
||||
<>
|
||||
{index === 0 && (
|
||||
<div className="pt-0.5">
|
||||
<div className="p-2 px-4 text-sm font-semibold" key={index}>
|
||||
Native Components
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<DisclosureComponent
|
||||
openDisc={
|
||||
getFilterEdge.length !== 0 || search.length !== 0
|
||||
? true
|
||||
: false
|
||||
}
|
||||
isChild={false}
|
||||
key={index + search + JSON.stringify(getFilterEdge)}
|
||||
button={{
|
||||
title: nodeNames[SBSectionName] ?? nodeNames.unknown,
|
||||
|
|
@ -342,37 +338,124 @@ export default function ExtraSidebar(): JSX.Element {
|
|||
))}
|
||||
</div>
|
||||
</DisclosureComponent>
|
||||
{index === Object.keys(dataFilter).length - 1 && (
|
||||
<>
|
||||
<a
|
||||
target={"_blank"}
|
||||
href="https://langflow.store"
|
||||
className="components-disclosure-arrangement"
|
||||
>
|
||||
<div className="flex gap-4">
|
||||
{/* BUG ON THIS ICON */}
|
||||
<SparklesIcon
|
||||
strokeWidth={1.5}
|
||||
className="w-[22px] text-primary"
|
||||
/>
|
||||
|
||||
<span className="components-disclosure-title">
|
||||
Discover More
|
||||
</span>
|
||||
</div>
|
||||
<div className="components-disclosure-div">
|
||||
<div>
|
||||
<LinkIcon className="h-4 w-4 text-foreground" />
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
) : (
|
||||
<div key={index}></div>
|
||||
)
|
||||
)}
|
||||
)}{" "}
|
||||
<ParentDisclosureComponent
|
||||
openDisc={
|
||||
getFilterEdge.length !== 0 || search.length !== 0 ? true : false
|
||||
}
|
||||
key={"Extended"}
|
||||
button={{
|
||||
title: "Extended",
|
||||
Icon: nodeIconsLucide.unknown,
|
||||
}}
|
||||
>
|
||||
{Object.keys(dataFilter)
|
||||
.sort(sortKeys)
|
||||
.filter((x) => !PRIORITY_SIDEBAR_ORDER.includes(x))
|
||||
.map((SBSectionName: keyof APIObjectType, index) =>
|
||||
Object.keys(dataFilter[SBSectionName]).length > 0 ? (
|
||||
<>
|
||||
<DisclosureComponent
|
||||
openDisc={
|
||||
getFilterEdge.length !== 0 || search.length !== 0
|
||||
? true
|
||||
: false
|
||||
}
|
||||
key={index + search + JSON.stringify(getFilterEdge)}
|
||||
button={{
|
||||
title: nodeNames[SBSectionName] ?? nodeNames.unknown,
|
||||
Icon:
|
||||
nodeIconsLucide[SBSectionName] ??
|
||||
nodeIconsLucide.unknown,
|
||||
}}
|
||||
>
|
||||
<div className="side-bar-components-gap">
|
||||
{Object.keys(dataFilter[SBSectionName])
|
||||
.sort((a, b) =>
|
||||
sensitiveSort(
|
||||
dataFilter[SBSectionName][a].display_name,
|
||||
dataFilter[SBSectionName][b].display_name
|
||||
)
|
||||
)
|
||||
.map((SBItemName: string, index) => (
|
||||
<ShadTooltip
|
||||
content={
|
||||
dataFilter[SBSectionName][SBItemName].display_name
|
||||
}
|
||||
side="right"
|
||||
key={index}
|
||||
>
|
||||
<SidebarDraggableComponent
|
||||
sectionName={SBSectionName as string}
|
||||
apiClass={dataFilter[SBSectionName][SBItemName]}
|
||||
key={index}
|
||||
onDragStart={(event) =>
|
||||
onDragStart(event, {
|
||||
//split type to remove type in nodes saved with same name removing it's
|
||||
type: removeCountFromString(SBItemName),
|
||||
node: dataFilter[SBSectionName][SBItemName],
|
||||
})
|
||||
}
|
||||
color={nodeColors[SBSectionName]}
|
||||
itemName={SBItemName}
|
||||
//convert error to boolean
|
||||
error={
|
||||
!!dataFilter[SBSectionName][SBItemName].error
|
||||
}
|
||||
display_name={
|
||||
dataFilter[SBSectionName][SBItemName]
|
||||
.display_name
|
||||
}
|
||||
official={
|
||||
dataFilter[SBSectionName][SBItemName]
|
||||
.official === false
|
||||
? false
|
||||
: true
|
||||
}
|
||||
/>
|
||||
</ShadTooltip>
|
||||
))}
|
||||
</div>
|
||||
</DisclosureComponent>
|
||||
{index ===
|
||||
Object.keys(dataFilter).length -
|
||||
PRIORITY_SIDEBAR_ORDER.length +
|
||||
1 && (
|
||||
<>
|
||||
<a
|
||||
target={"_blank"}
|
||||
href="https://langflow.store"
|
||||
className="components-disclosure-arrangement"
|
||||
>
|
||||
<div className="flex gap-4">
|
||||
{/* BUG ON THIS ICON */}
|
||||
<SparklesIcon
|
||||
strokeWidth={1.5}
|
||||
className="w-[22px] text-primary"
|
||||
/>
|
||||
|
||||
<span className="components-disclosure-title">
|
||||
Discover More
|
||||
</span>
|
||||
</div>
|
||||
<div className="components-disclosure-div">
|
||||
<div>
|
||||
<LinkIcon className="h-4 w-4 text-foreground" />
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
) : (
|
||||
<div key={index}></div>
|
||||
)
|
||||
)}
|
||||
</ParentDisclosureComponent>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -117,7 +117,7 @@
|
|||
@apply relative inline-flex w-full items-center justify-center rounded-md bg-background px-2 py-2 text-foreground transition-all duration-500 ease-in-out;
|
||||
}
|
||||
.header-menubar-item {
|
||||
@apply relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors hover:bg-accent hover:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 cursor-pointer;
|
||||
@apply relative flex cursor-default cursor-pointer select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors hover:bg-accent hover:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50;
|
||||
}
|
||||
.extra-side-bar-buttons:hover {
|
||||
@apply hover:bg-muted;
|
||||
|
|
@ -183,9 +183,19 @@
|
|||
.disabled-message-button-icon {
|
||||
@apply fill-chat-trigger-disabled stroke-chat-trigger-disabled stroke-1;
|
||||
}
|
||||
.parent-disclosure-arrangement {
|
||||
@apply flex w-full select-none items-center justify-between border-y border-y-input bg-background px-3 py-2;
|
||||
}
|
||||
.components-disclosure-arrangement {
|
||||
@apply -mt-px flex w-full select-none items-center justify-between border-y border-y-input bg-muted px-3 py-2;
|
||||
}
|
||||
.components-disclosure-arrangement-child {
|
||||
/* different color than the non child */
|
||||
@apply -mt-px flex w-full select-none items-center justify-between border-y border-y-input bg-muted px-3 py-2;
|
||||
}
|
||||
.parent-disclosure-title {
|
||||
@apply p-2 px-2 text-sm font-semibold;
|
||||
}
|
||||
.components-disclosure-title {
|
||||
@apply flex items-center text-sm text-primary;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -149,6 +149,7 @@ export type FileComponentType = {
|
|||
export type DisclosureComponentType = {
|
||||
children: ReactNode;
|
||||
openDisc: boolean;
|
||||
isChild?: boolean;
|
||||
button: {
|
||||
title: string;
|
||||
Icon: React.ElementType;
|
||||
|
|
|
|||
|
|
@ -249,7 +249,6 @@ export const nodeColors: { [char: string]: string } = {
|
|||
retrievers: "#e6b25a",
|
||||
unknown: "#9CA3AF",
|
||||
custom_components: "#ab11ab",
|
||||
Record:"#31a3cc"
|
||||
};
|
||||
|
||||
export const nodeNames: { [char: string]: string } = {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue