Format code and update langflow version (#1922)
* format * chore: Bump langflow version to 1.0.0a34 and langflow-base version to 0.0.45 * Fix fallback_to_env_vars type hint * chore: Add fallback_to_env_vars parameter to run_flow_from_json function The `run_flow_from_json` function now accepts a new optional parameter `fallback_to_env_vars` which determines whether Global Variables should fallback to environment variables if not found. This change allows for more flexibility in handling variable values. * chore: Add fallback_to_env_vars parameter to run_flow_from_json function * chore: Set file path to None when not found in component This commit modifies the `Vertex` class to set the file path to `None` when it is not found for a required field in a component. This change ensures that the code can handle missing file paths gracefully and avoids raising a `ValueError`. * chore: Add fallback_to_env_vars parameter to run_flow_from_json function * new package lock
This commit is contained in:
parent
5fe118a68a
commit
5c2ab59797
57 changed files with 14662 additions and 14666 deletions
750
poetry.lock
generated
750
poetry.lock
generated
File diff suppressed because it is too large
Load diff
|
|
@ -1,6 +1,6 @@
|
||||||
[tool.poetry]
|
[tool.poetry]
|
||||||
name = "langflow"
|
name = "langflow"
|
||||||
version = "1.0.0a33"
|
version = "1.0.0a34"
|
||||||
description = "A Python package with a built-in web application"
|
description = "A Python package with a built-in web application"
|
||||||
authors = ["Langflow <contact@langflow.org>"]
|
authors = ["Langflow <contact@langflow.org>"]
|
||||||
maintainers = [
|
maintainers = [
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,6 @@ class ChatComponent(CustomComponent):
|
||||||
sender: Optional[str] = None,
|
sender: Optional[str] = None,
|
||||||
sender_name: Optional[str] = None,
|
sender_name: Optional[str] = None,
|
||||||
) -> list[Record]:
|
) -> list[Record]:
|
||||||
|
|
||||||
records = store_message(
|
records = store_message(
|
||||||
message,
|
message,
|
||||||
session_id=session_id,
|
session_id=session_id,
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,5 @@
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
from langflow.field_typing import Text
|
|
||||||
from langflow.helpers.record import records_to_text
|
|
||||||
from langflow.interface.custom.custom_component import CustomComponent
|
from langflow.interface.custom.custom_component import CustomComponent
|
||||||
from langflow.schema.schema import Record
|
from langflow.schema.schema import Record
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
from typing import List, Optional
|
|
||||||
from pydantic.v1 import SecretStr
|
from pydantic.v1 import SecretStr
|
||||||
|
|
||||||
from langchain_mistralai.embeddings import MistralAIEmbeddings
|
from langchain_mistralai.embeddings import MistralAIEmbeddings
|
||||||
from langflow.interface.custom.custom_component import CustomComponent
|
from langflow.interface.custom.custom_component import CustomComponent
|
||||||
from langflow.field_typing import Embeddings, NestedDict
|
from langflow.field_typing import Embeddings
|
||||||
|
|
||||||
|
|
||||||
class MistralAIEmbeddingsComponent(CustomComponent):
|
class MistralAIEmbeddingsComponent(CustomComponent):
|
||||||
display_name = "MistralAI Embeddings"
|
display_name = "MistralAI Embeddings"
|
||||||
|
|
@ -37,11 +37,7 @@ class MistralAIEmbeddingsComponent(CustomComponent):
|
||||||
"advanced": True,
|
"advanced": True,
|
||||||
"value": 120,
|
"value": 120,
|
||||||
},
|
},
|
||||||
"endpoint": {
|
"endpoint": {"display_name": "API Endpoint", "advanced": True, "value": "https://api.mistral.ai/v1/"},
|
||||||
"display_name": "API Endpoint",
|
|
||||||
"advanced": True,
|
|
||||||
"value": "https://api.mistral.ai/v1/"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def build(
|
def build(
|
||||||
|
|
@ -51,7 +47,7 @@ class MistralAIEmbeddingsComponent(CustomComponent):
|
||||||
max_concurrent_requests: int = 64,
|
max_concurrent_requests: int = 64,
|
||||||
max_retries: int = 5,
|
max_retries: int = 5,
|
||||||
timeout: int = 120,
|
timeout: int = 120,
|
||||||
endpoint: str = "https://api.mistral.ai/v1/"
|
endpoint: str = "https://api.mistral.ai/v1/",
|
||||||
) -> Embeddings:
|
) -> Embeddings:
|
||||||
if mistral_api_key:
|
if mistral_api_key:
|
||||||
api_key = SecretStr(mistral_api_key)
|
api_key = SecretStr(mistral_api_key)
|
||||||
|
|
@ -64,6 +60,5 @@ class MistralAIEmbeddingsComponent(CustomComponent):
|
||||||
endpoint=endpoint,
|
endpoint=endpoint,
|
||||||
max_concurrent_requests=max_concurrent_requests,
|
max_concurrent_requests=max_concurrent_requests,
|
||||||
max_retries=max_retries,
|
max_retries=max_retries,
|
||||||
timeout=timeout
|
timeout=timeout,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,11 +3,12 @@ from langflow.interface.custom.custom_component import CustomComponent
|
||||||
from langflow.schema import Record
|
from langflow.schema import Record
|
||||||
from langflow.field_typing import Text
|
from langflow.field_typing import Text
|
||||||
|
|
||||||
|
|
||||||
class PassComponent(CustomComponent):
|
class PassComponent(CustomComponent):
|
||||||
display_name = "Pass"
|
display_name = "Pass"
|
||||||
description = "A pass-through component that forwards the second input while ignoring the first, used for controlling workflow direction."
|
description = "A pass-through component that forwards the second input while ignoring the first, used for controlling workflow direction."
|
||||||
field_order = ["ignored_input", "forwarded_input"]
|
field_order = ["ignored_input", "forwarded_input"]
|
||||||
|
|
||||||
def build_config(self) -> dict:
|
def build_config(self) -> dict:
|
||||||
return {
|
return {
|
||||||
"ignored_input": {
|
"ignored_input": {
|
||||||
|
|
@ -19,7 +20,7 @@ class PassComponent(CustomComponent):
|
||||||
"display_name": "Input",
|
"display_name": "Input",
|
||||||
"info": "This input is forwarded by the component.",
|
"info": "This input is forwarded by the component.",
|
||||||
"input_types": ["Text", "Record"],
|
"input_types": ["Text", "Record"],
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
def build(self, ignored_input: Text, forwarded_input: Text) -> Union[Text, Record]:
|
def build(self, ignored_input: Text, forwarded_input: Text) -> Union[Text, Record]:
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,6 @@ class StoreMessageComponent(CustomComponent):
|
||||||
session_id: Optional[str] = None,
|
session_id: Optional[str] = None,
|
||||||
message: str = "",
|
message: str = "",
|
||||||
) -> List[Record]:
|
) -> List[Record]:
|
||||||
|
|
||||||
store_message(
|
store_message(
|
||||||
sender=sender,
|
sender=sender,
|
||||||
sender_name=sender_name,
|
sender_name=sender_name,
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ from langflow.interface.custom.custom_component import CustomComponent
|
||||||
from langflow.schema import Record
|
from langflow.schema import Record
|
||||||
from langflow.field_typing import Text
|
from langflow.field_typing import Text
|
||||||
|
|
||||||
|
|
||||||
class TextOperatorComponent(CustomComponent):
|
class TextOperatorComponent(CustomComponent):
|
||||||
display_name = "Text Operator"
|
display_name = "Text Operator"
|
||||||
description = "Compares two text inputs based on a specified condition such as equality or inequality, with optional case sensitivity."
|
description = "Compares two text inputs based on a specified condition such as equality or inequality, with optional case sensitivity."
|
||||||
|
|
@ -21,14 +22,7 @@ class TextOperatorComponent(CustomComponent):
|
||||||
"operator": {
|
"operator": {
|
||||||
"display_name": "Operator",
|
"display_name": "Operator",
|
||||||
"info": "The operator to apply for comparing the texts.",
|
"info": "The operator to apply for comparing the texts.",
|
||||||
"options": [
|
"options": ["equals", "not equals", "contains", "starts with", "ends with", "exists"],
|
||||||
"equals",
|
|
||||||
"not equals",
|
|
||||||
"contains",
|
|
||||||
"starts with",
|
|
||||||
"ends with",
|
|
||||||
"exists"
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
"case_sensitive": {
|
"case_sensitive": {
|
||||||
"display_name": "Case Sensitive",
|
"display_name": "Case Sensitive",
|
||||||
|
|
@ -51,11 +45,8 @@ class TextOperatorComponent(CustomComponent):
|
||||||
case_sensitive: bool = False,
|
case_sensitive: bool = False,
|
||||||
true_output: Optional[Text] = "",
|
true_output: Optional[Text] = "",
|
||||||
) -> Union[Text, Record]:
|
) -> Union[Text, Record]:
|
||||||
|
|
||||||
if not input_text or not match_text:
|
if not input_text or not match_text:
|
||||||
raise ValueError(
|
raise ValueError("Both 'input_text' and 'match_text' must be provided and non-empty.")
|
||||||
"Both 'input_text' and 'match_text' must be provided and non-empty."
|
|
||||||
)
|
|
||||||
|
|
||||||
if not case_sensitive:
|
if not case_sensitive:
|
||||||
input_text = input_text.lower()
|
input_text = input_text.lower()
|
||||||
|
|
@ -82,4 +73,4 @@ class TextOperatorComponent(CustomComponent):
|
||||||
self.status = "Comparison failed, stopping execution."
|
self.status = "Comparison failed, stopping execution."
|
||||||
self.stop()
|
self.stop()
|
||||||
|
|
||||||
return output_record
|
return output_record
|
||||||
|
|
|
||||||
|
|
@ -715,9 +715,9 @@ class Graph:
|
||||||
lock: asyncio.Lock,
|
lock: asyncio.Lock,
|
||||||
set_cache_coro: Callable[["Graph", asyncio.Lock], Coroutine],
|
set_cache_coro: Callable[["Graph", asyncio.Lock], Coroutine],
|
||||||
vertex_id: str,
|
vertex_id: str,
|
||||||
fallback_to_env_vars: bool,
|
|
||||||
inputs_dict: Optional[Dict[str, str]] = None,
|
inputs_dict: Optional[Dict[str, str]] = None,
|
||||||
user_id: Optional[str] = None,
|
user_id: Optional[str] = None,
|
||||||
|
fallback_to_env_vars: bool = False,
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
Builds a vertex in the graph.
|
Builds a vertex in the graph.
|
||||||
|
|
|
||||||
|
|
@ -315,7 +315,11 @@ class Vertex:
|
||||||
params[field_name] = full_path
|
params[field_name] = full_path
|
||||||
elif field.get("required"):
|
elif field.get("required"):
|
||||||
field_display_name = field.get("display_name")
|
field_display_name = field.get("display_name")
|
||||||
raise ValueError(f"File path not found for {field_display_name} in component {self.display_name}")
|
logger.warning(
|
||||||
|
f"File path not found for {field_display_name} in component {self.display_name}. Setting to None."
|
||||||
|
)
|
||||||
|
params[field_name] = None
|
||||||
|
|
||||||
elif field.get("type") in DIRECT_TYPES and params.get(field_name) is None:
|
elif field.get("type") in DIRECT_TYPES and params.get(field_name) is None:
|
||||||
val = field.get("value")
|
val = field.get("value")
|
||||||
if field.get("type") == "code":
|
if field.get("type") == "code":
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@ import orjson
|
||||||
from langchain_community.vectorstores import (
|
from langchain_community.vectorstores import (
|
||||||
FAISS,
|
FAISS,
|
||||||
Chroma,
|
Chroma,
|
||||||
ElasticsearchStore,
|
|
||||||
MongoDBAtlasVectorSearch,
|
MongoDBAtlasVectorSearch,
|
||||||
Pinecone,
|
Pinecone,
|
||||||
Qdrant,
|
Qdrant,
|
||||||
|
|
|
||||||
|
|
@ -108,7 +108,6 @@ def store_message(
|
||||||
sender: Optional[str] = None,
|
sender: Optional[str] = None,
|
||||||
sender_name: Optional[str] = None,
|
sender_name: Optional[str] = None,
|
||||||
) -> list[Record]:
|
) -> list[Record]:
|
||||||
|
|
||||||
if not message:
|
if not message:
|
||||||
warnings.warn("No message provided.")
|
warnings.warn("No message provided.")
|
||||||
return []
|
return []
|
||||||
|
|
|
||||||
|
|
@ -82,7 +82,7 @@ def run_flow_from_json(
|
||||||
env_file: Optional[str] = None,
|
env_file: Optional[str] = None,
|
||||||
cache: Optional[str] = None,
|
cache: Optional[str] = None,
|
||||||
disable_logs: Optional[bool] = True,
|
disable_logs: Optional[bool] = True,
|
||||||
fallback_to_env_vars: Optional[bool] = False,
|
fallback_to_env_vars: bool = False,
|
||||||
) -> List[RunOutputs]:
|
) -> List[RunOutputs]:
|
||||||
"""
|
"""
|
||||||
Run a flow from a JSON file or dictionary.
|
Run a flow from a JSON file or dictionary.
|
||||||
|
|
@ -99,6 +99,7 @@ def run_flow_from_json(
|
||||||
env_file (Optional[str], optional): The environment file to load. Defaults to None.
|
env_file (Optional[str], optional): The environment file to load. Defaults to None.
|
||||||
cache (Optional[str], optional): The cache directory to use. Defaults to None.
|
cache (Optional[str], optional): The cache directory to use. Defaults to None.
|
||||||
disable_logs (Optional[bool], optional): Whether to disable logs. Defaults to True.
|
disable_logs (Optional[bool], optional): Whether to disable logs. Defaults to True.
|
||||||
|
fallback_to_env_vars (bool, optional): Whether Global Variables should fallback to environment variables if not found. Defaults to False.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
List[RunOutputs]: A list of RunOutputs objects representing the results of running the flow.
|
List[RunOutputs]: A list of RunOutputs objects representing the results of running the flow.
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ from typing import Literal, Optional, cast
|
||||||
from langchain_core.documents import Document
|
from langchain_core.documents import Document
|
||||||
from langchain_core.messages import AIMessage, BaseMessage, HumanMessage
|
from langchain_core.messages import AIMessage, BaseMessage, HumanMessage
|
||||||
from pydantic import BaseModel, model_validator
|
from pydantic import BaseModel, model_validator
|
||||||
from langchain_core.messages import HumanMessage, AIMessage
|
|
||||||
|
|
||||||
|
|
||||||
class Record(BaseModel):
|
class Record(BaseModel):
|
||||||
|
|
|
||||||
36
src/backend/base/poetry.lock
generated
36
src/backend/base/poetry.lock
generated
|
|
@ -1,4 +1,4 @@
|
||||||
# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand.
|
# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand.
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "aiohttp"
|
name = "aiohttp"
|
||||||
|
|
@ -1137,20 +1137,20 @@ extended-testing = ["faker (>=19.3.1,<20.0.0)", "jinja2 (>=3,<4)", "pandas (>=2.
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "langchain-text-splitters"
|
name = "langchain-text-splitters"
|
||||||
version = "0.0.1"
|
version = "0.0.2"
|
||||||
description = "LangChain text splitting utilities"
|
description = "LangChain text splitting utilities"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.8.1,<4.0"
|
python-versions = "<4.0,>=3.8.1"
|
||||||
files = [
|
files = [
|
||||||
{file = "langchain_text_splitters-0.0.1-py3-none-any.whl", hash = "sha256:f5b802f873f5ff6a8b9259ff34d53ed989666ef4e1582e6d1adb3b5520e3839a"},
|
{file = "langchain_text_splitters-0.0.2-py3-none-any.whl", hash = "sha256:13887f32705862c1e1454213cb7834a63aae57c26fcd80346703a1d09c46168d"},
|
||||||
{file = "langchain_text_splitters-0.0.1.tar.gz", hash = "sha256:ac459fa98799f5117ad5425a9330b21961321e30bc19a2a2f9f761ddadd62aa1"},
|
{file = "langchain_text_splitters-0.0.2.tar.gz", hash = "sha256:ac8927dc0ba08eba702f6961c9ed7df7cead8de19a9f7101ab2b5ea34201b3c1"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
langchain-core = ">=0.1.28,<0.2.0"
|
langchain-core = ">=0.1.28,<0.3"
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
extended-testing = ["lxml (>=5.1.0,<6.0.0)"]
|
extended-testing = ["beautifulsoup4 (>=4.12.3,<5.0.0)", "lxml (>=4.9.3,<6.0)"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "langchainhub"
|
name = "langchainhub"
|
||||||
|
|
@ -1169,13 +1169,13 @@ types-requests = ">=2.31.0.2,<3.0.0.0"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "langsmith"
|
name = "langsmith"
|
||||||
version = "0.1.57"
|
version = "0.1.59"
|
||||||
description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform."
|
description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform."
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = "<4.0,>=3.8.1"
|
python-versions = "<4.0,>=3.8.1"
|
||||||
files = [
|
files = [
|
||||||
{file = "langsmith-0.1.57-py3-none-any.whl", hash = "sha256:dbd83b0944a2fbea4151f0aa053530d93fcf6784a580621bc60633cb890b57dc"},
|
{file = "langsmith-0.1.59-py3-none-any.whl", hash = "sha256:445e3bc1d3baa1e5340cd979907a19483b9763a2ed37b863a01113d406f69345"},
|
||||||
{file = "langsmith-0.1.57.tar.gz", hash = "sha256:4682204de19f0218029c2b8445ce2cc3485c8d0df9796b31e2ce4c9051fce365"},
|
{file = "langsmith-0.1.59.tar.gz", hash = "sha256:e748a89f4dd6aa441349143e49e546c03b5dfb43376a25bfef6a5ca792fe1437"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
|
|
@ -1282,9 +1282,13 @@ files = [
|
||||||
{file = "lxml-5.2.2-cp36-cp36m-win_amd64.whl", hash = "sha256:edcfa83e03370032a489430215c1e7783128808fd3e2e0a3225deee278585196"},
|
{file = "lxml-5.2.2-cp36-cp36m-win_amd64.whl", hash = "sha256:edcfa83e03370032a489430215c1e7783128808fd3e2e0a3225deee278585196"},
|
||||||
{file = "lxml-5.2.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:28bf95177400066596cdbcfc933312493799382879da504633d16cf60bba735b"},
|
{file = "lxml-5.2.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:28bf95177400066596cdbcfc933312493799382879da504633d16cf60bba735b"},
|
||||||
{file = "lxml-5.2.2-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3a745cc98d504d5bd2c19b10c79c61c7c3df9222629f1b6210c0368177589fb8"},
|
{file = "lxml-5.2.2-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3a745cc98d504d5bd2c19b10c79c61c7c3df9222629f1b6210c0368177589fb8"},
|
||||||
|
{file = "lxml-5.2.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1b590b39ef90c6b22ec0be925b211298e810b4856909c8ca60d27ffbca6c12e6"},
|
||||||
{file = "lxml-5.2.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b336b0416828022bfd5a2e3083e7f5ba54b96242159f83c7e3eebaec752f1716"},
|
{file = "lxml-5.2.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b336b0416828022bfd5a2e3083e7f5ba54b96242159f83c7e3eebaec752f1716"},
|
||||||
|
{file = "lxml-5.2.2-cp37-cp37m-manylinux_2_28_aarch64.whl", hash = "sha256:c2faf60c583af0d135e853c86ac2735ce178f0e338a3c7f9ae8f622fd2eb788c"},
|
||||||
{file = "lxml-5.2.2-cp37-cp37m-manylinux_2_28_x86_64.whl", hash = "sha256:4bc6cb140a7a0ad1f7bc37e018d0ed690b7b6520ade518285dc3171f7a117905"},
|
{file = "lxml-5.2.2-cp37-cp37m-manylinux_2_28_x86_64.whl", hash = "sha256:4bc6cb140a7a0ad1f7bc37e018d0ed690b7b6520ade518285dc3171f7a117905"},
|
||||||
|
{file = "lxml-5.2.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7ff762670cada8e05b32bf1e4dc50b140790909caa8303cfddc4d702b71ea184"},
|
||||||
{file = "lxml-5.2.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:57f0a0bbc9868e10ebe874e9f129d2917750adf008fe7b9c1598c0fbbfdde6a6"},
|
{file = "lxml-5.2.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:57f0a0bbc9868e10ebe874e9f129d2917750adf008fe7b9c1598c0fbbfdde6a6"},
|
||||||
|
{file = "lxml-5.2.2-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:a6d2092797b388342c1bc932077ad232f914351932353e2e8706851c870bca1f"},
|
||||||
{file = "lxml-5.2.2-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:60499fe961b21264e17a471ec296dcbf4365fbea611bf9e303ab69db7159ce61"},
|
{file = "lxml-5.2.2-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:60499fe961b21264e17a471ec296dcbf4365fbea611bf9e303ab69db7159ce61"},
|
||||||
{file = "lxml-5.2.2-cp37-cp37m-win32.whl", hash = "sha256:d9b342c76003c6b9336a80efcc766748a333573abf9350f4094ee46b006ec18f"},
|
{file = "lxml-5.2.2-cp37-cp37m-win32.whl", hash = "sha256:d9b342c76003c6b9336a80efcc766748a333573abf9350f4094ee46b006ec18f"},
|
||||||
{file = "lxml-5.2.2-cp37-cp37m-win_amd64.whl", hash = "sha256:b16db2770517b8799c79aa80f4053cd6f8b716f21f8aca962725a9565ce3ee40"},
|
{file = "lxml-5.2.2-cp37-cp37m-win_amd64.whl", hash = "sha256:b16db2770517b8799c79aa80f4053cd6f8b716f21f8aca962725a9565ce3ee40"},
|
||||||
|
|
@ -1935,13 +1939,13 @@ xmp = ["defusedxml"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "platformdirs"
|
name = "platformdirs"
|
||||||
version = "4.2.1"
|
version = "4.2.2"
|
||||||
description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`."
|
description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`."
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.8"
|
python-versions = ">=3.8"
|
||||||
files = [
|
files = [
|
||||||
{file = "platformdirs-4.2.1-py3-none-any.whl", hash = "sha256:17d5a1161b3fd67b390023cb2d3b026bbd40abde6fdb052dfbd3a29c3ba22ee1"},
|
{file = "platformdirs-4.2.2-py3-none-any.whl", hash = "sha256:2d7a1657e36a80ea911db832a8a6ece5ee53d8de21edd5cc5879af6530b1bfee"},
|
||||||
{file = "platformdirs-4.2.1.tar.gz", hash = "sha256:031cd18d4ec63ec53e82dceaac0417d218a6863f7745dfcc9efe7793b7039bdf"},
|
{file = "platformdirs-4.2.2.tar.gz", hash = "sha256:38b7b51f512eed9e84a22788b4bce1de17c0adb134d6becb09836e37d8654cd3"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
|
|
@ -2180,13 +2184,13 @@ cli = ["click (>=5.0)"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "python-engineio"
|
name = "python-engineio"
|
||||||
version = "4.9.0"
|
version = "4.9.1"
|
||||||
description = "Engine.IO server and client for Python"
|
description = "Engine.IO server and client for Python"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.6"
|
python-versions = ">=3.6"
|
||||||
files = [
|
files = [
|
||||||
{file = "python-engineio-4.9.0.tar.gz", hash = "sha256:e87459c15638e567711fd156e6f9c4a402668871bed79523f0ecfec744729ec7"},
|
{file = "python_engineio-4.9.1-py3-none-any.whl", hash = "sha256:f995e702b21f6b9ebde4e2000cd2ad0112ba0e5116ec8d22fe3515e76ba9dddd"},
|
||||||
{file = "python_engineio-4.9.0-py3-none-any.whl", hash = "sha256:979859bff770725b75e60353d7ae53b397e8b517d05ba76733b404a3dcca3e4c"},
|
{file = "python_engineio-4.9.1.tar.gz", hash = "sha256:7631cf5563086076611e494c643b3fa93dd3a854634b5488be0bba0ef9b99709"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
[tool.poetry]
|
[tool.poetry]
|
||||||
name = "langflow-base"
|
name = "langflow-base"
|
||||||
version = "0.0.44"
|
version = "0.0.45"
|
||||||
description = "A Python package with a built-in web application"
|
description = "A Python package with a built-in web application"
|
||||||
authors = ["Langflow <contact@langflow.org>"]
|
authors = ["Langflow <contact@langflow.org>"]
|
||||||
maintainers = [
|
maintainers = [
|
||||||
|
|
|
||||||
27416
src/frontend/package-lock.json
generated
27416
src/frontend/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
|
@ -1,141 +1,162 @@
|
||||||
|
import { saveAs } from "file-saver";
|
||||||
|
import OpenSeadragon from "openseadragon";
|
||||||
import { useEffect, useRef, useState } from "react";
|
import { useEffect, useRef, useState } from "react";
|
||||||
import ForwardedIconComponent from "../genericIconComponent";
|
|
||||||
import useFlowStore from "../../stores/flowStore";
|
|
||||||
import OpenSeadragon from 'openseadragon';
|
|
||||||
import { Separator } from "../ui/separator";
|
|
||||||
import { saveAs } from 'file-saver'
|
|
||||||
import useAlertStore from "../../stores/alertStore";
|
|
||||||
import { IMGViewErrorMSG, IMGViewErrorTitle } from "../../constants/constants";
|
import { IMGViewErrorMSG, IMGViewErrorTitle } from "../../constants/constants";
|
||||||
|
import useAlertStore from "../../stores/alertStore";
|
||||||
|
import ForwardedIconComponent from "../genericIconComponent";
|
||||||
|
import { Separator } from "../ui/separator";
|
||||||
|
|
||||||
export default function ImageViewer({image }) {
|
export default function ImageViewer({ image }) {
|
||||||
const viewerRef = useRef(null);
|
const viewerRef = useRef(null);
|
||||||
const [errorDownloading, setErrordownloading] = useState(false)
|
const [errorDownloading, setErrordownloading] = useState(false);
|
||||||
const setErrorList = useAlertStore(state => state.setErrorData);
|
const setErrorList = useAlertStore((state) => state.setErrorData);
|
||||||
const [initialMsg, setInicialMsg] = useState("Please build your flow");
|
const [initialMsg, setInicialMsg] = useState("Please build your flow");
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
try {
|
||||||
|
if (viewerRef.current) {
|
||||||
|
// Initialize OpenSeadragon viewer
|
||||||
|
const viewer = OpenSeadragon({
|
||||||
|
element: viewerRef.current,
|
||||||
|
prefixUrl:
|
||||||
|
"https://cdnjs.cloudflare.com/ajax/libs/openseadragon/2.4.2/images/", // Optional: Set the path to OpenSeadragon images
|
||||||
|
tileSources: { type: "image", url: image },
|
||||||
|
defaultZoomLevel: 1,
|
||||||
|
maxZoomPixelRatio: 4,
|
||||||
|
showNavigationControl: false,
|
||||||
|
});
|
||||||
|
const zoomInButton = document.getElementById("zoom-in-button");
|
||||||
|
const zoomOutButton = document.getElementById("zoom-out-button");
|
||||||
|
const homeButton = document.getElementById("home-button");
|
||||||
|
const fullPageButton = document.getElementById("full-page-button");
|
||||||
|
|
||||||
useEffect(() => {
|
zoomInButton!.addEventListener("click", () =>
|
||||||
try {
|
viewer.viewport.zoomBy(1.2)
|
||||||
if (viewerRef.current) {
|
);
|
||||||
// Initialize OpenSeadragon viewer
|
zoomOutButton!.addEventListener("click", () =>
|
||||||
const viewer = OpenSeadragon({
|
viewer.viewport.zoomBy(0.8)
|
||||||
element: viewerRef.current,
|
);
|
||||||
prefixUrl: 'https://cdnjs.cloudflare.com/ajax/libs/openseadragon/2.4.2/images/', // Optional: Set the path to OpenSeadragon images
|
homeButton!.addEventListener("click", () => viewer.viewport.goHome());
|
||||||
tileSources: {type: 'image', url: image},
|
fullPageButton!.addEventListener("click", () =>
|
||||||
defaultZoomLevel: 1,
|
viewer.setFullScreen(true)
|
||||||
maxZoomPixelRatio: 4,
|
);
|
||||||
showNavigationControl: false,
|
|
||||||
});
|
|
||||||
const zoomInButton = document.getElementById('zoom-in-button');
|
|
||||||
const zoomOutButton = document.getElementById('zoom-out-button');
|
|
||||||
const homeButton = document.getElementById('home-button');
|
|
||||||
const fullPageButton = document.getElementById('full-page-button');
|
|
||||||
|
|
||||||
zoomInButton!.addEventListener('click', () => viewer.viewport.zoomBy(1.2));
|
|
||||||
zoomOutButton!.addEventListener('click', () => viewer.viewport.zoomBy(0.8));
|
|
||||||
homeButton!.addEventListener('click', () => viewer.viewport.goHome());
|
|
||||||
fullPageButton!.addEventListener('click', () => viewer.setFullScreen(true));
|
|
||||||
|
|
||||||
// Optionally, you can set additional viewer options here
|
|
||||||
|
|
||||||
// Cleanup function
|
|
||||||
return () => {
|
|
||||||
viewer.destroy();
|
|
||||||
zoomInButton!.removeEventListener('click', () => viewer.viewport.zoomBy(1.2));
|
|
||||||
zoomOutButton!.removeEventListener('click', () => viewer.viewport.zoomBy(0.8));
|
|
||||||
homeButton!.removeEventListener('click', () => viewer.viewport.goHome());
|
|
||||||
fullPageButton!.removeEventListener('click', () => viewer.setFullScreen(true));
|
|
||||||
};
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Error initializing OpenSeadragon:', error);
|
|
||||||
}
|
|
||||||
}, [image]);
|
|
||||||
|
|
||||||
function download() {
|
// Optionally, you can set additional viewer options here
|
||||||
const imageUrl = image;
|
|
||||||
// Fetch the image data
|
// Cleanup function
|
||||||
fetch(imageUrl)
|
return () => {
|
||||||
.then(response => response.blob())
|
viewer.destroy();
|
||||||
.then(blob => {
|
zoomInButton!.removeEventListener("click", () =>
|
||||||
// Save the image using FileSaver.js
|
viewer.viewport.zoomBy(1.2)
|
||||||
saveAs(blob, 'image.jpg');
|
);
|
||||||
})
|
zoomOutButton!.removeEventListener("click", () =>
|
||||||
.catch(error => {
|
viewer.viewport.zoomBy(0.8)
|
||||||
setErrorList({title: "There was an error downloading your image"})
|
);
|
||||||
console.error('Error downloading image:', error)
|
homeButton!.removeEventListener("click", () =>
|
||||||
});
|
viewer.viewport.goHome()
|
||||||
|
);
|
||||||
|
fullPageButton!.removeEventListener("click", () =>
|
||||||
|
viewer.setFullScreen(true)
|
||||||
|
);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error initializing OpenSeadragon:", error);
|
||||||
|
}
|
||||||
|
}, [image]);
|
||||||
|
|
||||||
return (
|
function download() {
|
||||||
image === "" ? (
|
const imageUrl = image;
|
||||||
<div className="w-full h-full bg-muted rounded-md flex align-center justify-center flex-col gap-5 border border-border">
|
// Fetch the image data
|
||||||
<div className="flex gap-2 align-center justify-center ">
|
fetch(imageUrl)
|
||||||
<ForwardedIconComponent
|
.then((response) => response.blob())
|
||||||
name="Image"
|
.then((blob) => {
|
||||||
/>
|
// Save the image using FileSaver.js
|
||||||
{IMGViewErrorTitle}
|
saveAs(blob, "image.jpg");
|
||||||
</div>
|
})
|
||||||
<div className="flex align-center justify-center">
|
.catch((error) => {
|
||||||
<div className="langflow-chat-desc flex align-center justify-center">
|
setErrorList({ title: "There was an error downloading your image" });
|
||||||
<div className="langflow-chat-desc-span">
|
console.error("Error downloading image:", error);
|
||||||
{IMGViewErrorMSG}
|
});
|
||||||
</div>
|
}
|
||||||
</div>
|
|
||||||
</div>
|
return image === "" ? (
|
||||||
|
<div className="align-center flex h-full w-full flex-col justify-center gap-5 rounded-md border border-border bg-muted">
|
||||||
|
<div className="align-center flex justify-center gap-2 ">
|
||||||
|
<ForwardedIconComponent name="Image" />
|
||||||
|
{IMGViewErrorTitle}
|
||||||
|
</div>
|
||||||
|
<div className="align-center flex justify-center">
|
||||||
|
<div className="langflow-chat-desc align-center flex justify-center">
|
||||||
|
<div className="langflow-chat-desc-span">{IMGViewErrorMSG}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<div className="align-center my-2 mb-4 flex w-full justify-center">
|
||||||
|
<div className="shadow-round-btn-shadow hover:shadow-round-btn-shadow flex w-[50%] items-center justify-center rounded-sm border bg-muted shadow-md transition-all">
|
||||||
|
<button
|
||||||
|
id="zoom-in-button"
|
||||||
|
className="relative inline-flex w-full w-full items-center justify-center px-3 py-3 text-sm font-semibold transition-all transition-all duration-500 ease-in-out ease-in-out hover:bg-hover"
|
||||||
|
>
|
||||||
|
<ForwardedIconComponent
|
||||||
|
name="ZoomIn"
|
||||||
|
className={"h-5 w-5 text-secondary-foreground"}
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
<div>
|
||||||
|
<Separator orientation="vertical" />
|
||||||
</div>
|
</div>
|
||||||
) : (
|
<button
|
||||||
<>
|
id="zoom-out-button"
|
||||||
<div className="w-full flex align-center justify-center my-2 mb-4">
|
className="relative inline-flex w-full items-center justify-center px-3 py-3 text-sm font-semibold transition-all transition-all duration-500 ease-in-out ease-in-out hover:bg-hover"
|
||||||
<div className="shadow-round-btn-shadow hover:shadow-round-btn-shadow flex items-center justify-center rounded-sm border bg-muted shadow-md transition-all w-[50%]">
|
>
|
||||||
<button id="zoom-in-button" className="relative inline-flex w-full items-center justify-center px-3 py-3 text-sm font-semibold transition-all w-full transition-all duration-500 ease-in-out ease-in-out hover:bg-hover">
|
<ForwardedIconComponent
|
||||||
<ForwardedIconComponent
|
name="ZoomOut"
|
||||||
name="ZoomIn"
|
className={"h-5 w-5 text-secondary-foreground"}
|
||||||
className={"text-secondary-foreground w-5 h-5"}
|
/>
|
||||||
/>
|
</button>
|
||||||
</button>
|
<div>
|
||||||
<div>
|
<Separator orientation="vertical" />
|
||||||
<Separator orientation="vertical" />
|
|
||||||
</div>
|
|
||||||
<button id="zoom-out-button" className="relative inline-flex w-full items-center justify-center px-3 py-3 text-sm font-semibold transition-all transition-all duration-500 ease-in-out ease-in-out hover:bg-hover">
|
|
||||||
<ForwardedIconComponent
|
|
||||||
name="ZoomOut"
|
|
||||||
className={"text-secondary-foreground w-5 h-5"}
|
|
||||||
/>
|
|
||||||
</button>
|
|
||||||
<div>
|
|
||||||
<Separator orientation="vertical" />
|
|
||||||
</div>
|
|
||||||
<button id="home-button" className="relative inline-flex w-full items-center justify-center px-3 py-3 text-sm font-semibold transition-all transition-all duration-500 ease-in-out ease-in-out hover:bg-hover">
|
|
||||||
<ForwardedIconComponent
|
|
||||||
name="RotateCcw"
|
|
||||||
className={"text-secondary-foreground w-5 h-5"}
|
|
||||||
/>
|
|
||||||
</button>
|
|
||||||
<div>
|
|
||||||
<Separator orientation="vertical" />
|
|
||||||
</div>
|
|
||||||
<button id="full-page-button" className="relative inline-flex w-full items-center justify-center px-3 py-3 text-sm font-semibold transition-all transition-all duration-500 ease-in-out ease-in-out hover:bg-hover">
|
|
||||||
<ForwardedIconComponent
|
|
||||||
name="Maximize2"
|
|
||||||
className={"text-secondary-foreground w-5 h-5"}
|
|
||||||
/>
|
|
||||||
</button>
|
|
||||||
<div>
|
|
||||||
<Separator orientation="vertical" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<button onClick={download} className="relative inline-flex w-full items-center justify-center px-3 py-3 text-sm font-semibold transition-all transition-all duration-500 ease-in-out ease-in-out hover:bg-hover">
|
|
||||||
<ForwardedIconComponent
|
|
||||||
name="ArrowDownToLine"
|
|
||||||
className={"text-secondary-foreground w-5 h-5"}
|
|
||||||
/>
|
|
||||||
</button>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div id="canvas" ref={viewerRef} className={`w-full h-[90%] `} />
|
<button
|
||||||
</>
|
id="home-button"
|
||||||
)
|
className="relative inline-flex w-full items-center justify-center px-3 py-3 text-sm font-semibold transition-all transition-all duration-500 ease-in-out ease-in-out hover:bg-hover"
|
||||||
);
|
>
|
||||||
}
|
<ForwardedIconComponent
|
||||||
|
name="RotateCcw"
|
||||||
|
className={"h-5 w-5 text-secondary-foreground"}
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
<div>
|
||||||
|
<Separator orientation="vertical" />
|
||||||
|
</div>
|
||||||
|
<button
|
||||||
|
id="full-page-button"
|
||||||
|
className="relative inline-flex w-full items-center justify-center px-3 py-3 text-sm font-semibold transition-all transition-all duration-500 ease-in-out ease-in-out hover:bg-hover"
|
||||||
|
>
|
||||||
|
<ForwardedIconComponent
|
||||||
|
name="Maximize2"
|
||||||
|
className={"h-5 w-5 text-secondary-foreground"}
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
<div>
|
||||||
|
<Separator orientation="vertical" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button
|
||||||
|
onClick={download}
|
||||||
|
className="relative inline-flex w-full items-center justify-center px-3 py-3 text-sm font-semibold transition-all transition-all duration-500 ease-in-out ease-in-out hover:bg-hover"
|
||||||
|
>
|
||||||
|
<ForwardedIconComponent
|
||||||
|
name="ArrowDownToLine"
|
||||||
|
className={"h-5 w-5 text-secondary-foreground"}
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="canvas" ref={viewerRef} className={`h-[90%] w-full `} />
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ export default function AccordionComponent({
|
||||||
sideBar,
|
sideBar,
|
||||||
}: AccordionComponentType): JSX.Element {
|
}: AccordionComponentType): JSX.Element {
|
||||||
const [value, setValue] = useState(
|
const [value, setValue] = useState(
|
||||||
open.length === 0 ? "" : getOpenAccordion(),
|
open.length === 0 ? "" : getOpenAccordion()
|
||||||
);
|
);
|
||||||
|
|
||||||
function getOpenAccordion(): string {
|
function getOpenAccordion(): string {
|
||||||
|
|
|
||||||
|
|
@ -24,19 +24,19 @@ export default function AddNewVariableButton({ children }): JSX.Element {
|
||||||
const setErrorData = useAlertStore((state) => state.setErrorData);
|
const setErrorData = useAlertStore((state) => state.setErrorData);
|
||||||
const componentFields = useTypesStore((state) => state.ComponentFields);
|
const componentFields = useTypesStore((state) => state.ComponentFields);
|
||||||
const unavaliableFields = new Set(
|
const unavaliableFields = new Set(
|
||||||
Object.keys(useGlobalVariablesStore((state) => state.unavaliableFields)),
|
Object.keys(useGlobalVariablesStore((state) => state.unavaliableFields))
|
||||||
);
|
);
|
||||||
|
|
||||||
const availableFields = () => {
|
const availableFields = () => {
|
||||||
const fields = Array.from(componentFields).filter(
|
const fields = Array.from(componentFields).filter(
|
||||||
(field) => !unavaliableFields.has(field),
|
(field) => !unavaliableFields.has(field)
|
||||||
);
|
);
|
||||||
|
|
||||||
return sortByName(fields);
|
return sortByName(fields);
|
||||||
};
|
};
|
||||||
|
|
||||||
const addGlobalVariable = useGlobalVariablesStore(
|
const addGlobalVariable = useGlobalVariablesStore(
|
||||||
(state) => state.addGlobalVariable,
|
(state) => state.addGlobalVariable
|
||||||
);
|
);
|
||||||
|
|
||||||
function handleSaveVariable() {
|
function handleSaveVariable() {
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ import useAlertStore from "../../stores/alertStore";
|
||||||
import useFlowStore from "../../stores/flowStore";
|
import useFlowStore from "../../stores/flowStore";
|
||||||
import useFlowsManagerStore from "../../stores/flowsManagerStore";
|
import useFlowsManagerStore from "../../stores/flowsManagerStore";
|
||||||
import { useStoreStore } from "../../stores/storeStore";
|
import { useStoreStore } from "../../stores/storeStore";
|
||||||
|
import { FlowType } from "../../types/flow";
|
||||||
import { storeComponent } from "../../types/store";
|
import { storeComponent } from "../../types/store";
|
||||||
import cloneFLowWithParent, {
|
import cloneFLowWithParent, {
|
||||||
getInputsAndOutputs,
|
getInputsAndOutputs,
|
||||||
|
|
@ -22,7 +23,6 @@ import {
|
||||||
CardTitle,
|
CardTitle,
|
||||||
} from "../ui/card";
|
} from "../ui/card";
|
||||||
import Loading from "../ui/loading";
|
import Loading from "../ui/loading";
|
||||||
import { FlowType } from "../../types/flow";
|
|
||||||
|
|
||||||
export default function CollectionCardComponent({
|
export default function CollectionCardComponent({
|
||||||
data,
|
data,
|
||||||
|
|
@ -50,11 +50,11 @@ export default function CollectionCardComponent({
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
const [loadingLike, setLoadingLike] = useState(false);
|
const [loadingLike, setLoadingLike] = useState(false);
|
||||||
const [liked_by_user, setLiked_by_user] = useState(
|
const [liked_by_user, setLiked_by_user] = useState(
|
||||||
data?.liked_by_user ?? false,
|
data?.liked_by_user ?? false
|
||||||
);
|
);
|
||||||
const [likes_count, setLikes_count] = useState(data?.liked_by_count ?? 0);
|
const [likes_count, setLikes_count] = useState(data?.liked_by_count ?? 0);
|
||||||
const [downloads_count, setDownloads_count] = useState(
|
const [downloads_count, setDownloads_count] = useState(
|
||||||
data?.downloads_count ?? 0,
|
data?.downloads_count ?? 0
|
||||||
);
|
);
|
||||||
const currentFlow = useFlowsManagerStore((state) => state.currentFlow);
|
const currentFlow = useFlowsManagerStore((state) => state.currentFlow);
|
||||||
const setCurrentFlow = useFlowsManagerStore((state) => state.setCurrentFlow);
|
const setCurrentFlow = useFlowsManagerStore((state) => state.setCurrentFlow);
|
||||||
|
|
@ -65,7 +65,7 @@ export default function CollectionCardComponent({
|
||||||
const [openPlayground, setOpenPlayground] = useState(false);
|
const [openPlayground, setOpenPlayground] = useState(false);
|
||||||
const [openDelete, setOpenDelete] = useState(false);
|
const [openDelete, setOpenDelete] = useState(false);
|
||||||
const setCurrentFlowId = useFlowsManagerStore(
|
const setCurrentFlowId = useFlowsManagerStore(
|
||||||
(state) => state.setCurrentFlowId,
|
(state) => state.setCurrentFlowId
|
||||||
);
|
);
|
||||||
const [loadingPlayground, setLoadingPlayground] = useState(false);
|
const [loadingPlayground, setLoadingPlayground] = useState(false);
|
||||||
|
|
||||||
|
|
@ -185,7 +185,7 @@ export default function CollectionCardComponent({
|
||||||
className={cn(
|
className={cn(
|
||||||
"group relative flex min-h-[11rem] flex-col justify-between overflow-hidden transition-all hover:bg-muted/50 hover:shadow-md hover:dark:bg-[#ffffff10]",
|
"group relative flex min-h-[11rem] flex-col justify-between overflow-hidden transition-all hover:bg-muted/50 hover:shadow-md hover:dark:bg-[#ffffff10]",
|
||||||
disabled ? "pointer-events-none opacity-50" : "",
|
disabled ? "pointer-events-none opacity-50" : "",
|
||||||
onClick ? "cursor-pointer" : "",
|
onClick ? "cursor-pointer" : ""
|
||||||
)}
|
)}
|
||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
>
|
>
|
||||||
|
|
@ -198,7 +198,7 @@ export default function CollectionCardComponent({
|
||||||
"flex-shrink-0",
|
"flex-shrink-0",
|
||||||
data.is_component
|
data.is_component
|
||||||
? "mx-0.5 h-6 w-6 text-component-icon"
|
? "mx-0.5 h-6 w-6 text-component-icon"
|
||||||
: "h-7 w-7 flex-shrink-0 text-flow-icon",
|
: "h-7 w-7 flex-shrink-0 text-flow-icon"
|
||||||
)}
|
)}
|
||||||
name={data.is_component ? "ToyBrick" : "Group"}
|
name={data.is_component ? "ToyBrick" : "Group"}
|
||||||
/>
|
/>
|
||||||
|
|
@ -386,7 +386,7 @@ export default function CollectionCardComponent({
|
||||||
name="Trash2"
|
name="Trash2"
|
||||||
className={cn(
|
className={cn(
|
||||||
"h-5 w-5",
|
"h-5 w-5",
|
||||||
!authorized ? " text-ring" : "",
|
!authorized ? " text-ring" : ""
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
</Button>
|
</Button>
|
||||||
|
|
@ -421,7 +421,7 @@ export default function CollectionCardComponent({
|
||||||
liked_by_user
|
liked_by_user
|
||||||
? "fill-destructive stroke-destructive"
|
? "fill-destructive stroke-destructive"
|
||||||
: "",
|
: "",
|
||||||
!authorized ? " text-ring" : "",
|
!authorized ? " text-ring" : ""
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
</Button>
|
</Button>
|
||||||
|
|
@ -459,7 +459,7 @@ export default function CollectionCardComponent({
|
||||||
}
|
}
|
||||||
className={cn(
|
className={cn(
|
||||||
loading ? "h-5 w-5 animate-spin" : "h-5 w-5",
|
loading ? "h-5 w-5 animate-spin" : "h-5 w-5",
|
||||||
!authorized ? " text-ring" : "",
|
!authorized ? " text-ring" : ""
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
</Button>
|
</Button>
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@ export default function FlowToolbar(): JSX.Element {
|
||||||
"relative inline-flex h-full w-full items-center justify-center gap-[4px] bg-muted px-5 py-3 text-sm font-semibold text-foreground transition-all duration-150 ease-in-out hover:bg-background hover:bg-hover ",
|
"relative inline-flex h-full w-full items-center justify-center gap-[4px] bg-muted px-5 py-3 text-sm font-semibold text-foreground transition-all duration-150 ease-in-out hover:bg-background hover:bg-hover ",
|
||||||
!hasApiKey || !validApiKey || !hasStore
|
!hasApiKey || !validApiKey || !hasStore
|
||||||
? " button-disable text-muted-foreground "
|
? " button-disable text-muted-foreground "
|
||||||
: "",
|
: ""
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<ForwardedIconComponent
|
<ForwardedIconComponent
|
||||||
|
|
@ -59,14 +59,14 @@ export default function FlowToolbar(): JSX.Element {
|
||||||
"-m-0.5 -ml-1 h-6 w-6",
|
"-m-0.5 -ml-1 h-6 w-6",
|
||||||
!hasApiKey || !validApiKey || !hasStore
|
!hasApiKey || !validApiKey || !hasStore
|
||||||
? "extra-side-bar-save-disable"
|
? "extra-side-bar-save-disable"
|
||||||
: "",
|
: ""
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
Share
|
Share
|
||||||
</button>
|
</button>
|
||||||
</ShareModal>
|
</ShareModal>
|
||||||
),
|
),
|
||||||
[hasApiKey, validApiKey, currentFlow, hasStore],
|
[hasApiKey, validApiKey, currentFlow, hasStore]
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
@ -118,7 +118,7 @@ export default function FlowToolbar(): JSX.Element {
|
||||||
<ApiModal flow={currentFlow}>
|
<ApiModal flow={currentFlow}>
|
||||||
<div
|
<div
|
||||||
className={classNames(
|
className={classNames(
|
||||||
"relative inline-flex w-full items-center justify-center gap-1 px-5 py-3 text-sm font-semibold text-foreground transition-all duration-150 ease-in-out hover:bg-hover",
|
"relative inline-flex w-full items-center justify-center gap-1 px-5 py-3 text-sm font-semibold text-foreground transition-all duration-150 ease-in-out hover:bg-hover"
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<ForwardedIconComponent
|
<ForwardedIconComponent
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ export default function CodeAreaComponent({
|
||||||
setOpen,
|
setOpen,
|
||||||
}: CodeAreaComponentType) {
|
}: CodeAreaComponentType) {
|
||||||
const [myValue, setMyValue] = useState(
|
const [myValue, setMyValue] = useState(
|
||||||
typeof value == "string" ? value : JSON.stringify(value),
|
typeof value == "string" ? value : JSON.stringify(value)
|
||||||
);
|
);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (disabled && myValue !== "") {
|
if (disabled && myValue !== "") {
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@ import {
|
||||||
TabsTrigger,
|
TabsTrigger,
|
||||||
} from "../../components/ui/tabs";
|
} from "../../components/ui/tabs";
|
||||||
import { LANGFLOW_SUPPORTED_TYPES } from "../../constants/constants";
|
import { LANGFLOW_SUPPORTED_TYPES } from "../../constants/constants";
|
||||||
|
import ExportModal from "../../modals/exportModal";
|
||||||
import { useDarkStore } from "../../stores/darkStore";
|
import { useDarkStore } from "../../stores/darkStore";
|
||||||
import useFlowStore from "../../stores/flowStore";
|
import useFlowStore from "../../stores/flowStore";
|
||||||
import { codeTabsPropsType } from "../../types/components";
|
import { codeTabsPropsType } from "../../types/components";
|
||||||
|
|
@ -43,7 +44,6 @@ import KeypairListComponent from "../keypairListComponent";
|
||||||
import ShadTooltip from "../shadTooltipComponent";
|
import ShadTooltip from "../shadTooltipComponent";
|
||||||
import { Label } from "../ui/label";
|
import { Label } from "../ui/label";
|
||||||
import { Switch } from "../ui/switch";
|
import { Switch } from "../ui/switch";
|
||||||
import ExportModal from "../../modals/exportModal";
|
|
||||||
|
|
||||||
export default function CodeTabsComponent({
|
export default function CodeTabsComponent({
|
||||||
flow,
|
flow,
|
||||||
|
|
@ -231,7 +231,7 @@ export default function CodeTabsComponent({
|
||||||
<div className="api-modal-according-display">
|
<div className="api-modal-according-display">
|
||||||
<div
|
<div
|
||||||
className={classNames(
|
className={classNames(
|
||||||
"h-[70vh] w-full overflow-y-auto overflow-x-hidden rounded-lg bg-muted custom-scroll",
|
"h-[70vh] w-full overflow-y-auto overflow-x-hidden rounded-lg bg-muted custom-scroll"
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
{data?.map((node: any, i) => (
|
{data?.map((node: any, i) => (
|
||||||
|
|
@ -270,8 +270,8 @@ export default function CodeTabsComponent({
|
||||||
.show &&
|
.show &&
|
||||||
LANGFLOW_SUPPORTED_TYPES.has(
|
LANGFLOW_SUPPORTED_TYPES.has(
|
||||||
node.data.node.template[templateField]
|
node.data.node.template[templateField]
|
||||||
.type,
|
.type
|
||||||
),
|
)
|
||||||
)
|
)
|
||||||
.map((templateField, indx) => {
|
.map((templateField, indx) => {
|
||||||
return (
|
return (
|
||||||
|
|
@ -326,7 +326,7 @@ export default function CodeTabsComponent({
|
||||||
target,
|
target,
|
||||||
node.data.node.template[
|
node.data.node.template[
|
||||||
templateField
|
templateField
|
||||||
],
|
]
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
@ -368,7 +368,7 @@ export default function CodeTabsComponent({
|
||||||
node.data.node
|
node.data.node
|
||||||
.template[
|
.template[
|
||||||
templateField
|
templateField
|
||||||
],
|
]
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
@ -411,7 +411,7 @@ export default function CodeTabsComponent({
|
||||||
target,
|
target,
|
||||||
node.data.node.template[
|
node.data.node.template[
|
||||||
templateField
|
templateField
|
||||||
],
|
]
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
@ -444,7 +444,7 @@ export default function CodeTabsComponent({
|
||||||
e,
|
e,
|
||||||
node.data.node.template[
|
node.data.node.template[
|
||||||
templateField
|
templateField
|
||||||
],
|
]
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
size="small"
|
size="small"
|
||||||
|
|
@ -470,7 +470,7 @@ export default function CodeTabsComponent({
|
||||||
].fileTypes
|
].fileTypes
|
||||||
}
|
}
|
||||||
onFileChange={(
|
onFileChange={(
|
||||||
value: any,
|
value: any
|
||||||
) => {
|
) => {
|
||||||
node.data.node.template[
|
node.data.node.template[
|
||||||
templateField
|
templateField
|
||||||
|
|
@ -518,7 +518,7 @@ export default function CodeTabsComponent({
|
||||||
target,
|
target,
|
||||||
node.data.node.template[
|
node.data.node.template[
|
||||||
templateField
|
templateField
|
||||||
],
|
]
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
@ -553,7 +553,7 @@ export default function CodeTabsComponent({
|
||||||
target,
|
target,
|
||||||
node.data.node.template[
|
node.data.node.template[
|
||||||
templateField
|
templateField
|
||||||
],
|
]
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
value={
|
value={
|
||||||
|
|
@ -610,7 +610,7 @@ export default function CodeTabsComponent({
|
||||||
target,
|
target,
|
||||||
node.data.node.template[
|
node.data.node.template[
|
||||||
templateField
|
templateField
|
||||||
],
|
]
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
@ -651,7 +651,7 @@ export default function CodeTabsComponent({
|
||||||
target,
|
target,
|
||||||
node.data.node.template[
|
node.data.node.template[
|
||||||
templateField
|
templateField
|
||||||
],
|
]
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
@ -692,7 +692,7 @@ export default function CodeTabsComponent({
|
||||||
target,
|
target,
|
||||||
node.data.node.template[
|
node.data.node.template[
|
||||||
templateField
|
templateField
|
||||||
],
|
]
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
@ -716,7 +716,7 @@ export default function CodeTabsComponent({
|
||||||
node.data.node!
|
node.data.node!
|
||||||
.template[
|
.template[
|
||||||
templateField
|
templateField
|
||||||
].value,
|
].value
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
duplicateKey={
|
duplicateKey={
|
||||||
|
|
@ -725,15 +725,15 @@ export default function CodeTabsComponent({
|
||||||
onChange={(target) => {
|
onChange={(target) => {
|
||||||
const valueToNumbers =
|
const valueToNumbers =
|
||||||
convertValuesToNumbers(
|
convertValuesToNumbers(
|
||||||
target,
|
target
|
||||||
);
|
);
|
||||||
node.data.node!.template[
|
node.data.node!.template[
|
||||||
templateField
|
templateField
|
||||||
].value = valueToNumbers;
|
].value = valueToNumbers;
|
||||||
setErrorDuplicateKey(
|
setErrorDuplicateKey(
|
||||||
hasDuplicateKeys(
|
hasDuplicateKeys(
|
||||||
valueToNumbers,
|
valueToNumbers
|
||||||
),
|
)
|
||||||
);
|
);
|
||||||
setData((old) => {
|
setData((old) => {
|
||||||
let newInputList =
|
let newInputList =
|
||||||
|
|
@ -750,7 +750,7 @@ export default function CodeTabsComponent({
|
||||||
target,
|
target,
|
||||||
node.data.node.template[
|
node.data.node.template[
|
||||||
templateField
|
templateField
|
||||||
],
|
]
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
isList={
|
isList={
|
||||||
|
|
@ -795,7 +795,7 @@ export default function CodeTabsComponent({
|
||||||
target,
|
target,
|
||||||
node.data.node.template[
|
node.data.node.template[
|
||||||
templateField
|
templateField
|
||||||
],
|
]
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
export const convertCSVToData = (csvFile, csvSeparator: string) => {
|
export const convertCSVToData = (csvFile, csvSeparator: string) => {
|
||||||
const lines = csvFile.data.trim().split("\n");
|
const lines = csvFile.data.trim().split("\n");
|
||||||
const headers = lines[0].trim().split(csvSeparator);
|
const headers = lines[0].trim().split(csvSeparator);
|
||||||
|
|
||||||
|
|
||||||
const initialRowData: any = [];
|
const initialRowData: any = [];
|
||||||
const initialColDefs = headers.map((header) => ({
|
const initialColDefs = headers.map((header) => ({
|
||||||
|
|
|
||||||
|
|
@ -69,7 +69,7 @@ function CsvOutputComponent({
|
||||||
if (file) {
|
if (file) {
|
||||||
const { rowData: data, colDefs: columns } = convertCSVToData(
|
const { rowData: data, colDefs: columns } = convertCSVToData(
|
||||||
file,
|
file,
|
||||||
separator,
|
separator
|
||||||
);
|
);
|
||||||
setRowData(data);
|
setRowData(data);
|
||||||
setColDefs(columns);
|
setColDefs(columns);
|
||||||
|
|
@ -114,14 +114,14 @@ function CsvOutputComponent({
|
||||||
(params: any) => {
|
(params: any) => {
|
||||||
updateRowHeight(params);
|
updateRowHeight(params);
|
||||||
},
|
},
|
||||||
[updateRowHeight],
|
[updateRowHeight]
|
||||||
);
|
);
|
||||||
|
|
||||||
const onGridSizeChanged = useCallback(
|
const onGridSizeChanged = useCallback(
|
||||||
(params: any) => {
|
(params: any) => {
|
||||||
updateRowHeight(params);
|
updateRowHeight(params);
|
||||||
},
|
},
|
||||||
[updateRowHeight],
|
[updateRowHeight]
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,7 @@ export default function Dropdown({
|
||||||
? "dropdown-component-outline"
|
? "dropdown-component-outline"
|
||||||
: "dropdown-component-false-outline",
|
: "dropdown-component-false-outline",
|
||||||
"w-full justify-between font-normal",
|
"w-full justify-between font-normal",
|
||||||
editNode ? "input-edit-node" : "py-2",
|
editNode ? "input-edit-node" : "py-2"
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<span data-testid={`value-dropdown-` + id}>
|
<span data-testid={`value-dropdown-` + id}>
|
||||||
|
|
@ -107,7 +107,7 @@ export default function Dropdown({
|
||||||
name="Check"
|
name="Check"
|
||||||
className={cn(
|
className={cn(
|
||||||
"ml-auto h-4 w-4 text-primary",
|
"ml-auto h-4 w-4 text-primary",
|
||||||
value === option ? "opacity-100" : "opacity-0",
|
value === option ? "opacity-100" : "opacity-0"
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
</CommandItem>
|
</CommandItem>
|
||||||
|
|
|
||||||
|
|
@ -76,7 +76,7 @@ export default function InputComponent({
|
||||||
editNode ? " input-edit-node " : "",
|
editNode ? " input-edit-node " : "",
|
||||||
password && editNode ? "pr-8" : "",
|
password && editNode ? "pr-8" : "",
|
||||||
password && !editNode ? "pr-10" : "",
|
password && !editNode ? "pr-10" : "",
|
||||||
className!,
|
className!
|
||||||
)}
|
)}
|
||||||
placeholder={password && editNode ? "Key" : placeholder}
|
placeholder={password && editNode ? "Key" : placeholder}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
|
|
@ -104,9 +104,9 @@ export default function InputComponent({
|
||||||
(selectedOption !== "" || !onChange) && setSelectedOption
|
(selectedOption !== "" || !onChange) && setSelectedOption
|
||||||
? selectedOption
|
? selectedOption
|
||||||
: (selectedOptions?.length !== 0 || !onChange) &&
|
: (selectedOptions?.length !== 0 || !onChange) &&
|
||||||
setSelectedOptions
|
setSelectedOptions
|
||||||
? selectedOptions?.join(", ")
|
? selectedOptions?.join(", ")
|
||||||
: value
|
: value
|
||||||
}
|
}
|
||||||
autoFocus={autoFocus}
|
autoFocus={autoFocus}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
|
|
@ -134,7 +134,7 @@ export default function InputComponent({
|
||||||
? "pr-8"
|
? "pr-8"
|
||||||
: "",
|
: "",
|
||||||
|
|
||||||
className!,
|
className!
|
||||||
)}
|
)}
|
||||||
placeholder={password && editNode ? "Key" : placeholder}
|
placeholder={password && editNode ? "Key" : placeholder}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
|
|
@ -195,15 +195,15 @@ export default function InputComponent({
|
||||||
setSelectedOption(
|
setSelectedOption(
|
||||||
currentValue === selectedOption
|
currentValue === selectedOption
|
||||||
? ""
|
? ""
|
||||||
: currentValue,
|
: currentValue
|
||||||
);
|
);
|
||||||
setSelectedOptions &&
|
setSelectedOptions &&
|
||||||
setSelectedOptions(
|
setSelectedOptions(
|
||||||
selectedOptions?.includes(currentValue)
|
selectedOptions?.includes(currentValue)
|
||||||
? selectedOptions.filter(
|
? selectedOptions.filter(
|
||||||
(item) => item !== currentValue,
|
(item) => item !== currentValue
|
||||||
)
|
)
|
||||||
: [...selectedOptions, currentValue],
|
: [...selectedOptions, currentValue]
|
||||||
);
|
);
|
||||||
!setSelectedOptions && setShowOptions(false);
|
!setSelectedOptions && setShowOptions(false);
|
||||||
}}
|
}}
|
||||||
|
|
@ -216,7 +216,7 @@ export default function InputComponent({
|
||||||
selectedOption === option ||
|
selectedOption === option ||
|
||||||
selectedOptions?.includes(option)
|
selectedOptions?.includes(option)
|
||||||
? "opacity-100"
|
? "opacity-100"
|
||||||
: "opacity-0",
|
: "opacity-0"
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<div className="absolute opacity-100 transition-all group-hover:opacity-0">
|
<div className="absolute opacity-100 transition-all group-hover:opacity-0">
|
||||||
|
|
@ -255,7 +255,7 @@ export default function InputComponent({
|
||||||
((selectedOptions?.length !== 0 || !onChange) &&
|
((selectedOptions?.length !== 0 || !onChange) &&
|
||||||
setSelectedOptions)
|
setSelectedOptions)
|
||||||
? ""
|
? ""
|
||||||
: "hidden",
|
: "hidden"
|
||||||
)}
|
)}
|
||||||
onClick={
|
onClick={
|
||||||
((selectedOption !== "" || !onChange) && setSelectedOption) ||
|
((selectedOption !== "" || !onChange) && setSelectedOption) ||
|
||||||
|
|
@ -276,7 +276,7 @@ export default function InputComponent({
|
||||||
<span
|
<span
|
||||||
className={cn(
|
className={cn(
|
||||||
password && selectedOption === "" ? "right-8" : "right-0",
|
password && selectedOption === "" ? "right-8" : "right-0",
|
||||||
"absolute inset-y-0 flex items-center pr-2.5",
|
"absolute inset-y-0 flex items-center pr-2.5"
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
|
|
@ -287,7 +287,7 @@ export default function InputComponent({
|
||||||
selectedOption !== ""
|
selectedOption !== ""
|
||||||
? "text-medium-indigo"
|
? "text-medium-indigo"
|
||||||
: "text-muted-foreground",
|
: "text-muted-foreground",
|
||||||
"hover:text-accent-foreground",
|
"hover:text-accent-foreground"
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<ForwardedIconComponent
|
<ForwardedIconComponent
|
||||||
|
|
@ -307,7 +307,7 @@ export default function InputComponent({
|
||||||
"mb-px",
|
"mb-px",
|
||||||
editNode
|
editNode
|
||||||
? "input-component-true-button"
|
? "input-component-true-button"
|
||||||
: "input-component-false-button",
|
: "input-component-false-button"
|
||||||
)}
|
)}
|
||||||
onClick={(event) => {
|
onClick={(event) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
@ -324,7 +324,7 @@ export default function InputComponent({
|
||||||
className={classNames(
|
className={classNames(
|
||||||
editNode
|
editNode
|
||||||
? "input-component-true-svg"
|
? "input-component-true-svg"
|
||||||
: "input-component-false-svg",
|
: "input-component-false-svg"
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<path
|
<path
|
||||||
|
|
@ -343,7 +343,7 @@ export default function InputComponent({
|
||||||
className={classNames(
|
className={classNames(
|
||||||
editNode
|
editNode
|
||||||
? "input-component-true-svg"
|
? "input-component-true-svg"
|
||||||
: "input-component-false-svg",
|
: "input-component-false-svg"
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<path
|
<path
|
||||||
|
|
|
||||||
|
|
@ -106,8 +106,8 @@ export default function InputFileComponent({
|
||||||
editNode
|
editNode
|
||||||
? "input-edit-node input-dialog text-muted-foreground"
|
? "input-edit-node input-dialog text-muted-foreground"
|
||||||
: disabled
|
: disabled
|
||||||
? "input-disable input-dialog primary-input"
|
? "input-disable input-dialog primary-input"
|
||||||
: "input-dialog primary-input text-muted-foreground"
|
: "input-dialog primary-input text-muted-foreground"
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
{myValue !== "" ? myValue : "No file"}
|
{myValue !== "" ? myValue : "No file"}
|
||||||
|
|
|
||||||
|
|
@ -19,15 +19,15 @@ export default function InputGlobalComponent({
|
||||||
editNode = false,
|
editNode = false,
|
||||||
}: InputGlobalComponentType): JSX.Element {
|
}: InputGlobalComponentType): JSX.Element {
|
||||||
const globalVariablesEntries = useGlobalVariablesStore(
|
const globalVariablesEntries = useGlobalVariablesStore(
|
||||||
(state) => state.globalVariablesEntries,
|
(state) => state.globalVariablesEntries
|
||||||
);
|
);
|
||||||
|
|
||||||
const getVariableId = useGlobalVariablesStore((state) => state.getVariableId);
|
const getVariableId = useGlobalVariablesStore((state) => state.getVariableId);
|
||||||
const unavaliableFields = useGlobalVariablesStore(
|
const unavaliableFields = useGlobalVariablesStore(
|
||||||
(state) => state.unavaliableFields,
|
(state) => state.unavaliableFields
|
||||||
);
|
);
|
||||||
const removeGlobalVariable = useGlobalVariablesStore(
|
const removeGlobalVariable = useGlobalVariablesStore(
|
||||||
(state) => state.removeGlobalVariable,
|
(state) => state.removeGlobalVariable
|
||||||
);
|
);
|
||||||
const setErrorData = useAlertStore((state) => state.setErrorData);
|
const setErrorData = useAlertStore((state) => state.setErrorData);
|
||||||
|
|
||||||
|
|
@ -129,7 +129,7 @@ export default function InputGlobalComponent({
|
||||||
<ForwardedIconComponent
|
<ForwardedIconComponent
|
||||||
name="Trash2"
|
name="Trash2"
|
||||||
className={cn(
|
className={cn(
|
||||||
"h-4 w-4 text-primary opacity-0 hover:text-status-red group-hover:opacity-100",
|
"h-4 w-4 text-primary opacity-0 hover:text-status-red group-hover:opacity-100"
|
||||||
)}
|
)}
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,19 @@
|
||||||
import { CHAT_FIRST_INITIAL_TEXT, CHAT_SECOND_INITIAL_TEXT, PDFCheckFlow, PDFLoadErrorTitle } from "../../../constants/constants";
|
import { PDFCheckFlow, PDFLoadErrorTitle } from "../../../constants/constants";
|
||||||
import IconComponent from "../../genericIconComponent";
|
import IconComponent from "../../genericIconComponent";
|
||||||
|
|
||||||
|
|
||||||
export default function Error(): JSX.Element {
|
export default function Error(): JSX.Element {
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col items-center justify-center h-full w-full bg-muted">
|
<div className="flex h-full w-full flex-col items-center justify-center bg-muted">
|
||||||
<div className="chat-alert-box">
|
<div className="chat-alert-box">
|
||||||
<span className="flex gap-2">
|
<span className="flex gap-2">
|
||||||
<IconComponent name="FileX2" />
|
<IconComponent name="FileX2" />
|
||||||
<span className="langflow-chat-span">{PDFLoadErrorTitle}</span>
|
<span className="langflow-chat-span">{PDFLoadErrorTitle}</span>
|
||||||
</span>
|
</span>
|
||||||
<br />
|
<br />
|
||||||
<div className="langflow-chat-desc">
|
<div className="langflow-chat-desc">
|
||||||
<span className="langflow-chat-desc-span">
|
<span className="langflow-chat-desc-span">{PDFCheckFlow} </span>
|
||||||
{PDFCheckFlow}{" "}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
);
|
</div>
|
||||||
}
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ const TableComponent = forwardRef<
|
||||||
<div
|
<div
|
||||||
className={cn(
|
className={cn(
|
||||||
dark ? "ag-theme-quartz-dark" : "ag-theme-quartz",
|
dark ? "ag-theme-quartz-dark" : "ag-theme-quartz",
|
||||||
"ag-theme-shadcn flex h-full flex-col",
|
"ag-theme-shadcn flex h-full flex-col"
|
||||||
)} // applying the grid theme
|
)} // applying the grid theme
|
||||||
>
|
>
|
||||||
<AgGridReact ref={ref} {...props} />
|
<AgGridReact ref={ref} {...props} />
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { AxiosRequestConfig, AxiosResponse } from "axios";
|
import { AxiosRequestConfig, AxiosResponse } from "axios";
|
||||||
import { Edge, ReactFlowJsonObject,Node } from "reactflow";
|
import { Edge, Node, ReactFlowJsonObject } from "reactflow";
|
||||||
import { BASE_URL_API } from "../../constants/constants";
|
import { BASE_URL_API } from "../../constants/constants";
|
||||||
import { api } from "../../controllers/API/api";
|
import { api } from "../../controllers/API/api";
|
||||||
import {
|
import {
|
||||||
|
|
@ -929,25 +929,29 @@ export async function getVerticesOrder(
|
||||||
flowId: string,
|
flowId: string,
|
||||||
startNodeId?: string | null,
|
startNodeId?: string | null,
|
||||||
stopNodeId?: string | null,
|
stopNodeId?: string | null,
|
||||||
nodes?:Node[],
|
nodes?: Node[],
|
||||||
Edges?:Edge[]
|
Edges?: Edge[]
|
||||||
): Promise<AxiosResponse<VerticesOrderTypeAPI>> {
|
): Promise<AxiosResponse<VerticesOrderTypeAPI>> {
|
||||||
// nodeId is optional and is a query parameter
|
// nodeId is optional and is a query parameter
|
||||||
// if nodeId is not provided, the API will return all vertices
|
// if nodeId is not provided, the API will return all vertices
|
||||||
const config:AxiosRequestConfig<any> = {};
|
const config: AxiosRequestConfig<any> = {};
|
||||||
if (stopNodeId) {
|
if (stopNodeId) {
|
||||||
config["params"] = { stop_component_id: stopNodeId };
|
config["params"] = { stop_component_id: stopNodeId };
|
||||||
} else if (startNodeId) {
|
} else if (startNodeId) {
|
||||||
config["params"] = { start_component_id: startNodeId };
|
config["params"] = { start_component_id: startNodeId };
|
||||||
}
|
}
|
||||||
const data = {
|
const data = {
|
||||||
data:{}
|
data: {},
|
||||||
|
};
|
||||||
|
if (nodes && Edges) {
|
||||||
|
data["data"]["nodes"] = nodes;
|
||||||
|
data["data"]["edges"] = Edges;
|
||||||
}
|
}
|
||||||
if(nodes && Edges){
|
return await api.post(
|
||||||
data["data"]["nodes"] = nodes
|
`${BASE_URL_API}build/${flowId}/vertices`,
|
||||||
data["data"]["edges"] = Edges
|
data,
|
||||||
}
|
config
|
||||||
return await api.post(`${BASE_URL_API}build/${flowId}/vertices`,data, config);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function postBuildVertex(
|
export async function postBuildVertex(
|
||||||
|
|
|
||||||
|
|
@ -86,7 +86,7 @@ export default function ParameterComponent({
|
||||||
let disabled =
|
let disabled =
|
||||||
edges.some(
|
edges.some(
|
||||||
(edge) =>
|
(edge) =>
|
||||||
edge.targetHandle === scapedJSONStringfy(proxy ? { ...id, proxy } : id),
|
edge.targetHandle === scapedJSONStringfy(proxy ? { ...id, proxy } : id)
|
||||||
) ?? false;
|
) ?? false;
|
||||||
|
|
||||||
const myData = useTypesStore((state) => state.data);
|
const myData = useTypesStore((state) => state.data);
|
||||||
|
|
@ -159,7 +159,7 @@ export default function ParameterComponent({
|
||||||
|
|
||||||
const handleOnNewValue = async (
|
const handleOnNewValue = async (
|
||||||
newValue: string | string[] | boolean | Object[],
|
newValue: string | string[] | boolean | Object[],
|
||||||
skipSnapshot: boolean | undefined = false,
|
skipSnapshot: boolean | undefined = false
|
||||||
): Promise<void> => {
|
): Promise<void> => {
|
||||||
const nodeTemplate = data.node!.template[name];
|
const nodeTemplate = data.node!.template[name];
|
||||||
const currentValue = nodeTemplate.value;
|
const currentValue = nodeTemplate.value;
|
||||||
|
|
@ -280,7 +280,7 @@ export default function ParameterComponent({
|
||||||
<span
|
<span
|
||||||
key={index}
|
key={index}
|
||||||
className={classNames(
|
className={classNames(
|
||||||
index > 0 ? "mt-2 flex items-center" : "mt-3 flex items-center",
|
index > 0 ? "mt-2 flex items-center" : "mt-3 flex items-center"
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
|
|
@ -396,7 +396,7 @@ export default function ParameterComponent({
|
||||||
className={classNames(
|
className={classNames(
|
||||||
left ? "my-12 -ml-0.5 " : " my-12 -mr-0.5 ",
|
left ? "my-12 -ml-0.5 " : " my-12 -mr-0.5 ",
|
||||||
"h-3 w-3 rounded-full border-2 bg-background",
|
"h-3 w-3 rounded-full border-2 bg-background",
|
||||||
!showNode ? "mt-0" : "",
|
!showNode ? "mt-0" : ""
|
||||||
)}
|
)}
|
||||||
style={{
|
style={{
|
||||||
borderColor: color ?? nodeColors.unknown,
|
borderColor: color ?? nodeColors.unknown,
|
||||||
|
|
@ -492,7 +492,7 @@ export default function ParameterComponent({
|
||||||
}
|
}
|
||||||
className={classNames(
|
className={classNames(
|
||||||
left ? "-ml-0.5 " : "-mr-0.5 ",
|
left ? "-ml-0.5 " : "-mr-0.5 ",
|
||||||
"h-3 w-3 rounded-full border-2 bg-background",
|
"h-3 w-3 rounded-full border-2 bg-background"
|
||||||
)}
|
)}
|
||||||
style={{
|
style={{
|
||||||
borderColor: color ?? nodeColors.unknown,
|
borderColor: color ?? nodeColors.unknown,
|
||||||
|
|
|
||||||
|
|
@ -324,7 +324,7 @@ dark:prose-invert"
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<span
|
<span
|
||||||
className="prose text-primary word-break-break-word dark:prose-invert"
|
className="prose text-primary word-break-break-word dark:prose-invert"
|
||||||
data-testid={
|
data-testid={
|
||||||
"chat-message-" + chat.sender_name + "-" + chatMessage
|
"chat-message-" + chat.sender_name + "-" + chatMessage
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,25 +34,25 @@ export default function IOModal({
|
||||||
}: IOModalPropsType): JSX.Element {
|
}: IOModalPropsType): JSX.Element {
|
||||||
const allNodes = useFlowStore((state) => state.nodes);
|
const allNodes = useFlowStore((state) => state.nodes);
|
||||||
const inputs = useFlowStore((state) => state.inputs).filter(
|
const inputs = useFlowStore((state) => state.inputs).filter(
|
||||||
(input) => input.type !== "ChatInput",
|
(input) => input.type !== "ChatInput"
|
||||||
);
|
);
|
||||||
const chatInput = useFlowStore((state) => state.inputs).find(
|
const chatInput = useFlowStore((state) => state.inputs).find(
|
||||||
(input) => input.type === "ChatInput",
|
(input) => input.type === "ChatInput"
|
||||||
);
|
);
|
||||||
const outputs = useFlowStore((state) => state.outputs).filter(
|
const outputs = useFlowStore((state) => state.outputs).filter(
|
||||||
(output) => output.type !== "ChatOutput",
|
(output) => output.type !== "ChatOutput"
|
||||||
);
|
);
|
||||||
const chatOutput = useFlowStore((state) => state.outputs).find(
|
const chatOutput = useFlowStore((state) => state.outputs).find(
|
||||||
(output) => output.type === "ChatOutput",
|
(output) => output.type === "ChatOutput"
|
||||||
);
|
);
|
||||||
const nodes = useFlowStore((state) => state.nodes).filter(
|
const nodes = useFlowStore((state) => state.nodes).filter(
|
||||||
(node) =>
|
(node) =>
|
||||||
inputs.some((input) => input.id === node.id) ||
|
inputs.some((input) => input.id === node.id) ||
|
||||||
outputs.some((output) => output.id === node.id),
|
outputs.some((output) => output.id === node.id)
|
||||||
);
|
);
|
||||||
const haveChat = chatInput || chatOutput;
|
const haveChat = chatInput || chatOutput;
|
||||||
const [selectedTab, setSelectedTab] = useState(
|
const [selectedTab, setSelectedTab] = useState(
|
||||||
inputs.length > 0 ? 1 : outputs.length > 0 ? 2 : 0,
|
inputs.length > 0 ? 1 : outputs.length > 0 ? 2 : 0
|
||||||
);
|
);
|
||||||
|
|
||||||
function startView() {
|
function startView() {
|
||||||
|
|
@ -140,7 +140,7 @@ export default function IOModal({
|
||||||
{selectedTab !== 0 && (
|
{selectedTab !== 0 && (
|
||||||
<div
|
<div
|
||||||
className={cn(
|
className={cn(
|
||||||
"mr-6 flex h-full w-2/6 flex-shrink-0 flex-col justify-start transition-all duration-300",
|
"mr-6 flex h-full w-2/6 flex-shrink-0 flex-col justify-start transition-all duration-300"
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<Tabs
|
<Tabs
|
||||||
|
|
@ -173,11 +173,11 @@ export default function IOModal({
|
||||||
</div>
|
</div>
|
||||||
{nodes
|
{nodes
|
||||||
.filter((node) =>
|
.filter((node) =>
|
||||||
inputs.some((input) => input.id === node.id),
|
inputs.some((input) => input.id === node.id)
|
||||||
)
|
)
|
||||||
.map((node, index) => {
|
.map((node, index) => {
|
||||||
const input = inputs.find(
|
const input = inputs.find(
|
||||||
(input) => input.id === node.id,
|
(input) => input.id === node.id
|
||||||
)!;
|
)!;
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
|
|
@ -241,11 +241,11 @@ export default function IOModal({
|
||||||
</div>
|
</div>
|
||||||
{nodes
|
{nodes
|
||||||
.filter((node) =>
|
.filter((node) =>
|
||||||
outputs.some((output) => output.id === node.id),
|
outputs.some((output) => output.id === node.id)
|
||||||
)
|
)
|
||||||
.map((node, index) => {
|
.map((node, index) => {
|
||||||
const output = outputs.find(
|
const output = outputs.find(
|
||||||
(output) => output.id === node.id,
|
(output) => output.id === node.id
|
||||||
)!;
|
)!;
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
|
|
@ -308,7 +308,7 @@ export default function IOModal({
|
||||||
<div
|
<div
|
||||||
className={cn(
|
className={cn(
|
||||||
"flex h-full w-full flex-col items-start gap-4 pt-4",
|
"flex h-full w-full flex-col items-start gap-4 pt-4",
|
||||||
!selectedViewField ? "hidden" : "",
|
!selectedViewField ? "hidden" : ""
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<div className="font-xl flex items-center justify-center gap-3 font-semibold">
|
<div className="font-xl flex items-center justify-center gap-3 font-semibold">
|
||||||
|
|
@ -327,7 +327,7 @@ export default function IOModal({
|
||||||
</div>
|
</div>
|
||||||
<div className="h-full w-full">
|
<div className="h-full w-full">
|
||||||
{inputs.some(
|
{inputs.some(
|
||||||
(input) => input.id === selectedViewField.id,
|
(input) => input.id === selectedViewField.id
|
||||||
) ? (
|
) ? (
|
||||||
<IOFieldView
|
<IOFieldView
|
||||||
type={InputOutput.INPUT}
|
type={InputOutput.INPUT}
|
||||||
|
|
@ -349,7 +349,7 @@ export default function IOModal({
|
||||||
<div
|
<div
|
||||||
className={cn(
|
className={cn(
|
||||||
"flex h-full w-full",
|
"flex h-full w-full",
|
||||||
selectedViewField ? "hidden" : "",
|
selectedViewField ? "hidden" : ""
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
{haveChat ? (
|
{haveChat ? (
|
||||||
|
|
@ -384,7 +384,7 @@ export default function IOModal({
|
||||||
"h-4 w-4",
|
"h-4 w-4",
|
||||||
isBuilding
|
isBuilding
|
||||||
? "animate-spin"
|
? "animate-spin"
|
||||||
: "fill-current text-medium-indigo",
|
: "fill-current text-medium-indigo"
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
Run Flow
|
Run Flow
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ export const checkCanBuildTweakObject = (element, templateField) => {
|
||||||
templateField.charAt(0) !== "_" &&
|
templateField.charAt(0) !== "_" &&
|
||||||
element.data.node.template[templateField].show &&
|
element.data.node.template[templateField].show &&
|
||||||
LANGFLOW_SUPPORTED_TYPES.has(
|
LANGFLOW_SUPPORTED_TYPES.has(
|
||||||
element.data.node.template[templateField].type,
|
element.data.node.template[templateField].type
|
||||||
) &&
|
) &&
|
||||||
templateField !== "code"
|
templateField !== "code"
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ import { convertArrayToObj } from "../../../utils/reactflowUtils";
|
||||||
|
|
||||||
export const getChangesType = (
|
export const getChangesType = (
|
||||||
changes: string | string[] | boolean | number | Object[] | Object,
|
changes: string | string[] | boolean | number | Object[] | Object,
|
||||||
template: TemplateVariableType,
|
template: TemplateVariableType
|
||||||
) => {
|
) => {
|
||||||
if (typeof changes === "string" && template.type === "float") {
|
if (typeof changes === "string" && template.type === "float") {
|
||||||
changes = parseFloat(changes);
|
changes = parseFloat(changes);
|
||||||
|
|
|
||||||
|
|
@ -13,8 +13,8 @@ export const getNodesWithDefaultValue = (flow) => {
|
||||||
templateField.charAt(0) !== "_" &&
|
templateField.charAt(0) !== "_" &&
|
||||||
node.data.node.template[templateField].show &&
|
node.data.node.template[templateField].show &&
|
||||||
LANGFLOW_SUPPORTED_TYPES.has(
|
LANGFLOW_SUPPORTED_TYPES.has(
|
||||||
node.data.node.template[templateField].type,
|
node.data.node.template[templateField].type
|
||||||
),
|
)
|
||||||
)
|
)
|
||||||
.map((n, i) => {
|
.map((n, i) => {
|
||||||
arrNodesWithValues.push(node["id"]);
|
arrNodesWithValues.push(node["id"]);
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ export const getValue = (
|
||||||
value: string,
|
value: string,
|
||||||
node: NodeType,
|
node: NodeType,
|
||||||
template: TemplateVariableType,
|
template: TemplateVariableType,
|
||||||
tweak: Object[],
|
tweak: Object[]
|
||||||
) => {
|
) => {
|
||||||
let returnValue = value ?? "";
|
let returnValue = value ?? "";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,7 @@ interface BaseModalProps {
|
||||||
React.ReactElement<ContentProps>,
|
React.ReactElement<ContentProps>,
|
||||||
React.ReactElement<HeaderProps>,
|
React.ReactElement<HeaderProps>,
|
||||||
React.ReactElement<TriggerProps>?,
|
React.ReactElement<TriggerProps>?,
|
||||||
React.ReactElement<FooterProps>?,
|
React.ReactElement<FooterProps>?
|
||||||
];
|
];
|
||||||
open?: boolean;
|
open?: boolean;
|
||||||
setOpen?: (open: boolean) => void;
|
setOpen?: (open: boolean) => void;
|
||||||
|
|
@ -95,16 +95,16 @@ function BaseModal({
|
||||||
type = "dialog",
|
type = "dialog",
|
||||||
}: BaseModalProps) {
|
}: BaseModalProps) {
|
||||||
const headerChild = React.Children.toArray(children).find(
|
const headerChild = React.Children.toArray(children).find(
|
||||||
(child) => (child as React.ReactElement).type === Header,
|
(child) => (child as React.ReactElement).type === Header
|
||||||
);
|
);
|
||||||
const triggerChild = React.Children.toArray(children).find(
|
const triggerChild = React.Children.toArray(children).find(
|
||||||
(child) => (child as React.ReactElement).type === Trigger,
|
(child) => (child as React.ReactElement).type === Trigger
|
||||||
);
|
);
|
||||||
const ContentChild = React.Children.toArray(children).find(
|
const ContentChild = React.Children.toArray(children).find(
|
||||||
(child) => (child as React.ReactElement).type === Content,
|
(child) => (child as React.ReactElement).type === Content
|
||||||
);
|
);
|
||||||
const ContentFooter = React.Children.toArray(children).find(
|
const ContentFooter = React.Children.toArray(children).find(
|
||||||
(child) => (child as React.ReactElement).type === Footer,
|
(child) => (child as React.ReactElement).type === Footer
|
||||||
);
|
);
|
||||||
|
|
||||||
let minWidth: string;
|
let minWidth: string;
|
||||||
|
|
|
||||||
|
|
@ -51,19 +51,19 @@ export default function Page({
|
||||||
}): JSX.Element {
|
}): JSX.Element {
|
||||||
const uploadFlow = useFlowsManagerStore((state) => state.uploadFlow);
|
const uploadFlow = useFlowsManagerStore((state) => state.uploadFlow);
|
||||||
const autoSaveCurrentFlow = useFlowsManagerStore(
|
const autoSaveCurrentFlow = useFlowsManagerStore(
|
||||||
(state) => state.autoSaveCurrentFlow,
|
(state) => state.autoSaveCurrentFlow
|
||||||
);
|
);
|
||||||
const types = useTypesStore((state) => state.types);
|
const types = useTypesStore((state) => state.types);
|
||||||
const templates = useTypesStore((state) => state.templates);
|
const templates = useTypesStore((state) => state.templates);
|
||||||
const setFilterEdge = useFlowStore((state) => state.setFilterEdge);
|
const setFilterEdge = useFlowStore((state) => state.setFilterEdge);
|
||||||
const reactFlowWrapper = useRef<HTMLDivElement>(null);
|
const reactFlowWrapper = useRef<HTMLDivElement>(null);
|
||||||
const [showCanvas, setSHowCanvas] = useState(
|
const [showCanvas, setSHowCanvas] = useState(
|
||||||
Object.keys(templates).length > 0 && Object.keys(types).length > 0,
|
Object.keys(templates).length > 0 && Object.keys(types).length > 0
|
||||||
);
|
);
|
||||||
|
|
||||||
const reactFlowInstance = useFlowStore((state) => state.reactFlowInstance);
|
const reactFlowInstance = useFlowStore((state) => state.reactFlowInstance);
|
||||||
const setReactFlowInstance = useFlowStore(
|
const setReactFlowInstance = useFlowStore(
|
||||||
(state) => state.setReactFlowInstance,
|
(state) => state.setReactFlowInstance
|
||||||
);
|
);
|
||||||
const nodes = useFlowStore((state) => state.nodes);
|
const nodes = useFlowStore((state) => state.nodes);
|
||||||
const edges = useFlowStore((state) => state.edges);
|
const edges = useFlowStore((state) => state.edges);
|
||||||
|
|
@ -80,10 +80,10 @@ export default function Page({
|
||||||
const paste = useFlowStore((state) => state.paste);
|
const paste = useFlowStore((state) => state.paste);
|
||||||
const resetFlow = useFlowStore((state) => state.resetFlow);
|
const resetFlow = useFlowStore((state) => state.resetFlow);
|
||||||
const lastCopiedSelection = useFlowStore(
|
const lastCopiedSelection = useFlowStore(
|
||||||
(state) => state.lastCopiedSelection,
|
(state) => state.lastCopiedSelection
|
||||||
);
|
);
|
||||||
const setLastCopiedSelection = useFlowStore(
|
const setLastCopiedSelection = useFlowStore(
|
||||||
(state) => state.setLastCopiedSelection,
|
(state) => state.setLastCopiedSelection
|
||||||
);
|
);
|
||||||
const onConnect = useFlowStore((state) => state.onConnect);
|
const onConnect = useFlowStore((state) => state.onConnect);
|
||||||
const currentFlowId = useFlowsManagerStore((state) => state.currentFlowId);
|
const currentFlowId = useFlowsManagerStore((state) => state.currentFlowId);
|
||||||
|
|
@ -106,7 +106,7 @@ export default function Page({
|
||||||
clonedSelection!,
|
clonedSelection!,
|
||||||
clonedNodes,
|
clonedNodes,
|
||||||
clonedEdges,
|
clonedEdges,
|
||||||
getRandomName(),
|
getRandomName()
|
||||||
);
|
);
|
||||||
const newGroupNode = generateNodeFromFlow(newFlow, getNodeId);
|
const newGroupNode = generateNodeFromFlow(newFlow, getNodeId);
|
||||||
const newEdges = reconnectEdges(newGroupNode, removedEdges);
|
const newEdges = reconnectEdges(newGroupNode, removedEdges);
|
||||||
|
|
@ -114,8 +114,8 @@ export default function Page({
|
||||||
...clonedNodes.filter(
|
...clonedNodes.filter(
|
||||||
(oldNodes) =>
|
(oldNodes) =>
|
||||||
!clonedSelection?.nodes.some(
|
!clonedSelection?.nodes.some(
|
||||||
(selectionNode) => selectionNode.id === oldNodes.id,
|
(selectionNode) => selectionNode.id === oldNodes.id
|
||||||
),
|
)
|
||||||
),
|
),
|
||||||
newGroupNode,
|
newGroupNode,
|
||||||
]);
|
]);
|
||||||
|
|
@ -125,8 +125,8 @@ export default function Page({
|
||||||
!clonedSelection!.nodes.some(
|
!clonedSelection!.nodes.some(
|
||||||
(selectionNode) =>
|
(selectionNode) =>
|
||||||
selectionNode.id === oldEdge.target ||
|
selectionNode.id === oldEdge.target ||
|
||||||
selectionNode.id === oldEdge.source,
|
selectionNode.id === oldEdge.source
|
||||||
),
|
)
|
||||||
),
|
),
|
||||||
...newEdges,
|
...newEdges,
|
||||||
]);
|
]);
|
||||||
|
|
@ -179,7 +179,7 @@ export default function Page({
|
||||||
{
|
{
|
||||||
x: position.current.x,
|
x: position.current.x,
|
||||||
y: position.current.y,
|
y: position.current.y,
|
||||||
},
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (!isWrappedWithClass(event, "noundo")) {
|
if (!isWrappedWithClass(event, "noundo")) {
|
||||||
|
|
@ -275,7 +275,7 @@ export default function Page({
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setSHowCanvas(
|
setSHowCanvas(
|
||||||
Object.keys(templates).length > 0 && Object.keys(types).length > 0,
|
Object.keys(templates).length > 0 && Object.keys(types).length > 0
|
||||||
);
|
);
|
||||||
}, [templates, types]);
|
}, [templates, types]);
|
||||||
|
|
||||||
|
|
@ -284,7 +284,7 @@ export default function Page({
|
||||||
takeSnapshot();
|
takeSnapshot();
|
||||||
onConnect(params);
|
onConnect(params);
|
||||||
},
|
},
|
||||||
[takeSnapshot, onConnect],
|
[takeSnapshot, onConnect]
|
||||||
);
|
);
|
||||||
|
|
||||||
const onNodeDragStart: NodeDragHandler = useCallback(() => {
|
const onNodeDragStart: NodeDragHandler = useCallback(() => {
|
||||||
|
|
@ -325,7 +325,7 @@ export default function Page({
|
||||||
|
|
||||||
// Extract the data from the drag event and parse it as a JSON object
|
// Extract the data from the drag event and parse it as a JSON object
|
||||||
const data: { type: string; node?: APIClassType } = JSON.parse(
|
const data: { type: string; node?: APIClassType } = JSON.parse(
|
||||||
event.dataTransfer.getData("nodedata"),
|
event.dataTransfer.getData("nodedata")
|
||||||
);
|
);
|
||||||
|
|
||||||
const newId = getNodeId(data.type);
|
const newId = getNodeId(data.type);
|
||||||
|
|
@ -341,7 +341,7 @@ export default function Page({
|
||||||
};
|
};
|
||||||
paste(
|
paste(
|
||||||
{ nodes: [newNode], edges: [] },
|
{ nodes: [newNode], edges: [] },
|
||||||
{ x: event.clientX, y: event.clientY },
|
{ x: event.clientX, y: event.clientY }
|
||||||
);
|
);
|
||||||
} else if (event.dataTransfer.types.some((types) => types === "Files")) {
|
} else if (event.dataTransfer.types.some((types) => types === "Files")) {
|
||||||
takeSnapshot();
|
takeSnapshot();
|
||||||
|
|
@ -370,7 +370,7 @@ export default function Page({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// Specify dependencies for useCallback
|
// Specify dependencies for useCallback
|
||||||
[getNodeId, setNodes, takeSnapshot, paste],
|
[getNodeId, setNodes, takeSnapshot, paste]
|
||||||
);
|
);
|
||||||
|
|
||||||
const onEdgeUpdateStart = useCallback(() => {
|
const onEdgeUpdateStart = useCallback(() => {
|
||||||
|
|
@ -386,7 +386,7 @@ export default function Page({
|
||||||
setEdges((els) => updateEdge(oldEdge, newConnection, els));
|
setEdges((els) => updateEdge(oldEdge, newConnection, els));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[setEdges],
|
[setEdges]
|
||||||
);
|
);
|
||||||
|
|
||||||
const onEdgeUpdateEnd = useCallback((_, edge: Edge): void => {
|
const onEdgeUpdateEnd = useCallback((_, edge: Edge): void => {
|
||||||
|
|
@ -419,7 +419,7 @@ export default function Page({
|
||||||
(flow: OnSelectionChangeParams): void => {
|
(flow: OnSelectionChangeParams): void => {
|
||||||
setLastSelection(flow);
|
setLastSelection(flow);
|
||||||
},
|
},
|
||||||
[],
|
[]
|
||||||
);
|
);
|
||||||
|
|
||||||
const onPaneClick = useCallback((flow) => {
|
const onPaneClick = useCallback((flow) => {
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { NodeToolbar } from "reactflow";
|
import { NodeToolbar } from "reactflow";
|
||||||
import { GradientGroup } from "../../../../icons/GradientSparkles";
|
import { GradientGroup } from "../../../../icons/GradientSparkles";
|
||||||
import { validateSelection } from "../../../../utils/reactflowUtils";
|
|
||||||
import useFlowStore from "../../../../stores/flowStore";
|
import useFlowStore from "../../../../stores/flowStore";
|
||||||
|
import { validateSelection } from "../../../../utils/reactflowUtils";
|
||||||
export default function SelectionMenu({
|
export default function SelectionMenu({
|
||||||
onClick,
|
onClick,
|
||||||
nodes,
|
nodes,
|
||||||
|
|
@ -13,7 +13,7 @@ export default function SelectionMenu({
|
||||||
const [disable, setDisable] = useState<boolean>(
|
const [disable, setDisable] = useState<boolean>(
|
||||||
lastSelection && edges.length > 0
|
lastSelection && edges.length > 0
|
||||||
? validateSelection(lastSelection!, edges).length > 0
|
? validateSelection(lastSelection!, edges).length > 0
|
||||||
: false,
|
: false
|
||||||
);
|
);
|
||||||
const [isOpen, setIsOpen] = useState(false);
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
const [isTransitioning, setIsTransitioning] = useState(false);
|
const [isTransitioning, setIsTransitioning] = useState(false);
|
||||||
|
|
@ -62,7 +62,11 @@ export default function SelectionMenu({
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
className={`${disable ? "flex h-full w-full cursor-not-allowed items-center justify-between text-sm text-muted-foreground" : "flex h-full w-full items-center justify-between text-sm hover:text-indigo-500"}`}
|
className={`${
|
||||||
|
disable
|
||||||
|
? "flex h-full w-full cursor-not-allowed items-center justify-between text-sm text-muted-foreground"
|
||||||
|
: "flex h-full w-full items-center justify-between text-sm hover:text-indigo-500"
|
||||||
|
}`}
|
||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
disabled={disable}
|
disabled={disable}
|
||||||
>
|
>
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,7 @@ export default function NodeToolbarComponent({
|
||||||
data.node.template[templateField].type === "Any" ||
|
data.node.template[templateField].type === "Any" ||
|
||||||
data.node.template[templateField].type === "int" ||
|
data.node.template[templateField].type === "int" ||
|
||||||
data.node.template[templateField].type === "dict" ||
|
data.node.template[templateField].type === "dict" ||
|
||||||
data.node.template[templateField].type === "NestedDict"),
|
data.node.template[templateField].type === "NestedDict")
|
||||||
).length;
|
).length;
|
||||||
const templates = useTypesStore((state) => state.templates);
|
const templates = useTypesStore((state) => state.templates);
|
||||||
const hasStore = useStoreStore((state) => state.hasStore);
|
const hasStore = useStoreStore((state) => state.hasStore);
|
||||||
|
|
@ -85,7 +85,7 @@ export default function NodeToolbarComponent({
|
||||||
const [showconfirmShare, setShowconfirmShare] = useState(false);
|
const [showconfirmShare, setShowconfirmShare] = useState(false);
|
||||||
const [showOverrideModal, setShowOverrideModal] = useState(false);
|
const [showOverrideModal, setShowOverrideModal] = useState(false);
|
||||||
const [flowComponent, setFlowComponent] = useState<FlowType>(
|
const [flowComponent, setFlowComponent] = useState<FlowType>(
|
||||||
createFlowComponent(cloneDeep(data), version),
|
createFlowComponent(cloneDeep(data), version)
|
||||||
);
|
);
|
||||||
|
|
||||||
const openInNewTab = (url) => {
|
const openInNewTab = (url) => {
|
||||||
|
|
@ -100,7 +100,7 @@ export default function NodeToolbarComponent({
|
||||||
const updateNodeInternals = useUpdateNodeInternals();
|
const updateNodeInternals = useUpdateNodeInternals();
|
||||||
|
|
||||||
const setLastCopiedSelection = useFlowStore(
|
const setLastCopiedSelection = useFlowStore(
|
||||||
(state) => state.setLastCopiedSelection,
|
(state) => state.setLastCopiedSelection
|
||||||
);
|
);
|
||||||
|
|
||||||
const setSuccessData = useAlertStore((state) => state.setSuccessData);
|
const setSuccessData = useAlertStore((state) => state.setSuccessData);
|
||||||
|
|
@ -150,7 +150,7 @@ export default function NodeToolbarComponent({
|
||||||
nodes,
|
nodes,
|
||||||
edges,
|
edges,
|
||||||
setNodes,
|
setNodes,
|
||||||
setEdges,
|
setEdges
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
case "override":
|
case "override":
|
||||||
|
|
@ -174,7 +174,7 @@ export default function NodeToolbarComponent({
|
||||||
y: 10,
|
y: 10,
|
||||||
paneX: nodes.find((node) => node.id === data.id)?.position.x,
|
paneX: nodes.find((node) => node.id === data.id)?.position.x,
|
||||||
paneY: nodes.find((node) => node.id === data.id)?.position.y,
|
paneY: nodes.find((node) => node.id === data.id)?.position.y,
|
||||||
},
|
}
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
case "update":
|
case "update":
|
||||||
|
|
@ -212,13 +212,13 @@ export default function NodeToolbarComponent({
|
||||||
};
|
};
|
||||||
|
|
||||||
const isSaved = flows.some((flow) =>
|
const isSaved = flows.some((flow) =>
|
||||||
Object.values(flow).includes(data.node?.display_name!),
|
Object.values(flow).includes(data.node?.display_name!)
|
||||||
);
|
);
|
||||||
|
|
||||||
const setNode = useFlowStore((state) => state.setNode);
|
const setNode = useFlowStore((state) => state.setNode);
|
||||||
|
|
||||||
const handleOnNewValue = (
|
const handleOnNewValue = (
|
||||||
newValue: string | string[] | boolean | Object[],
|
newValue: string | string[] | boolean | Object[]
|
||||||
): void => {
|
): void => {
|
||||||
if (data.node!.template[name].value !== newValue) {
|
if (data.node!.template[name].value !== newValue) {
|
||||||
takeSnapshot();
|
takeSnapshot();
|
||||||
|
|
@ -393,7 +393,7 @@ export default function NodeToolbarComponent({
|
||||||
data-testid="save-button-modal"
|
data-testid="save-button-modal"
|
||||||
className={classNames(
|
className={classNames(
|
||||||
"relative -ml-px inline-flex items-center bg-background px-2 py-2 text-foreground shadow-md ring-1 ring-inset ring-ring transition-all duration-500 ease-in-out hover:bg-muted focus:z-10",
|
"relative -ml-px inline-flex items-center bg-background px-2 py-2 text-foreground shadow-md ring-1 ring-inset ring-ring transition-all duration-500 ease-in-out hover:bg-muted focus:z-10",
|
||||||
hasCode ? " " : " rounded-l-md ",
|
hasCode ? " " : " rounded-l-md "
|
||||||
)}
|
)}
|
||||||
onClick={(event) => {
|
onClick={(event) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
@ -411,7 +411,7 @@ export default function NodeToolbarComponent({
|
||||||
<button
|
<button
|
||||||
data-testid="duplicate-button-modal"
|
data-testid="duplicate-button-modal"
|
||||||
className={classNames(
|
className={classNames(
|
||||||
"relative -ml-px inline-flex items-center bg-background px-2 py-2 text-foreground shadow-md ring-1 ring-inset ring-ring transition-all duration-500 ease-in-out hover:bg-muted focus:z-10",
|
"relative -ml-px inline-flex items-center bg-background px-2 py-2 text-foreground shadow-md ring-1 ring-inset ring-ring transition-all duration-500 ease-in-out hover:bg-muted focus:z-10"
|
||||||
)}
|
)}
|
||||||
onClick={(event) => {
|
onClick={(event) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
@ -459,7 +459,7 @@ export default function NodeToolbarComponent({
|
||||||
<div
|
<div
|
||||||
data-testid="more-options-modal"
|
data-testid="more-options-modal"
|
||||||
className={classNames(
|
className={classNames(
|
||||||
"relative -ml-px inline-flex h-8 w-[31px] items-center rounded-r-md bg-background text-foreground shadow-md ring-1 ring-inset ring-ring transition-all duration-500 ease-in-out hover:bg-muted focus:z-10",
|
"relative -ml-px inline-flex h-8 w-[31px] items-center rounded-r-md bg-background text-foreground shadow-md ring-1 ring-inset ring-ring transition-all duration-500 ease-in-out hover:bg-muted focus:z-10"
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<IconComponent
|
<IconComponent
|
||||||
|
|
|
||||||
|
|
@ -3,10 +3,10 @@ import { useParams } from "react-router-dom";
|
||||||
import FlowToolbar from "../../components/chatComponent";
|
import FlowToolbar from "../../components/chatComponent";
|
||||||
import Header from "../../components/headerComponent";
|
import Header from "../../components/headerComponent";
|
||||||
import { useDarkStore } from "../../stores/darkStore";
|
import { useDarkStore } from "../../stores/darkStore";
|
||||||
|
import useFlowStore from "../../stores/flowStore";
|
||||||
import useFlowsManagerStore from "../../stores/flowsManagerStore";
|
import useFlowsManagerStore from "../../stores/flowsManagerStore";
|
||||||
import Page from "./components/PageComponent";
|
import Page from "./components/PageComponent";
|
||||||
import ExtraSidebar from "./components/extraSidebarComponent";
|
import ExtraSidebar from "./components/extraSidebarComponent";
|
||||||
import useFlowStore from "../../stores/flowStore";
|
|
||||||
|
|
||||||
export default function FlowPage({ view }: { view?: boolean }): JSX.Element {
|
export default function FlowPage({ view }: { view?: boolean }): JSX.Element {
|
||||||
const setCurrentFlowId = useFlowsManagerStore(
|
const setCurrentFlowId = useFlowsManagerStore(
|
||||||
|
|
@ -21,7 +21,7 @@ export default function FlowPage({ view }: { view?: boolean }): JSX.Element {
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setCurrentFlowId(id!);
|
setCurrentFlowId(id!);
|
||||||
setOnFlowPage(true);
|
setOnFlowPage(true);
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
setOnFlowPage(false);
|
setOnFlowPage(false);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,64 +1,69 @@
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { useParams } from "react-router-dom";
|
import { useParams } from "react-router-dom";
|
||||||
import useFlowsManagerStore from "../../stores/flowsManagerStore";
|
|
||||||
import { getComponent } from "../../controllers/API";
|
|
||||||
import cloneFLowWithParent from "../../utils/storeUtils";
|
|
||||||
import LoadingComponent from "../../components/loadingComponent";
|
import LoadingComponent from "../../components/loadingComponent";
|
||||||
import useFlowStore from "../../stores/flowStore";
|
import { getComponent } from "../../controllers/API";
|
||||||
import IOModal from "../../modals/IOModal";
|
import IOModal from "../../modals/IOModal";
|
||||||
|
import useFlowStore from "../../stores/flowStore";
|
||||||
|
import useFlowsManagerStore from "../../stores/flowsManagerStore";
|
||||||
|
import cloneFLowWithParent from "../../utils/storeUtils";
|
||||||
|
|
||||||
export default function PlaygroundPage() {
|
export default function PlaygroundPage() {
|
||||||
const currentFlow = useFlowsManagerStore((state) => state.currentFlow);
|
const currentFlow = useFlowsManagerStore((state) => state.currentFlow);
|
||||||
const getFlowById = useFlowsManagerStore((state) => state.getFlowById);
|
const getFlowById = useFlowsManagerStore((state) => state.getFlowById);
|
||||||
const setCurrentFlowId = useFlowsManagerStore((state) => state.setCurrentFlowId);
|
const setCurrentFlowId = useFlowsManagerStore(
|
||||||
const currentFlowId = useFlowsManagerStore((state) => state.currentFlowId);
|
(state) => state.setCurrentFlowId
|
||||||
const setCurrentFlow = useFlowsManagerStore((state) => state.setCurrentFlow);
|
);
|
||||||
const setNodes = useFlowStore((state) => state.setNodes);
|
const currentFlowId = useFlowsManagerStore((state) => state.currentFlowId);
|
||||||
const setEdges = useFlowStore((state) => state.setEdges);
|
const setCurrentFlow = useFlowsManagerStore((state) => state.setCurrentFlow);
|
||||||
const cleanFlowPool = useFlowStore((state) => state.CleanFlowPool);
|
const setNodes = useFlowStore((state) => state.setNodes);
|
||||||
|
const setEdges = useFlowStore((state) => state.setEdges);
|
||||||
|
const cleanFlowPool = useFlowStore((state) => state.CleanFlowPool);
|
||||||
|
|
||||||
const { id } = useParams();
|
const { id } = useParams();
|
||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
async function getFlowData() {
|
async function getFlowData() {
|
||||||
const res = await getComponent(id!);
|
const res = await getComponent(id!);
|
||||||
const newFlow = cloneFLowWithParent(res, res.id, false, true);
|
const newFlow = cloneFLowWithParent(res, res.id, false, true);
|
||||||
return newFlow;
|
return newFlow;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set flow tab id
|
||||||
|
useEffect(() => {
|
||||||
|
console.log("id", id);
|
||||||
|
if (getFlowById(id!)) {
|
||||||
|
setCurrentFlowId(id!);
|
||||||
|
} else {
|
||||||
|
getFlowData().then((flow) => {
|
||||||
|
setCurrentFlow(flow);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
}, [id]);
|
||||||
|
|
||||||
// Set flow tab id
|
useEffect(() => {
|
||||||
useEffect(() => {
|
if (currentFlow) {
|
||||||
console.log("id", id);
|
setNodes(currentFlow?.data?.nodes ?? [], true);
|
||||||
if (getFlowById(id!)) {
|
setEdges(currentFlow?.data?.edges ?? [], true);
|
||||||
setCurrentFlowId(id!);
|
cleanFlowPool();
|
||||||
}
|
setLoading(false);
|
||||||
else {
|
}
|
||||||
getFlowData().then((flow) => {
|
return () => {
|
||||||
setCurrentFlow(flow);
|
setNodes([], true);
|
||||||
});
|
setEdges([], true);
|
||||||
}
|
cleanFlowPool();
|
||||||
}, [id]);
|
};
|
||||||
|
}, [currentFlow]);
|
||||||
|
|
||||||
useEffect(() => {
|
return (
|
||||||
if (currentFlow) {
|
<div className="flex h-full w-full flex-col items-center justify-center align-middle">
|
||||||
setNodes(currentFlow?.data?.nodes ?? [], true);
|
{loading ? (
|
||||||
setEdges(currentFlow?.data?.edges ?? [], true);
|
<div>
|
||||||
cleanFlowPool();
|
<LoadingComponent remSize={24}></LoadingComponent>
|
||||||
setLoading(false);
|
|
||||||
}
|
|
||||||
return () => {
|
|
||||||
setNodes([], true);
|
|
||||||
setEdges([], true);
|
|
||||||
cleanFlowPool();
|
|
||||||
};
|
|
||||||
}, [currentFlow]);
|
|
||||||
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="w-full h-full flex flex-col align-middle items-center justify-center">
|
|
||||||
{loading ? <div><LoadingComponent remSize={24}></LoadingComponent></div> :
|
|
||||||
<IOModal open={true}setOpen={()=>{}} isPlayground>
|
|
||||||
<></>
|
|
||||||
</IOModal>}
|
|
||||||
</div>
|
</div>
|
||||||
)
|
) : (
|
||||||
}
|
<IOModal open={true} setOpen={() => {}} isPlayground>
|
||||||
|
<></>
|
||||||
|
</IOModal>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -113,110 +113,109 @@ export default function GeneralPage() {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="grid gap-6">
|
<div className="grid gap-6">
|
||||||
|
<Form.Root
|
||||||
<Form.Root
|
onSubmit={(event) => {
|
||||||
onSubmit={(event) => {
|
handlePatchGradient();
|
||||||
handlePatchGradient();
|
event.preventDefault();
|
||||||
event.preventDefault();
|
}}
|
||||||
}}
|
>
|
||||||
>
|
<Card x-chunk="dashboard-04-chunk-1">
|
||||||
<Card x-chunk="dashboard-04-chunk-1">
|
<CardHeader>
|
||||||
<CardHeader>
|
<CardTitle>Profile Gradient</CardTitle>
|
||||||
<CardTitle>Profile Gradient</CardTitle>
|
<CardDescription>
|
||||||
<CardDescription>
|
Choose the gradient that appears as your profile picture.
|
||||||
Choose the gradient that appears as your profile picture.
|
</CardDescription>
|
||||||
</CardDescription>
|
</CardHeader>
|
||||||
</CardHeader>
|
<CardContent>
|
||||||
<CardContent>
|
<div className="py-2">
|
||||||
<div className="py-2">
|
<GradientChooserComponent
|
||||||
<GradientChooserComponent
|
value={
|
||||||
value={
|
gradient == ""
|
||||||
gradient == ""
|
? userData?.profile_image ??
|
||||||
? userData?.profile_image ??
|
gradients[
|
||||||
gradients[
|
parseInt(userData?.id ?? "", 30) % gradients.length
|
||||||
parseInt(userData?.id ?? "", 30) %
|
]
|
||||||
gradients.length
|
: gradient
|
||||||
]
|
}
|
||||||
: gradient
|
onChange={(value) => {
|
||||||
}
|
handleInput({ target: { name: "gradient", value } });
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</CardContent>
|
||||||
|
<CardFooter className="border-t px-6 py-4">
|
||||||
|
<Form.Submit asChild>
|
||||||
|
<Button type="submit">Save</Button>
|
||||||
|
</Form.Submit>
|
||||||
|
</CardFooter>
|
||||||
|
</Card>
|
||||||
|
</Form.Root>
|
||||||
|
{!autoLogin && (
|
||||||
|
<Form.Root
|
||||||
|
onSubmit={(event) => {
|
||||||
|
handlePatchPassword();
|
||||||
|
event.preventDefault();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Card x-chunk="dashboard-04-chunk-2">
|
||||||
|
<CardHeader>
|
||||||
|
<CardTitle>Password</CardTitle>
|
||||||
|
<CardDescription>
|
||||||
|
Type your new password and confirm it.
|
||||||
|
</CardDescription>
|
||||||
|
</CardHeader>
|
||||||
|
<CardContent>
|
||||||
|
<div className="flex w-full gap-4">
|
||||||
|
<Form.Field name="password" className="w-full">
|
||||||
|
<InputComponent
|
||||||
|
id="pasword"
|
||||||
onChange={(value) => {
|
onChange={(value) => {
|
||||||
handleInput({ target: { name: "gradient", value } });
|
handleInput({ target: { name: "password", value } });
|
||||||
}}
|
}}
|
||||||
|
value={password}
|
||||||
|
isForm
|
||||||
|
password={true}
|
||||||
|
placeholder="Password"
|
||||||
|
className="w-full"
|
||||||
|
/>
|
||||||
|
<Form.Message
|
||||||
|
match="valueMissing"
|
||||||
|
className="field-invalid"
|
||||||
|
>
|
||||||
|
Please enter your password
|
||||||
|
</Form.Message>
|
||||||
|
</Form.Field>
|
||||||
|
<Form.Field name="cnfPassword" className="w-full">
|
||||||
|
<InputComponent
|
||||||
|
id="cnfPassword"
|
||||||
|
onChange={(value) => {
|
||||||
|
handleInput({
|
||||||
|
target: { name: "cnfPassword", value },
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
value={cnfPassword}
|
||||||
|
isForm
|
||||||
|
password={true}
|
||||||
|
placeholder="Confirm Password"
|
||||||
|
className="w-full"
|
||||||
/>
|
/>
|
||||||
</div>
|
|
||||||
</CardContent>
|
|
||||||
<CardFooter className="border-t px-6 py-4">
|
|
||||||
<Form.Submit asChild>
|
|
||||||
<Button type="submit">Save</Button>
|
|
||||||
</Form.Submit>
|
|
||||||
</CardFooter>
|
|
||||||
</Card>
|
|
||||||
</Form.Root>{!autoLogin && (
|
|
||||||
<Form.Root
|
|
||||||
onSubmit={(event) => {
|
|
||||||
handlePatchPassword();
|
|
||||||
event.preventDefault();
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Card x-chunk="dashboard-04-chunk-2">
|
|
||||||
<CardHeader>
|
|
||||||
<CardTitle>Password</CardTitle>
|
|
||||||
<CardDescription>
|
|
||||||
Type your new password and confirm it.
|
|
||||||
</CardDescription>
|
|
||||||
</CardHeader>
|
|
||||||
<CardContent>
|
|
||||||
<div className="flex w-full gap-4">
|
|
||||||
<Form.Field name="password" className="w-full">
|
|
||||||
<InputComponent
|
|
||||||
id="pasword"
|
|
||||||
onChange={(value) => {
|
|
||||||
handleInput({ target: { name: "password", value } });
|
|
||||||
}}
|
|
||||||
value={password}
|
|
||||||
isForm
|
|
||||||
password={true}
|
|
||||||
placeholder="Password"
|
|
||||||
className="w-full"
|
|
||||||
/>
|
|
||||||
<Form.Message
|
|
||||||
match="valueMissing"
|
|
||||||
className="field-invalid"
|
|
||||||
>
|
|
||||||
Please enter your password
|
|
||||||
</Form.Message>
|
|
||||||
</Form.Field>
|
|
||||||
<Form.Field name="cnfPassword" className="w-full">
|
|
||||||
<InputComponent
|
|
||||||
id="cnfPassword"
|
|
||||||
onChange={(value) => {
|
|
||||||
handleInput({
|
|
||||||
target: { name: "cnfPassword", value },
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
value={cnfPassword}
|
|
||||||
isForm
|
|
||||||
password={true}
|
|
||||||
placeholder="Confirm Password"
|
|
||||||
className="w-full"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<Form.Message
|
<Form.Message
|
||||||
className="field-invalid"
|
className="field-invalid"
|
||||||
match="valueMissing"
|
match="valueMissing"
|
||||||
>
|
>
|
||||||
Please confirm your password
|
Please confirm your password
|
||||||
</Form.Message>
|
</Form.Message>
|
||||||
</Form.Field>
|
</Form.Field>
|
||||||
</div>
|
</div>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
<CardFooter className="border-t px-6 py-4">
|
<CardFooter className="border-t px-6 py-4">
|
||||||
<Form.Submit asChild>
|
<Form.Submit asChild>
|
||||||
<Button type="submit">Save</Button>
|
<Button type="submit">Save</Button>
|
||||||
</Form.Submit>
|
</Form.Submit>
|
||||||
</CardFooter>
|
</CardFooter>
|
||||||
</Card>
|
</Card>
|
||||||
</Form.Root>
|
</Form.Root>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -16,13 +16,13 @@ import { cn } from "../../../../utils/utils";
|
||||||
|
|
||||||
export default function GlobalVariablesPage() {
|
export default function GlobalVariablesPage() {
|
||||||
const globalVariablesEntries = useGlobalVariablesStore(
|
const globalVariablesEntries = useGlobalVariablesStore(
|
||||||
(state) => state.globalVariablesEntries,
|
(state) => state.globalVariablesEntries
|
||||||
);
|
);
|
||||||
const removeGlobalVariable = useGlobalVariablesStore(
|
const removeGlobalVariable = useGlobalVariablesStore(
|
||||||
(state) => state.removeGlobalVariable,
|
(state) => state.removeGlobalVariable
|
||||||
);
|
);
|
||||||
const globalVariables = useGlobalVariablesStore(
|
const globalVariables = useGlobalVariablesStore(
|
||||||
(state) => state.globalVariables,
|
(state) => state.globalVariables
|
||||||
);
|
);
|
||||||
const setErrorData = useAlertStore((state) => state.setErrorData);
|
const setErrorData = useAlertStore((state) => state.setErrorData);
|
||||||
const getVariableId = useGlobalVariablesStore((state) => state.getVariableId);
|
const getVariableId = useGlobalVariablesStore((state) => state.getVariableId);
|
||||||
|
|
@ -156,7 +156,7 @@ export default function GlobalVariablesPage() {
|
||||||
<IconComponent
|
<IconComponent
|
||||||
name="Trash2"
|
name="Trash2"
|
||||||
className={cn(
|
className={cn(
|
||||||
"h-5 w-5 text-destructive group-disabled:text-primary",
|
"h-5 w-5 text-destructive group-disabled:text-primary"
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
</Button>
|
</Button>
|
||||||
|
|
@ -176,7 +176,7 @@ export default function GlobalVariablesPage() {
|
||||||
overlayNoRowsTemplate="No data available"
|
overlayNoRowsTemplate="No data available"
|
||||||
onSelectionChanged={(event: SelectionChangedEvent) => {
|
onSelectionChanged={(event: SelectionChangedEvent) => {
|
||||||
setSelectedRows(
|
setSelectedRows(
|
||||||
event.api.getSelectedRows().map((row) => row.name),
|
event.api.getSelectedRows().map((row) => row.name)
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
rowSelection="multiple"
|
rowSelection="multiple"
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,6 @@ const useFlowsManagerStore = create<FlowsManagerStoreType>((set, get) => ({
|
||||||
currentFlow: flow,
|
currentFlow: flow,
|
||||||
currentFlowId: flow.id,
|
currentFlowId: flow.id,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
},
|
},
|
||||||
getFlowById: (id: string) => {
|
getFlowById: (id: string) => {
|
||||||
return get().flows.find((flow) => flow.id === id);
|
return get().flows.find((flow) => flow.id === id);
|
||||||
|
|
|
||||||
|
|
@ -511,7 +511,7 @@ export type nodeToolbarPropsType = {
|
||||||
updateNodeCode?: (
|
updateNodeCode?: (
|
||||||
newNodeClass: APIClassType,
|
newNodeClass: APIClassType,
|
||||||
code: string,
|
code: string,
|
||||||
name: string,
|
name: string
|
||||||
) => void;
|
) => void;
|
||||||
setShowState: (show: boolean | SetStateAction<boolean>) => void;
|
setShowState: (show: boolean | SetStateAction<boolean>) => void;
|
||||||
isOutdated?: boolean;
|
isOutdated?: boolean;
|
||||||
|
|
@ -561,7 +561,7 @@ export type chatMessagePropsType = {
|
||||||
updateChat: (
|
updateChat: (
|
||||||
chat: ChatMessageType,
|
chat: ChatMessageType,
|
||||||
message: string,
|
message: string,
|
||||||
stream_url?: string,
|
stream_url?: string
|
||||||
) => void;
|
) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -653,12 +653,12 @@ export type codeTabsPropsType = {
|
||||||
value: string,
|
value: string,
|
||||||
node: NodeType,
|
node: NodeType,
|
||||||
template: TemplateVariableType,
|
template: TemplateVariableType,
|
||||||
tweak: tweakType,
|
tweak: tweakType
|
||||||
) => string;
|
) => string;
|
||||||
buildTweakObject?: (
|
buildTweakObject?: (
|
||||||
tw: string,
|
tw: string,
|
||||||
changes: string | string[] | boolean | number | Object[] | Object,
|
changes: string | string[] | boolean | number | Object[] | Object,
|
||||||
template: TemplateVariableType,
|
template: TemplateVariableType
|
||||||
) => Promise<string | void>;
|
) => Promise<string | void>;
|
||||||
};
|
};
|
||||||
activeTweaks?: boolean;
|
activeTweaks?: boolean;
|
||||||
|
|
|
||||||
|
|
@ -76,8 +76,14 @@ export type FlowStoreType = {
|
||||||
edges: Edge[];
|
edges: Edge[];
|
||||||
onNodesChange: OnNodesChange;
|
onNodesChange: OnNodesChange;
|
||||||
onEdgesChange: OnEdgesChange;
|
onEdgesChange: OnEdgesChange;
|
||||||
setNodes: (update: Node[] | ((oldState: Node[]) => Node[]),skipSave?:boolean) => void;
|
setNodes: (
|
||||||
setEdges: (update: Edge[] | ((oldState: Edge[]) => Edge[]),skipSave?:boolean) => void;
|
update: Node[] | ((oldState: Node[]) => Node[]),
|
||||||
|
skipSave?: boolean
|
||||||
|
) => void;
|
||||||
|
setEdges: (
|
||||||
|
update: Edge[] | ((oldState: Edge[]) => Edge[]),
|
||||||
|
skipSave?: boolean
|
||||||
|
) => void;
|
||||||
setNode: (id: string, update: Node | ((oldState: Node) => Node)) => void;
|
setNode: (id: string, update: Node | ((oldState: Node) => Node)) => void;
|
||||||
getNode: (id: string) => Node | undefined;
|
getNode: (id: string) => Node | undefined;
|
||||||
deleteNode: (nodeId: string | Array<string>) => void;
|
deleteNode: (nodeId: string | Array<string>) => void;
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ export type GlobalVariablesStore = {
|
||||||
) => void;
|
) => void;
|
||||||
removeGlobalVariable: (name: string) => Promise<void>;
|
removeGlobalVariable: (name: string) => Promise<void>;
|
||||||
getVariableId: (name: string) => string | undefined;
|
getVariableId: (name: string) => string | undefined;
|
||||||
unavaliableFields: {[name: string]: string};
|
unavaliableFields: { [name: string]: string };
|
||||||
setUnavaliableFields: (fields: {[name: string]: string}) => void;
|
setUnavaliableFields: (fields: { [name: string]: string }) => void;
|
||||||
removeUnavaliableField: (field: string) => void;
|
removeUnavaliableField: (field: string) => void;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ export const handleUpdateValues = async (name: string, data: NodeDataType) => {
|
||||||
code,
|
code,
|
||||||
template,
|
template,
|
||||||
name,
|
name,
|
||||||
data.node?.template[name]?.value,
|
data.node?.template[name]?.value
|
||||||
);
|
);
|
||||||
if (res.status === 200 && data.node?.template) {
|
if (res.status === 200 && data.node?.template) {
|
||||||
return res.data.template;
|
return res.data.template;
|
||||||
|
|
@ -34,5 +34,5 @@ export const handleUpdateValues = async (name: string, data: NodeDataType) => {
|
||||||
|
|
||||||
export const debouncedHandleUpdateValues = debounce(
|
export const debouncedHandleUpdateValues = debounce(
|
||||||
handleUpdateValues,
|
handleUpdateValues,
|
||||||
SAVE_DEBOUNCE_TIME,
|
SAVE_DEBOUNCE_TIME
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -102,18 +102,18 @@ export function unselectAllNodes({ updateNodes, data }: unselectAllNodesType) {
|
||||||
export function isValidConnection(
|
export function isValidConnection(
|
||||||
{ source, target, sourceHandle, targetHandle }: Connection,
|
{ source, target, sourceHandle, targetHandle }: Connection,
|
||||||
nodes: Node[],
|
nodes: Node[],
|
||||||
edges: Edge[],
|
edges: Edge[]
|
||||||
) {
|
) {
|
||||||
const targetHandleObject: targetHandleType = scapeJSONParse(targetHandle!);
|
const targetHandleObject: targetHandleType = scapeJSONParse(targetHandle!);
|
||||||
const sourceHandleObject: sourceHandleType = scapeJSONParse(sourceHandle!);
|
const sourceHandleObject: sourceHandleType = scapeJSONParse(sourceHandle!);
|
||||||
if (
|
if (
|
||||||
targetHandleObject.inputTypes?.some(
|
targetHandleObject.inputTypes?.some(
|
||||||
(n) => n === sourceHandleObject.dataType,
|
(n) => n === sourceHandleObject.dataType
|
||||||
) ||
|
) ||
|
||||||
sourceHandleObject.baseClasses.some(
|
sourceHandleObject.baseClasses.some(
|
||||||
(t) =>
|
(t) =>
|
||||||
targetHandleObject.inputTypes?.some((n) => n === t) ||
|
targetHandleObject.inputTypes?.some((n) => n === t) ||
|
||||||
t === targetHandleObject.type,
|
t === targetHandleObject.type
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
let targetNode = nodes.find((node) => node.id === target!)?.data?.node;
|
let targetNode = nodes.find((node) => node.id === target!)?.data?.node;
|
||||||
|
|
@ -146,7 +146,7 @@ export function removeApiKeys(flow: FlowType): FlowType {
|
||||||
|
|
||||||
export function updateTemplate(
|
export function updateTemplate(
|
||||||
reference: APITemplateType,
|
reference: APITemplateType,
|
||||||
objectToUpdate: APITemplateType,
|
objectToUpdate: APITemplateType
|
||||||
): APITemplateType {
|
): APITemplateType {
|
||||||
let clonedObject: APITemplateType = cloneDeep(reference);
|
let clonedObject: APITemplateType = cloneDeep(reference);
|
||||||
|
|
||||||
|
|
@ -206,7 +206,7 @@ export const processDataFromFlow = (flow: FlowType, refreshIds = true) => {
|
||||||
|
|
||||||
export function updateIds(
|
export function updateIds(
|
||||||
{ edges, nodes }: { edges: Edge[]; nodes: Node[] },
|
{ edges, nodes }: { edges: Edge[]; nodes: Node[] },
|
||||||
selection?: { edges: Edge[]; nodes: Node[] },
|
selection?: { edges: Edge[]; nodes: Node[] }
|
||||||
) {
|
) {
|
||||||
let idsMap = {};
|
let idsMap = {};
|
||||||
const selectionIds = selection?.nodes.map((n) => n.id);
|
const selectionIds = selection?.nodes.map((n) => n.id);
|
||||||
|
|
@ -234,7 +234,7 @@ export function updateIds(
|
||||||
edge.source = idsMap[edge.source];
|
edge.source = idsMap[edge.source];
|
||||||
edge.target = idsMap[edge.target];
|
edge.target = idsMap[edge.target];
|
||||||
const sourceHandleObject: sourceHandleType = scapeJSONParse(
|
const sourceHandleObject: sourceHandleType = scapeJSONParse(
|
||||||
edge.sourceHandle!,
|
edge.sourceHandle!
|
||||||
);
|
);
|
||||||
edge.sourceHandle = scapedJSONStringfy({
|
edge.sourceHandle = scapedJSONStringfy({
|
||||||
...sourceHandleObject,
|
...sourceHandleObject,
|
||||||
|
|
@ -244,7 +244,7 @@ export function updateIds(
|
||||||
edge.data.sourceHandle.id = edge.source;
|
edge.data.sourceHandle.id = edge.source;
|
||||||
}
|
}
|
||||||
const targetHandleObject: targetHandleType = scapeJSONParse(
|
const targetHandleObject: targetHandleType = scapeJSONParse(
|
||||||
edge.targetHandle!,
|
edge.targetHandle!
|
||||||
);
|
);
|
||||||
edge.targetHandle = scapedJSONStringfy({
|
edge.targetHandle = scapedJSONStringfy({
|
||||||
...targetHandleObject,
|
...targetHandleObject,
|
||||||
|
|
@ -290,11 +290,11 @@ export function validateNode(node: NodeType, edges: Edge[]): Array<string> {
|
||||||
(scapeJSONParse(edge.targetHandle!) as targetHandleType).fieldName ===
|
(scapeJSONParse(edge.targetHandle!) as targetHandleType).fieldName ===
|
||||||
t &&
|
t &&
|
||||||
(scapeJSONParse(edge.targetHandle!) as targetHandleType).id ===
|
(scapeJSONParse(edge.targetHandle!) as targetHandleType).id ===
|
||||||
node.id,
|
node.id
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
errors.push(
|
errors.push(
|
||||||
`${displayName || type} is missing ${getFieldTitle(template, t)}.`,
|
`${displayName || type} is missing ${getFieldTitle(template, t)}.`
|
||||||
);
|
);
|
||||||
} else if (
|
} else if (
|
||||||
template[t].type === "dict" &&
|
template[t].type === "dict" &&
|
||||||
|
|
@ -308,15 +308,15 @@ export function validateNode(node: NodeType, edges: Edge[]): Array<string> {
|
||||||
errors.push(
|
errors.push(
|
||||||
`${displayName || type} (${getFieldTitle(
|
`${displayName || type} (${getFieldTitle(
|
||||||
template,
|
template,
|
||||||
t,
|
t
|
||||||
)}) contains duplicate keys with the same values.`,
|
)}) contains duplicate keys with the same values.`
|
||||||
);
|
);
|
||||||
if (hasEmptyKey(template[t].value))
|
if (hasEmptyKey(template[t].value))
|
||||||
errors.push(
|
errors.push(
|
||||||
`${displayName || type} (${getFieldTitle(
|
`${displayName || type} (${getFieldTitle(
|
||||||
template,
|
template,
|
||||||
t,
|
t
|
||||||
)}) field must not be empty.`,
|
)}) field must not be empty.`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return errors;
|
return errors;
|
||||||
|
|
@ -325,7 +325,7 @@ export function validateNode(node: NodeType, edges: Edge[]): Array<string> {
|
||||||
|
|
||||||
export function validateNodes(
|
export function validateNodes(
|
||||||
nodes: Node[],
|
nodes: Node[],
|
||||||
edges: Edge[],
|
edges: Edge[]
|
||||||
): // this returns an array of tuples with the node id and the errors
|
): // this returns an array of tuples with the node id and the errors
|
||||||
Array<{ id: string; errors: Array<string> }> {
|
Array<{ id: string; errors: Array<string> }> {
|
||||||
if (nodes.length === 0) {
|
if (nodes.length === 0) {
|
||||||
|
|
@ -346,7 +346,7 @@ export function updateEdges(edges: Edge[]) {
|
||||||
if (edges)
|
if (edges)
|
||||||
edges.forEach((edge) => {
|
edges.forEach((edge) => {
|
||||||
const targetHandleObject: targetHandleType = scapeJSONParse(
|
const targetHandleObject: targetHandleType = scapeJSONParse(
|
||||||
edge.targetHandle!,
|
edge.targetHandle!
|
||||||
);
|
);
|
||||||
edge.className = "stroke-gray-900 stroke-connection";
|
edge.className = "stroke-gray-900 stroke-connection";
|
||||||
});
|
});
|
||||||
|
|
@ -413,7 +413,7 @@ export function handleKeyDown(
|
||||||
| React.KeyboardEvent<HTMLInputElement>
|
| React.KeyboardEvent<HTMLInputElement>
|
||||||
| React.KeyboardEvent<HTMLTextAreaElement>,
|
| React.KeyboardEvent<HTMLTextAreaElement>,
|
||||||
inputValue: string | string[] | null,
|
inputValue: string | string[] | null,
|
||||||
block: string,
|
block: string
|
||||||
) {
|
) {
|
||||||
//condition to fix bug control+backspace on Windows/Linux
|
//condition to fix bug control+backspace on Windows/Linux
|
||||||
if (
|
if (
|
||||||
|
|
@ -438,7 +438,7 @@ export function handleKeyDown(
|
||||||
}
|
}
|
||||||
|
|
||||||
export function handleOnlyIntegerInput(
|
export function handleOnlyIntegerInput(
|
||||||
event: React.KeyboardEvent<HTMLInputElement>,
|
event: React.KeyboardEvent<HTMLInputElement>
|
||||||
) {
|
) {
|
||||||
if (
|
if (
|
||||||
event.key === "." ||
|
event.key === "." ||
|
||||||
|
|
@ -454,7 +454,7 @@ export function handleOnlyIntegerInput(
|
||||||
|
|
||||||
export function getConnectedNodes(
|
export function getConnectedNodes(
|
||||||
edge: Edge,
|
edge: Edge,
|
||||||
nodes: Array<NodeType>,
|
nodes: Array<NodeType>
|
||||||
): Array<NodeType> {
|
): Array<NodeType> {
|
||||||
const sourceId = edge.source;
|
const sourceId = edge.source;
|
||||||
const targetId = edge.target;
|
const targetId = edge.target;
|
||||||
|
|
@ -554,7 +554,7 @@ export function checkOldEdgesHandles(edges: Edge[]): boolean {
|
||||||
!edge.sourceHandle ||
|
!edge.sourceHandle ||
|
||||||
!edge.targetHandle ||
|
!edge.targetHandle ||
|
||||||
!edge.sourceHandle.includes("{") ||
|
!edge.sourceHandle.includes("{") ||
|
||||||
!edge.targetHandle.includes("{"),
|
!edge.targetHandle.includes("{")
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -577,7 +577,7 @@ export function customStringify(obj: any): string {
|
||||||
|
|
||||||
const keys = Object.keys(obj).sort();
|
const keys = Object.keys(obj).sort();
|
||||||
const keyValuePairs = keys.map(
|
const keyValuePairs = keys.map(
|
||||||
(key) => `"${key}":${customStringify(obj[key])}`,
|
(key) => `"${key}":${customStringify(obj[key])}`
|
||||||
);
|
);
|
||||||
return `{${keyValuePairs.join(",")}}`;
|
return `{${keyValuePairs.join(",")}}`;
|
||||||
}
|
}
|
||||||
|
|
@ -606,7 +606,7 @@ export function getHandleId(
|
||||||
source: string,
|
source: string,
|
||||||
sourceHandle: string,
|
sourceHandle: string,
|
||||||
target: string,
|
target: string,
|
||||||
targetHandle: string,
|
targetHandle: string
|
||||||
) {
|
) {
|
||||||
return (
|
return (
|
||||||
"reactflow__edge-" + source + sourceHandle + "-" + target + targetHandle
|
"reactflow__edge-" + source + sourceHandle + "-" + target + targetHandle
|
||||||
|
|
@ -617,7 +617,7 @@ export function generateFlow(
|
||||||
selection: OnSelectionChangeParams,
|
selection: OnSelectionChangeParams,
|
||||||
nodes: Node[],
|
nodes: Node[],
|
||||||
edges: Edge[],
|
edges: Edge[],
|
||||||
name: string,
|
name: string
|
||||||
): generateFlowType {
|
): generateFlowType {
|
||||||
const newFlowData = { nodes, edges, viewport: { zoom: 1, x: 0, y: 0 } };
|
const newFlowData = { nodes, edges, viewport: { zoom: 1, x: 0, y: 0 } };
|
||||||
const uid = new ShortUniqueId({ length: 5 });
|
const uid = new ShortUniqueId({ length: 5 });
|
||||||
|
|
@ -626,7 +626,7 @@ export function generateFlow(
|
||||||
newFlowData.edges = selection.edges.filter(
|
newFlowData.edges = selection.edges.filter(
|
||||||
(edge) =>
|
(edge) =>
|
||||||
selection.nodes.some((node) => node.id === edge.target) &&
|
selection.nodes.some((node) => node.id === edge.target) &&
|
||||||
selection.nodes.some((node) => node.id === edge.source),
|
selection.nodes.some((node) => node.id === edge.source)
|
||||||
);
|
);
|
||||||
newFlowData.nodes = selection.nodes;
|
newFlowData.nodes = selection.nodes;
|
||||||
|
|
||||||
|
|
@ -647,7 +647,7 @@ export function generateFlow(
|
||||||
(edge) =>
|
(edge) =>
|
||||||
(selection.nodes.some((node) => node.id === edge.target) ||
|
(selection.nodes.some((node) => node.id === edge.target) ||
|
||||||
selection.nodes.some((node) => node.id === edge.source)) &&
|
selection.nodes.some((node) => node.id === edge.source)) &&
|
||||||
newFlowData.edges.every((e) => e.id !== edge.id),
|
newFlowData.edges.every((e) => e.id !== edge.id)
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
@ -658,13 +658,13 @@ export function reconnectEdges(groupNode: NodeType, excludedEdges: Edge[]) {
|
||||||
const { nodes, edges } = groupNode.data.node!.flow!.data!;
|
const { nodes, edges } = groupNode.data.node!.flow!.data!;
|
||||||
const lastNode = findLastNode(groupNode.data.node!.flow!.data!);
|
const lastNode = findLastNode(groupNode.data.node!.flow!.data!);
|
||||||
newEdges = newEdges.filter(
|
newEdges = newEdges.filter(
|
||||||
(e) => !(nodes.some((n) => n.id === e.source) && e.source !== lastNode?.id),
|
(e) => !(nodes.some((n) => n.id === e.source) && e.source !== lastNode?.id)
|
||||||
);
|
);
|
||||||
newEdges.forEach((edge) => {
|
newEdges.forEach((edge) => {
|
||||||
if (lastNode && edge.source === lastNode.id) {
|
if (lastNode && edge.source === lastNode.id) {
|
||||||
edge.source = groupNode.id;
|
edge.source = groupNode.id;
|
||||||
let newSourceHandle: sourceHandleType = scapeJSONParse(
|
let newSourceHandle: sourceHandleType = scapeJSONParse(
|
||||||
edge.sourceHandle!,
|
edge.sourceHandle!
|
||||||
);
|
);
|
||||||
newSourceHandle.id = groupNode.id;
|
newSourceHandle.id = groupNode.id;
|
||||||
edge.sourceHandle = scapedJSONStringfy(newSourceHandle);
|
edge.sourceHandle = scapedJSONStringfy(newSourceHandle);
|
||||||
|
|
@ -691,7 +691,7 @@ export function reconnectEdges(groupNode: NodeType, excludedEdges: Edge[]) {
|
||||||
export function filterFlow(
|
export function filterFlow(
|
||||||
selection: OnSelectionChangeParams,
|
selection: OnSelectionChangeParams,
|
||||||
setNodes: (update: Node[] | ((oldState: Node[]) => Node[])) => void,
|
setNodes: (update: Node[] | ((oldState: Node[]) => Node[])) => void,
|
||||||
setEdges: (update: Edge[] | ((oldState: Edge[]) => Edge[])) => void,
|
setEdges: (update: Edge[] | ((oldState: Edge[]) => Edge[])) => void
|
||||||
) {
|
) {
|
||||||
setNodes((nodes) => nodes.filter((node) => !selection.nodes.includes(node)));
|
setNodes((nodes) => nodes.filter((node) => !selection.nodes.includes(node)));
|
||||||
setEdges((edges) => edges.filter((edge) => !selection.edges.includes(edge)));
|
setEdges((edges) => edges.filter((edge) => !selection.edges.includes(edge)));
|
||||||
|
|
@ -729,7 +729,7 @@ export function updateFlowPosition(NewPosition: XYPosition, flow: FlowType) {
|
||||||
export function concatFlows(
|
export function concatFlows(
|
||||||
flow: FlowType,
|
flow: FlowType,
|
||||||
setNodes: (update: Node[] | ((oldState: Node[]) => Node[])) => void,
|
setNodes: (update: Node[] | ((oldState: Node[]) => Node[])) => void,
|
||||||
setEdges: (update: Edge[] | ((oldState: Edge[]) => Edge[])) => void,
|
setEdges: (update: Edge[] | ((oldState: Edge[]) => Edge[])) => void
|
||||||
) {
|
) {
|
||||||
const { nodes, edges } = flow.data!;
|
const { nodes, edges } = flow.data!;
|
||||||
setNodes((old) => [...old, ...nodes]);
|
setNodes((old) => [...old, ...nodes]);
|
||||||
|
|
@ -738,7 +738,7 @@ export function concatFlows(
|
||||||
|
|
||||||
export function validateSelection(
|
export function validateSelection(
|
||||||
selection: OnSelectionChangeParams,
|
selection: OnSelectionChangeParams,
|
||||||
edges: Edge[],
|
edges: Edge[]
|
||||||
): Array<string> {
|
): Array<string> {
|
||||||
const clonedSelection = cloneDeep(selection);
|
const clonedSelection = cloneDeep(selection);
|
||||||
const clonedEdges = cloneDeep(edges);
|
const clonedEdges = cloneDeep(edges);
|
||||||
|
|
@ -752,7 +752,7 @@ export function validateSelection(
|
||||||
let nodesSet = new Set(clonedSelection.nodes.map((n) => n.id));
|
let nodesSet = new Set(clonedSelection.nodes.map((n) => n.id));
|
||||||
// then filter the edges that are connected to the nodes in the set
|
// then filter the edges that are connected to the nodes in the set
|
||||||
let connectedEdges = clonedSelection.edges.filter(
|
let connectedEdges = clonedSelection.edges.filter(
|
||||||
(e) => nodesSet.has(e.source) && nodesSet.has(e.target),
|
(e) => nodesSet.has(e.source) && nodesSet.has(e.target)
|
||||||
);
|
);
|
||||||
// add the edges to the selection
|
// add the edges to the selection
|
||||||
clonedSelection.edges = connectedEdges;
|
clonedSelection.edges = connectedEdges;
|
||||||
|
|
@ -766,17 +766,17 @@ export function validateSelection(
|
||||||
clonedSelection.nodes.some(
|
clonedSelection.nodes.some(
|
||||||
(node) =>
|
(node) =>
|
||||||
isInputNode(node.data as NodeDataType) ||
|
isInputNode(node.data as NodeDataType) ||
|
||||||
isOutputNode(node.data as NodeDataType),
|
isOutputNode(node.data as NodeDataType)
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
errorsArray.push(
|
errorsArray.push(
|
||||||
"Please select only nodes that are not input or output nodes",
|
"Please select only nodes that are not input or output nodes"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
//check if there are two or more nodes with free outputs
|
//check if there are two or more nodes with free outputs
|
||||||
if (
|
if (
|
||||||
clonedSelection.nodes.filter(
|
clonedSelection.nodes.filter(
|
||||||
(n) => !clonedSelection.edges.some((e) => e.source === n.id),
|
(n) => !clonedSelection.edges.some((e) => e.source === n.id)
|
||||||
).length > 1
|
).length > 1
|
||||||
) {
|
) {
|
||||||
errorsArray.push("Please select only one node with free outputs");
|
errorsArray.push("Please select only one node with free outputs");
|
||||||
|
|
@ -787,7 +787,7 @@ export function validateSelection(
|
||||||
clonedSelection.nodes.some(
|
clonedSelection.nodes.some(
|
||||||
(node) =>
|
(node) =>
|
||||||
!clonedSelection.edges.some((edge) => edge.target === node.id) &&
|
!clonedSelection.edges.some((edge) => edge.target === node.id) &&
|
||||||
!clonedSelection.edges.some((edge) => edge.source === node.id),
|
!clonedSelection.edges.some((edge) => edge.source === node.id)
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
errorsArray.push("Please select only nodes that are connected");
|
errorsArray.push("Please select only nodes that are connected");
|
||||||
|
|
@ -844,8 +844,8 @@ export function mergeNodeTemplates({
|
||||||
nodeTemplate[key].display_name
|
nodeTemplate[key].display_name
|
||||||
? nodeTemplate[key].display_name
|
? nodeTemplate[key].display_name
|
||||||
: nodeTemplate[key].name
|
: nodeTemplate[key].name
|
||||||
? toTitleCase(nodeTemplate[key].name)
|
? toTitleCase(nodeTemplate[key].name)
|
||||||
: toTitleCase(key);
|
: toTitleCase(key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -856,7 +856,7 @@ function isHandleConnected(
|
||||||
edges: Edge[],
|
edges: Edge[],
|
||||||
key: string,
|
key: string,
|
||||||
field: TemplateVariableType,
|
field: TemplateVariableType,
|
||||||
nodeId: string,
|
nodeId: string
|
||||||
) {
|
) {
|
||||||
/*
|
/*
|
||||||
this function receives a flow and a handleId and check if there is a connection with this handle
|
this function receives a flow and a handleId and check if there is a connection with this handle
|
||||||
|
|
@ -872,7 +872,7 @@ function isHandleConnected(
|
||||||
id: nodeId,
|
id: nodeId,
|
||||||
proxy: { id: field.proxy!.id, field: field.proxy!.field },
|
proxy: { id: field.proxy!.id, field: field.proxy!.field },
|
||||||
inputTypes: field.input_types,
|
inputTypes: field.input_types,
|
||||||
} as targetHandleType),
|
} as targetHandleType)
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -887,7 +887,7 @@ function isHandleConnected(
|
||||||
fieldName: key,
|
fieldName: key,
|
||||||
id: nodeId,
|
id: nodeId,
|
||||||
inputTypes: field.input_types,
|
inputTypes: field.input_types,
|
||||||
} as targetHandleType),
|
} as targetHandleType)
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -910,7 +910,7 @@ export function generateNodeTemplate(Flow: FlowType) {
|
||||||
|
|
||||||
export function generateNodeFromFlow(
|
export function generateNodeFromFlow(
|
||||||
flow: FlowType,
|
flow: FlowType,
|
||||||
getNodeId: (type: string) => string,
|
getNodeId: (type: string) => string
|
||||||
): NodeType {
|
): NodeType {
|
||||||
const { nodes } = flow.data!;
|
const { nodes } = flow.data!;
|
||||||
const outputNode = cloneDeep(findLastNode(flow.data!));
|
const outputNode = cloneDeep(findLastNode(flow.data!));
|
||||||
|
|
@ -941,7 +941,7 @@ export function generateNodeFromFlow(
|
||||||
export function connectedInputNodesOnHandle(
|
export function connectedInputNodesOnHandle(
|
||||||
nodeId: string,
|
nodeId: string,
|
||||||
handleId: string,
|
handleId: string,
|
||||||
{ nodes, edges }: { nodes: NodeType[]; edges: Edge[] },
|
{ nodes, edges }: { nodes: NodeType[]; edges: Edge[] }
|
||||||
) {
|
) {
|
||||||
const connectedNodes: Array<{ name: string; id: string; isGroup: boolean }> =
|
const connectedNodes: Array<{ name: string; id: string; isGroup: boolean }> =
|
||||||
[];
|
[];
|
||||||
|
|
@ -978,7 +978,7 @@ export function connectedInputNodesOnHandle(
|
||||||
|
|
||||||
export function updateProxyIdsOnTemplate(
|
export function updateProxyIdsOnTemplate(
|
||||||
template: APITemplateType,
|
template: APITemplateType,
|
||||||
idsMap: { [key: string]: string },
|
idsMap: { [key: string]: string }
|
||||||
) {
|
) {
|
||||||
Object.keys(template).forEach((key) => {
|
Object.keys(template).forEach((key) => {
|
||||||
if (template[key].proxy && idsMap[template[key].proxy!.id]) {
|
if (template[key].proxy && idsMap[template[key].proxy!.id]) {
|
||||||
|
|
@ -989,7 +989,7 @@ export function updateProxyIdsOnTemplate(
|
||||||
|
|
||||||
export function updateEdgesIds(
|
export function updateEdgesIds(
|
||||||
edges: Edge[],
|
edges: Edge[],
|
||||||
idsMap: { [key: string]: string },
|
idsMap: { [key: string]: string }
|
||||||
) {
|
) {
|
||||||
edges.forEach((edge) => {
|
edges.forEach((edge) => {
|
||||||
let targetHandle: targetHandleType = edge.data.targetHandle;
|
let targetHandle: targetHandleType = edge.data.targetHandle;
|
||||||
|
|
@ -1021,7 +1021,7 @@ export function expandGroupNode(
|
||||||
nodes: Node[],
|
nodes: Node[],
|
||||||
edges: Edge[],
|
edges: Edge[],
|
||||||
setNodes: (update: Node[] | ((oldState: Node[]) => Node[])) => void,
|
setNodes: (update: Node[] | ((oldState: Node[]) => Node[])) => void,
|
||||||
setEdges: (update: Edge[] | ((oldState: Edge[]) => Edge[])) => void,
|
setEdges: (update: Edge[] | ((oldState: Edge[]) => Edge[])) => void
|
||||||
) {
|
) {
|
||||||
const idsMap = updateIds(flow!.data!);
|
const idsMap = updateIds(flow!.data!);
|
||||||
updateProxyIdsOnTemplate(template, idsMap);
|
updateProxyIdsOnTemplate(template, idsMap);
|
||||||
|
|
@ -1064,7 +1064,7 @@ export function expandGroupNode(
|
||||||
const lastNode = cloneDeep(findLastNode(flow!.data!));
|
const lastNode = cloneDeep(findLastNode(flow!.data!));
|
||||||
newEdge.source = lastNode!.id;
|
newEdge.source = lastNode!.id;
|
||||||
let newSourceHandle: sourceHandleType = scapeJSONParse(
|
let newSourceHandle: sourceHandleType = scapeJSONParse(
|
||||||
newEdge.sourceHandle!,
|
newEdge.sourceHandle!
|
||||||
);
|
);
|
||||||
newSourceHandle.id = lastNode!.id;
|
newSourceHandle.id = lastNode!.id;
|
||||||
newEdge.data.sourceHandle = newSourceHandle;
|
newEdge.data.sourceHandle = newSourceHandle;
|
||||||
|
|
@ -1121,7 +1121,7 @@ export function expandGroupNode(
|
||||||
|
|
||||||
export function getGroupStatus(
|
export function getGroupStatus(
|
||||||
flow: FlowType,
|
flow: FlowType,
|
||||||
ssData: { [key: string]: { valid: boolean; params: string } },
|
ssData: { [key: string]: { valid: boolean; params: string } }
|
||||||
) {
|
) {
|
||||||
let status = { valid: true, params: SUCCESS_BUILD };
|
let status = { valid: true, params: SUCCESS_BUILD };
|
||||||
const { nodes } = flow.data!;
|
const { nodes } = flow.data!;
|
||||||
|
|
@ -1140,7 +1140,7 @@ export function getGroupStatus(
|
||||||
|
|
||||||
export function createFlowComponent(
|
export function createFlowComponent(
|
||||||
nodeData: NodeDataType,
|
nodeData: NodeDataType,
|
||||||
version: string,
|
version: string
|
||||||
): FlowType {
|
): FlowType {
|
||||||
const flowNode: FlowType = {
|
const flowNode: FlowType = {
|
||||||
data: {
|
data: {
|
||||||
|
|
@ -1176,7 +1176,7 @@ export function downloadNode(NodeFLow: FlowType) {
|
||||||
|
|
||||||
export function updateComponentNameAndType(
|
export function updateComponentNameAndType(
|
||||||
data: any,
|
data: any,
|
||||||
component: NodeDataType,
|
component: NodeDataType
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
export function removeFileNameFromComponents(flow: FlowType) {
|
export function removeFileNameFromComponents(flow: FlowType) {
|
||||||
|
|
@ -1250,7 +1250,7 @@ export function extractFieldsFromComponenents(data: APIObjectType) {
|
||||||
export function downloadFlow(
|
export function downloadFlow(
|
||||||
flow: FlowType,
|
flow: FlowType,
|
||||||
flowName: string,
|
flowName: string,
|
||||||
flowDescription?: string,
|
flowDescription?: string
|
||||||
) {
|
) {
|
||||||
let clonedFlow = cloneDeep(flow);
|
let clonedFlow = cloneDeep(flow);
|
||||||
removeFileNameFromComponents(clonedFlow);
|
removeFileNameFromComponents(clonedFlow);
|
||||||
|
|
@ -1260,7 +1260,7 @@ export function downloadFlow(
|
||||||
...clonedFlow,
|
...clonedFlow,
|
||||||
name: flowName,
|
name: flowName,
|
||||||
description: flowDescription,
|
description: flowDescription,
|
||||||
}),
|
})
|
||||||
)}`;
|
)}`;
|
||||||
|
|
||||||
// create a link element and set its properties
|
// create a link element and set its properties
|
||||||
|
|
@ -1275,7 +1275,7 @@ export function downloadFlow(
|
||||||
export function downloadFlows() {
|
export function downloadFlows() {
|
||||||
downloadFlowsFromDatabase().then((flows) => {
|
downloadFlowsFromDatabase().then((flows) => {
|
||||||
const jsonString = `data:text/json;chatset=utf-8,${encodeURIComponent(
|
const jsonString = `data:text/json;chatset=utf-8,${encodeURIComponent(
|
||||||
JSON.stringify(flows),
|
JSON.stringify(flows)
|
||||||
)}`;
|
)}`;
|
||||||
|
|
||||||
// create a link element and set its properties
|
// create a link element and set its properties
|
||||||
|
|
@ -1290,7 +1290,7 @@ export function downloadFlows() {
|
||||||
|
|
||||||
export const createNewFlow = (
|
export const createNewFlow = (
|
||||||
flowData: ReactFlowJsonObject,
|
flowData: ReactFlowJsonObject,
|
||||||
flow: FlowType,
|
flow: FlowType
|
||||||
) => {
|
) => {
|
||||||
return {
|
return {
|
||||||
description: flow?.description ?? getRandomDescription(),
|
description: flow?.description ?? getRandomDescription(),
|
||||||
|
|
|
||||||
|
|
@ -7,15 +7,14 @@ export default function cloneFLowWithParent(
|
||||||
flow: FlowType,
|
flow: FlowType,
|
||||||
parent: string,
|
parent: string,
|
||||||
is_component: boolean,
|
is_component: boolean,
|
||||||
keepId=false
|
keepId = false
|
||||||
) {
|
) {
|
||||||
let childFLow = cloneDeep(flow);
|
let childFLow = cloneDeep(flow);
|
||||||
childFLow.parent = parent;
|
childFLow.parent = parent;
|
||||||
if(!keepId){
|
if (!keepId) {
|
||||||
childFLow.id = "";
|
childFLow.id = "";
|
||||||
}
|
} else {
|
||||||
else{
|
childFLow.id = uniqueId() + "-" + childFLow.id;
|
||||||
childFLow.id = uniqueId()+"-"+childFLow.id;
|
|
||||||
}
|
}
|
||||||
childFLow.is_component = is_component;
|
childFLow.is_component = is_component;
|
||||||
return childFLow;
|
return childFLow;
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,6 @@ import orjson
|
||||||
import pytest
|
import pytest
|
||||||
from fastapi.testclient import TestClient
|
from fastapi.testclient import TestClient
|
||||||
from httpx import AsyncClient
|
from httpx import AsyncClient
|
||||||
from sqlmodel import Session, SQLModel, create_engine, select
|
|
||||||
from langflow.graph.graph.base import Graph
|
from langflow.graph.graph.base import Graph
|
||||||
from langflow.initial_setup.setup import STARTER_FOLDER_NAME
|
from langflow.initial_setup.setup import STARTER_FOLDER_NAME
|
||||||
from langflow.services.auth.utils import get_password_hash
|
from langflow.services.auth.utils import get_password_hash
|
||||||
|
|
@ -19,6 +18,7 @@ from langflow.services.database.models.flow.model import Flow, FlowCreate
|
||||||
from langflow.services.database.models.user.model import User, UserCreate
|
from langflow.services.database.models.user.model import User, UserCreate
|
||||||
from langflow.services.database.utils import session_getter
|
from langflow.services.database.utils import session_getter
|
||||||
from langflow.services.deps import get_db_service
|
from langflow.services.deps import get_db_service
|
||||||
|
from sqlmodel import Session, SQLModel, create_engine, select
|
||||||
from sqlmodel.pool import StaticPool
|
from sqlmodel.pool import StaticPool
|
||||||
from typer.testing import CliRunner
|
from typer.testing import CliRunner
|
||||||
|
|
||||||
|
|
@ -26,7 +26,8 @@ if TYPE_CHECKING:
|
||||||
from langflow.services.database.service import DatabaseService
|
from langflow.services.database.service import DatabaseService
|
||||||
|
|
||||||
|
|
||||||
def pytest_configure():
|
def pytest_configure(config):
|
||||||
|
config.addinivalue_line("markers", "noclient: don't create a client for this test")
|
||||||
data_path = Path(__file__).parent.absolute() / "data"
|
data_path = Path(__file__).parent.absolute() / "data"
|
||||||
|
|
||||||
pytest.BASIC_EXAMPLE_PATH = data_path / "basic_example.json"
|
pytest.BASIC_EXAMPLE_PATH = data_path / "basic_example.json"
|
||||||
|
|
|
||||||
|
|
@ -407,7 +407,7 @@ def test_update_source_handle():
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
async def test_pickle_graph(json_vector_store):
|
async def test_pickle_graph():
|
||||||
starter_projects = load_starter_projects()
|
starter_projects = load_starter_projects()
|
||||||
data = starter_projects[0][1]["data"]
|
data = starter_projects[0][1]["data"]
|
||||||
graph = Graph.from_payload(data)
|
graph = Graph.from_payload(data)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue