merge fix
This commit is contained in:
commit
686a07faaa
156 changed files with 1698 additions and 1641 deletions
|
|
@ -36,7 +36,6 @@
|
||||||
|
|
||||||
# 📝 Conteúdo
|
# 📝 Conteúdo
|
||||||
|
|
||||||
- [](#)
|
|
||||||
- [📝 Conteúdo](#-conteúdo)
|
- [📝 Conteúdo](#-conteúdo)
|
||||||
- [📦 Introdução](#-introdução)
|
- [📦 Introdução](#-introdução)
|
||||||
- [🎨 Criar Fluxos](#-criar-fluxos)
|
- [🎨 Criar Fluxos](#-criar-fluxos)
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@
|
||||||
|
|
||||||
<div align="center">
|
<div align="center">
|
||||||
<a href="./README.md"><img alt="README in English" src="https://img.shields.io/badge/English-d9d9d9"></a>
|
<a href="./README.md"><img alt="README in English" src="https://img.shields.io/badge/English-d9d9d9"></a>
|
||||||
|
<a href="./README.PT.md"><img alt="README in Portuguese" src="https://img.shields.io/badge/Portuguese-d9d9d9"></a>
|
||||||
<a href="./README.zh_CN.md"><img alt="README in Simplified Chinese" src="https://img.shields.io/badge/简体中文-d9d9d9"></a>
|
<a href="./README.zh_CN.md"><img alt="README in Simplified Chinese" src="https://img.shields.io/badge/简体中文-d9d9d9"></a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
||||||
44
poetry.lock
generated
44
poetry.lock
generated
|
|
@ -4058,19 +4058,19 @@ text-helpers = ["chardet (>=5.1.0,<6.0.0)"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "langchain-anthropic"
|
name = "langchain-anthropic"
|
||||||
version = "0.1.15"
|
version = "0.1.13"
|
||||||
description = "An integration package connecting AnthropicMessages and LangChain"
|
description = "An integration package connecting AnthropicMessages and LangChain"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = "<4.0,>=3.8.1"
|
python-versions = "<4.0,>=3.8.1"
|
||||||
files = [
|
files = [
|
||||||
{file = "langchain_anthropic-0.1.15-py3-none-any.whl", hash = "sha256:7cceea526f473e4d514f39295dc128eec57da628a4bbb54850d11dda7aa959fc"},
|
{file = "langchain_anthropic-0.1.13-py3-none-any.whl", hash = "sha256:121f6f480da7685c239573d98322adb94fe486d40651ac341637f65da36881de"},
|
||||||
{file = "langchain_anthropic-0.1.15.tar.gz", hash = "sha256:c5c3c6eaccb11ed99a63886e50873ac21eaf8e9441e0f75c7ae7cd8cdef65155"},
|
{file = "langchain_anthropic-0.1.13.tar.gz", hash = "sha256:32e7ac51e1874c47e1a20493e75f5bfc88b0ffeaf5f1aed6091547e1ae44bb85"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
anthropic = ">=0.28.0,<1"
|
anthropic = ">=0.26.0,<1"
|
||||||
defusedxml = ">=0.7.1,<0.8.0"
|
defusedxml = ">=0.7.1,<0.8.0"
|
||||||
langchain-core = ">=0.2.2rc1,<0.3"
|
langchain-core = ">=0.1.43,<0.3"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "langchain-astradb"
|
name = "langchain-astradb"
|
||||||
|
|
@ -6844,7 +6844,7 @@ files = [
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
pydantic = ">=2.7.0"
|
pydantic = ">=2.3.0"
|
||||||
python-dotenv = ">=0.21.0"
|
python-dotenv = ">=0.21.0"
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
|
|
@ -9013,13 +9013,13 @@ types-pyOpenSSL = "*"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "types-requests"
|
name = "types-requests"
|
||||||
version = "2.32.0.20240602"
|
version = "2.32.0.20240523"
|
||||||
description = "Typing stubs for requests"
|
description = "Typing stubs for requests"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.8"
|
python-versions = ">=3.8"
|
||||||
files = [
|
files = [
|
||||||
{file = "types-requests-2.32.0.20240602.tar.gz", hash = "sha256:3f98d7bbd0dd94ebd10ff43a7fbe20c3b8528acace6d8efafef0b6a184793f06"},
|
{file = "types-requests-2.32.0.20240523.tar.gz", hash = "sha256:26b8a6de32d9f561192b9942b41c0ab2d8010df5677ca8aa146289d11d505f57"},
|
||||||
{file = "types_requests-2.32.0.20240602-py3-none-any.whl", hash = "sha256:ed3946063ea9fbc6b5fc0c44fa279188bae42d582cb63760be6cb4b9d06c3de8"},
|
{file = "types_requests-2.32.0.20240523-py3-none-any.whl", hash = "sha256:f19ed0e2daa74302069bbbbf9e82902854ffa780bc790742a810a9aaa52f65ec"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
|
|
@ -9038,13 +9038,13 @@ files = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "typing-extensions"
|
name = "typing-extensions"
|
||||||
version = "4.12.1"
|
version = "4.12.0"
|
||||||
description = "Backported and Experimental Type Hints for Python 3.8+"
|
description = "Backported and Experimental Type Hints for Python 3.8+"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.8"
|
python-versions = ">=3.8"
|
||||||
files = [
|
files = [
|
||||||
{file = "typing_extensions-4.12.1-py3-none-any.whl", hash = "sha256:6024b58b69089e5a89c347397254e35f1bf02a907728ec7fee9bf0fe837d203a"},
|
{file = "typing_extensions-4.12.0-py3-none-any.whl", hash = "sha256:b349c66bea9016ac22978d800cfff206d5f9816951f12a7d0ec5578b0a819594"},
|
||||||
{file = "typing_extensions-4.12.1.tar.gz", hash = "sha256:915f5e35ff76f56588223f15fdd5938f9a1cf9195c0de25130c627e4d597f6d1"},
|
{file = "typing_extensions-4.12.0.tar.gz", hash = "sha256:8cbcdc8606ebcb0d95453ad7dc5065e6237b6aa230a31e81d0f440c30fed5fd8"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -9230,13 +9230,13 @@ files = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "uvicorn"
|
name = "uvicorn"
|
||||||
version = "0.30.1"
|
version = "0.29.0"
|
||||||
description = "The lightning-fast ASGI server."
|
description = "The lightning-fast ASGI server."
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.8"
|
python-versions = ">=3.8"
|
||||||
files = [
|
files = [
|
||||||
{file = "uvicorn-0.30.1-py3-none-any.whl", hash = "sha256:cd17daa7f3b9d7a24de3617820e634d0933b69eed8e33a516071174427238c81"},
|
{file = "uvicorn-0.29.0-py3-none-any.whl", hash = "sha256:2c2aac7ff4f4365c206fd773a39bf4ebd1047c238f8b8268ad996829323473de"},
|
||||||
{file = "uvicorn-0.30.1.tar.gz", hash = "sha256:d46cd8e0fd80240baffbcd9ec1012a712938754afcf81bce56c024c1656aece8"},
|
{file = "uvicorn-0.29.0.tar.gz", hash = "sha256:6a69214c0b6a087462412670b3ef21224fa48cae0e452b5883e8e8bdfdd11dd0"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
|
|
@ -9300,13 +9300,13 @@ test = ["Cython (>=0.29.36,<0.30.0)", "aiohttp (==3.9.0b0)", "aiohttp (>=3.8.1)"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "validators"
|
name = "validators"
|
||||||
version = "0.28.3"
|
version = "0.28.1"
|
||||||
description = "Python Data Validation for Humans™"
|
description = "Python Data Validation for Humans™"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.8"
|
python-versions = ">=3.8"
|
||||||
files = [
|
files = [
|
||||||
{file = "validators-0.28.3-py3-none-any.whl", hash = "sha256:53cafa854f13850156259d9cc479b864ee901f6a96e6b109e6fc33f98f37d99f"},
|
{file = "validators-0.28.1-py3-none-any.whl", hash = "sha256:890c98789ad884037f059af6ea915ec2d667129d509180c2c590b8009a4c4219"},
|
||||||
{file = "validators-0.28.3.tar.gz", hash = "sha256:c6c79840bcde9ba77b19f6218f7738188115e27830cbaff43264bc4ed24c429d"},
|
{file = "validators-0.28.1.tar.gz", hash = "sha256:5ac88e7916c3405f0ce38ac2ac82a477fcf4d90dbbeddd04c8193171fc17f7dc"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -9454,13 +9454,13 @@ files = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "weaviate-client"
|
name = "weaviate-client"
|
||||||
version = "4.6.4"
|
version = "4.6.3"
|
||||||
description = "A python native Weaviate client"
|
description = "A python native Weaviate client"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.8"
|
python-versions = ">=3.8"
|
||||||
files = [
|
files = [
|
||||||
{file = "weaviate_client-4.6.4-py3-none-any.whl", hash = "sha256:19b76fb923a5f0b6fcb7471ef3cd990d2791ede71731e53429e1066a9dbf2af2"},
|
{file = "weaviate_client-4.6.3-py3-none-any.whl", hash = "sha256:b2921f9aea84a4eccb1c75d55dd2857a87241e5536540fb96ffdf4737ed4fe8a"},
|
||||||
{file = "weaviate_client-4.6.4.tar.gz", hash = "sha256:5378db8a33bf1d48adff3f9efa572d9fb04eaeb36444817cab56f1ba3c595500"},
|
{file = "weaviate_client-4.6.3.tar.gz", hash = "sha256:a6e638f746f91c310fe6680cffa77949718f17d8b40b966f7037028cacfd94e0"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
|
|
@ -9471,7 +9471,7 @@ grpcio-tools = ">=1.57.0,<2.0.0"
|
||||||
httpx = ">=0.25.0,<=0.27.0"
|
httpx = ">=0.25.0,<=0.27.0"
|
||||||
pydantic = ">=2.5.0,<3.0.0"
|
pydantic = ">=2.5.0,<3.0.0"
|
||||||
requests = ">=2.30.0,<3.0.0"
|
requests = ">=2.30.0,<3.0.0"
|
||||||
validators = "0.28.3"
|
validators = "0.28.1"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "websocket-client"
|
name = "websocket-client"
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ if not space:
|
||||||
print("Please provide a space to restart.")
|
print("Please provide a space to restart.")
|
||||||
exit()
|
exit()
|
||||||
|
|
||||||
if not parsed_args.api_token:
|
if not parsed_args.token:
|
||||||
print("Please provide an API token.")
|
print("Please provide an API token.")
|
||||||
exit()
|
exit()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -71,9 +71,7 @@ async def login_to_get_access_token(
|
||||||
|
|
||||||
@router.get("/auto_login")
|
@router.get("/auto_login")
|
||||||
async def auto_login(
|
async def auto_login(
|
||||||
response: Response,
|
response: Response, db: Session = Depends(get_session), settings_service=Depends(get_settings_service)
|
||||||
db: Session = Depends(get_session),
|
|
||||||
settings_service=Depends(get_settings_service)
|
|
||||||
):
|
):
|
||||||
auth_settings = settings_service.auth_settings
|
auth_settings = settings_service.auth_settings
|
||||||
if settings_service.auth_settings.AUTO_LOGIN:
|
if settings_service.auth_settings.AUTO_LOGIN:
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
from typing import List, Optional
|
from typing import List, Optional
|
||||||
from uuid import UUID
|
|
||||||
from fastapi import APIRouter, Depends, HTTPException, Query
|
from fastapi import APIRouter, Depends, HTTPException, Query
|
||||||
|
|
||||||
from langflow.services.deps import get_monitor_service
|
from langflow.services.deps import get_monitor_service
|
||||||
|
|
|
||||||
|
|
@ -15,10 +15,25 @@ import shlex
|
||||||
from collections import OrderedDict, namedtuple
|
from collections import OrderedDict, namedtuple
|
||||||
from http.cookies import SimpleCookie
|
from http.cookies import SimpleCookie
|
||||||
|
|
||||||
from uncurl.api import parser # type: ignore
|
ParsedArgs = namedtuple(
|
||||||
|
"ParsedContext",
|
||||||
parser.add_argument("-x", "--proxy", default={})
|
[
|
||||||
parser.add_argument("-U", "--proxy-user", default="")
|
"command",
|
||||||
|
"url",
|
||||||
|
"data",
|
||||||
|
"data_binary",
|
||||||
|
"method",
|
||||||
|
"headers",
|
||||||
|
"compressed",
|
||||||
|
"insecure",
|
||||||
|
"user",
|
||||||
|
"include",
|
||||||
|
"silent",
|
||||||
|
"proxy",
|
||||||
|
"proxy_user",
|
||||||
|
"cookies",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
ParsedContext = namedtuple("ParsedContext", ["method", "url", "data", "headers", "cookies", "verify", "auth", "proxy"])
|
ParsedContext = namedtuple("ParsedContext", ["method", "url", "data", "headers", "cookies", "verify", "auth", "proxy"])
|
||||||
|
|
||||||
|
|
@ -27,24 +42,89 @@ def normalize_newlines(multiline_text):
|
||||||
return multiline_text.replace(" \\\n", " ")
|
return multiline_text.replace(" \\\n", " ")
|
||||||
|
|
||||||
|
|
||||||
|
def parse_curl_command(curl_command):
|
||||||
|
tokens = shlex.split(normalize_newlines(curl_command))
|
||||||
|
tokens = [token for token in tokens if token and token != " "]
|
||||||
|
if "curl" not in tokens[0]:
|
||||||
|
raise ValueError("Invalid curl command")
|
||||||
|
args_template = {
|
||||||
|
"command": None,
|
||||||
|
"url": None,
|
||||||
|
"data": None,
|
||||||
|
"data_binary": None,
|
||||||
|
"method": "get",
|
||||||
|
"headers": [],
|
||||||
|
"compressed": False,
|
||||||
|
"insecure": False,
|
||||||
|
"user": (),
|
||||||
|
"include": False,
|
||||||
|
"silent": False,
|
||||||
|
"proxy": None,
|
||||||
|
"proxy_user": None,
|
||||||
|
"cookies": {},
|
||||||
|
}
|
||||||
|
args = args_template.copy()
|
||||||
|
|
||||||
|
i = 0
|
||||||
|
while i < len(tokens):
|
||||||
|
token = tokens[i]
|
||||||
|
if token == "-X":
|
||||||
|
i += 1
|
||||||
|
args["method"] = tokens[i].lower()
|
||||||
|
elif token in ("-d", "--data"):
|
||||||
|
i += 1
|
||||||
|
args["data"] = tokens[i]
|
||||||
|
args["method"] = "post"
|
||||||
|
elif token in ("-b", "--data-binary", "--data-raw"):
|
||||||
|
i += 1
|
||||||
|
args["data_binary"] = tokens[i]
|
||||||
|
args["method"] = "post"
|
||||||
|
elif token in ("-H", "--header"):
|
||||||
|
i += 1
|
||||||
|
args["headers"].append(tokens[i])
|
||||||
|
elif token == "--compressed":
|
||||||
|
args["compressed"] = True
|
||||||
|
elif token in ("-k", "--insecure"):
|
||||||
|
args["insecure"] = True
|
||||||
|
elif token in ("-u", "--user"):
|
||||||
|
i += 1
|
||||||
|
args["user"] = tuple(tokens[i].split(":"))
|
||||||
|
elif token in ("-I", "--include"):
|
||||||
|
args["include"] = True
|
||||||
|
elif token in ("-s", "--silent"):
|
||||||
|
args["silent"] = True
|
||||||
|
elif token in ("-x", "--proxy"):
|
||||||
|
i += 1
|
||||||
|
args["proxy"] = tokens[i]
|
||||||
|
elif token in ("-U", "--proxy-user"):
|
||||||
|
i += 1
|
||||||
|
args["proxy_user"] = tokens[i]
|
||||||
|
elif not token.startswith("-"):
|
||||||
|
if args["command"] is None:
|
||||||
|
args["command"] = token
|
||||||
|
else:
|
||||||
|
args["url"] = token
|
||||||
|
i += 1
|
||||||
|
|
||||||
|
return ParsedArgs(**args)
|
||||||
|
|
||||||
|
|
||||||
def parse_context(curl_command):
|
def parse_context(curl_command):
|
||||||
method = "get"
|
method = "get"
|
||||||
|
|
||||||
tokens = shlex.split(normalize_newlines(curl_command))
|
parsed_args: ParsedArgs = parse_curl_command(curl_command)
|
||||||
tokens = [token for token in tokens if token and token != " "]
|
|
||||||
parsed_args = parser.parse_args(tokens)
|
|
||||||
|
|
||||||
post_data = parsed_args.data or parsed_args.data_binary
|
post_data = parsed_args.data or parsed_args.data_binary
|
||||||
if post_data:
|
if post_data:
|
||||||
method = "post"
|
method = "post"
|
||||||
|
|
||||||
if parsed_args.X:
|
if parsed_args.method:
|
||||||
method = parsed_args.X.lower()
|
method = parsed_args.method.lower()
|
||||||
|
|
||||||
cookie_dict = OrderedDict()
|
cookie_dict = OrderedDict()
|
||||||
quoted_headers = OrderedDict()
|
quoted_headers = OrderedDict()
|
||||||
|
|
||||||
for curl_header in parsed_args.header:
|
for curl_header in parsed_args.headers:
|
||||||
if curl_header.startswith(":"):
|
if curl_header.startswith(":"):
|
||||||
occurrence = [m.start() for m in re.finditer(":", curl_header)]
|
occurrence = [m.start() for m in re.finditer(":", curl_header)]
|
||||||
header_key, header_value = curl_header[: occurrence[1]], curl_header[occurrence[1] + 1 :]
|
header_key, header_value = curl_header[: occurrence[1]], curl_header[occurrence[1] + 1 :]
|
||||||
|
|
|
||||||
|
|
@ -99,7 +99,7 @@ def read_text_file(file_path: str) -> str:
|
||||||
with open(file_path, "rb") as f:
|
with open(file_path, "rb") as f:
|
||||||
raw_data = f.read()
|
raw_data = f.read()
|
||||||
result = chardet.detect(raw_data)
|
result = chardet.detect(raw_data)
|
||||||
encoding = result['encoding']
|
encoding = result["encoding"]
|
||||||
|
|
||||||
with open(file_path, "r", encoding=encoding) as f:
|
with open(file_path, "r", encoding=encoding) as f:
|
||||||
return f.read()
|
return f.read()
|
||||||
|
|
|
||||||
|
|
@ -90,7 +90,9 @@ async def run_flow(
|
||||||
|
|
||||||
fallback_to_env_vars = get_settings_service().settings.fallback_to_env_var
|
fallback_to_env_vars = get_settings_service().settings.fallback_to_env_var
|
||||||
|
|
||||||
return await graph.arun(inputs_list, inputs_components=inputs_components, types=types, fallback_to_env_vars=fallback_to_env_vars)
|
return await graph.arun(
|
||||||
|
inputs_list, inputs_components=inputs_components, types=types, fallback_to_env_vars=fallback_to_env_vars
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def generate_function_for_flow(
|
def generate_function_for_flow(
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ from langflow.services.database.models.user.crud import get_user_by_username
|
||||||
from langflow.services.deps import get_settings_service, session_scope
|
from langflow.services.deps import get_settings_service, session_scope
|
||||||
|
|
||||||
from langflow.services.database.models.folder.utils import create_default_folder_if_it_doesnt_exist
|
from langflow.services.database.models.folder.utils import create_default_folder_if_it_doesnt_exist
|
||||||
from langflow.services.deps import get_settings_service, session_scope, get_variable_service
|
from langflow.services.deps import get_variable_service
|
||||||
|
|
||||||
|
|
||||||
STARTER_FOLDER_NAME = "Starter Projects"
|
STARTER_FOLDER_NAME = "Starter Projects"
|
||||||
|
|
@ -221,6 +221,7 @@ def _is_valid_uuid(val):
|
||||||
return False
|
return False
|
||||||
return str(uuid_obj) == val
|
return str(uuid_obj) == val
|
||||||
|
|
||||||
|
|
||||||
def load_flows_from_directory():
|
def load_flows_from_directory():
|
||||||
settings_service = get_settings_service()
|
settings_service = get_settings_service()
|
||||||
flows_path = settings_service.settings.load_flows_path
|
flows_path = settings_service.settings.load_flows_path
|
||||||
|
|
@ -262,6 +263,7 @@ def load_flows_from_directory():
|
||||||
session.add(flow)
|
session.add(flow)
|
||||||
session.commit()
|
session.commit()
|
||||||
|
|
||||||
|
|
||||||
def find_existing_flow(session, flow_id, flow_endpoint_name):
|
def find_existing_flow(session, flow_id, flow_endpoint_name):
|
||||||
if flow_endpoint_name:
|
if flow_endpoint_name:
|
||||||
stmt = select(Flow).where(Flow.endpoint_name == flow_endpoint_name)
|
stmt = select(Flow).where(Flow.endpoint_name == flow_endpoint_name)
|
||||||
|
|
@ -271,6 +273,8 @@ def find_existing_flow(session, flow_id, flow_endpoint_name):
|
||||||
if existing := session.exec(stmt).first():
|
if existing := session.exec(stmt).first():
|
||||||
return existing
|
return existing
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def create_or_update_starter_projects():
|
def create_or_update_starter_projects():
|
||||||
components_paths = get_settings_service().settings.components_path
|
components_paths = get_settings_service().settings.components_path
|
||||||
try:
|
try:
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,7 @@ async def run_graph_internal(
|
||||||
outputs or [],
|
outputs or [],
|
||||||
stream=stream,
|
stream=stream,
|
||||||
session_id=session_id_str or "",
|
session_id=session_id_str or "",
|
||||||
fallback_to_env_vars=fallback_to_env_vars
|
fallback_to_env_vars=fallback_to_env_vars,
|
||||||
)
|
)
|
||||||
if session_id_str and session_service:
|
if session_id_str and session_service:
|
||||||
await session_service.update_session(session_id_str, (graph, artifacts))
|
await session_service.update_session(session_id_str, (graph, artifacts))
|
||||||
|
|
|
||||||
|
|
@ -215,10 +215,7 @@ def create_user_longterm_token(db: Session = Depends(get_session)) -> tuple[UUID
|
||||||
username = settings_service.auth_settings.SUPERUSER
|
username = settings_service.auth_settings.SUPERUSER
|
||||||
super_user = get_user_by_username(db, username)
|
super_user = get_user_by_username(db, username)
|
||||||
if not super_user:
|
if not super_user:
|
||||||
raise HTTPException(
|
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="Super user hasn't been created")
|
||||||
status_code=status.HTTP_400_BAD_REQUEST,
|
|
||||||
detail="Super user hasn't been created"
|
|
||||||
)
|
|
||||||
access_token_expires_longterm = timedelta(days=365)
|
access_token_expires_longterm = timedelta(days=365)
|
||||||
access_token = create_token(
|
access_token = create_token(
|
||||||
data={"sub": str(super_user.id)},
|
data={"sub": str(super_user.id)},
|
||||||
|
|
|
||||||
|
|
@ -55,6 +55,7 @@ class ApiKeyRead(ApiKeyBase):
|
||||||
id: UUID
|
id: UUID
|
||||||
api_key: str = Field(schema_extra={"validate_default": True})
|
api_key: str = Field(schema_extra={"validate_default": True})
|
||||||
user_id: UUID = Field()
|
user_id: UUID = Field()
|
||||||
|
created_at: datetime = Field()
|
||||||
|
|
||||||
@field_validator("api_key")
|
@field_validator("api_key")
|
||||||
@classmethod
|
@classmethod
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
import os
|
import os
|
||||||
from typing import Optional
|
|
||||||
|
|
||||||
import yaml
|
import yaml
|
||||||
from loguru import logger
|
from loguru import logger
|
||||||
|
|
@ -8,6 +7,7 @@ from langflow.services.base import Service
|
||||||
from langflow.services.settings.auth import AuthSettings
|
from langflow.services.settings.auth import AuthSettings
|
||||||
from langflow.services.settings.base import Settings
|
from langflow.services.settings.base import Settings
|
||||||
|
|
||||||
|
|
||||||
class SettingsService(Service):
|
class SettingsService(Service):
|
||||||
name = "settings_service"
|
name = "settings_service"
|
||||||
|
|
||||||
|
|
|
||||||
17
src/frontend/package-lock.json
generated
17
src/frontend/package-lock.json
generated
|
|
@ -44,6 +44,7 @@
|
||||||
"debounce-promise": "^3.1.2",
|
"debounce-promise": "^3.1.2",
|
||||||
"dompurify": "^3.0.5",
|
"dompurify": "^3.0.5",
|
||||||
"dotenv": "^16.4.5",
|
"dotenv": "^16.4.5",
|
||||||
|
"emoji-regex": "^10.3.0",
|
||||||
"esbuild": "^0.17.19",
|
"esbuild": "^0.17.19",
|
||||||
"file-saver": "^2.0.5",
|
"file-saver": "^2.0.5",
|
||||||
"framer-motion": "^11.0.6",
|
"framer-motion": "^11.0.6",
|
||||||
|
|
@ -5997,9 +5998,9 @@
|
||||||
"integrity": "sha512-NPtACGFe7vunRYzvYqVRhQvsDrTevxpgDKxG/Vcbe0BTNOY+5+/2mOXSw2ls7ToNbE5Bf/+uQbjTxcmwMozpCw=="
|
"integrity": "sha512-NPtACGFe7vunRYzvYqVRhQvsDrTevxpgDKxG/Vcbe0BTNOY+5+/2mOXSw2ls7ToNbE5Bf/+uQbjTxcmwMozpCw=="
|
||||||
},
|
},
|
||||||
"node_modules/emoji-regex": {
|
"node_modules/emoji-regex": {
|
||||||
"version": "8.0.0",
|
"version": "10.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.3.0.tgz",
|
||||||
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
|
"integrity": "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw=="
|
||||||
},
|
},
|
||||||
"node_modules/end-of-stream": {
|
"node_modules/end-of-stream": {
|
||||||
"version": "1.4.4",
|
"version": "1.4.4",
|
||||||
|
|
@ -12205,6 +12206,16 @@
|
||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/string-width-cjs/node_modules/emoji-regex": {
|
||||||
|
"version": "8.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
|
||||||
|
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
|
||||||
|
},
|
||||||
|
"node_modules/string-width/node_modules/emoji-regex": {
|
||||||
|
"version": "8.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
|
||||||
|
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
|
||||||
|
},
|
||||||
"node_modules/strip-ansi": {
|
"node_modules/strip-ansi": {
|
||||||
"version": "6.0.1",
|
"version": "6.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,7 @@
|
||||||
"debounce-promise": "^3.1.2",
|
"debounce-promise": "^3.1.2",
|
||||||
"dompurify": "^3.0.5",
|
"dompurify": "^3.0.5",
|
||||||
"dotenv": "^16.4.5",
|
"dotenv": "^16.4.5",
|
||||||
|
"emoji-regex": "^10.3.0",
|
||||||
"esbuild": "^0.17.19",
|
"esbuild": "^0.17.19",
|
||||||
"file-saver": "^2.0.5",
|
"file-saver": "^2.0.5",
|
||||||
"framer-motion": "^11.0.6",
|
"framer-motion": "^11.0.6",
|
||||||
|
|
|
||||||
|
|
@ -164,3 +164,13 @@ body {
|
||||||
.ag-body-vertical-scroll-viewport::-webkit-scrollbar-thumb:hover {
|
.ag-body-vertical-scroll-viewport::-webkit-scrollbar-thumb:hover {
|
||||||
background-color: #bbb;
|
background-color: #bbb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This CSS is to not apply the border for the column having 'no-border' class */
|
||||||
|
.no-border.ag-cell:focus {
|
||||||
|
border: none !important;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
.no-border.ag-cell {
|
||||||
|
border: none !important;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
import axios from "axios";
|
|
||||||
import { useContext, useEffect, useState } from "react";
|
import { useContext, useEffect, useState } from "react";
|
||||||
import { ErrorBoundary } from "react-error-boundary";
|
import { ErrorBoundary } from "react-error-boundary";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
|
|
@ -30,10 +29,10 @@ export default function App() {
|
||||||
useTrackLastVisitedPath();
|
useTrackLastVisitedPath();
|
||||||
|
|
||||||
const removeFromTempNotificationList = useAlertStore(
|
const removeFromTempNotificationList = useAlertStore(
|
||||||
(state) => state.removeFromTempNotificationList,
|
(state) => state.removeFromTempNotificationList
|
||||||
);
|
);
|
||||||
const tempNotificationList = useAlertStore(
|
const tempNotificationList = useAlertStore(
|
||||||
(state) => state.tempNotificationList,
|
(state) => state.tempNotificationList
|
||||||
);
|
);
|
||||||
const [fetchError, setFetchError] = useState(false);
|
const [fetchError, setFetchError] = useState(false);
|
||||||
const isLoading = useFlowsManagerStore((state) => state.isLoading);
|
const isLoading = useFlowsManagerStore((state) => state.isLoading);
|
||||||
|
|
@ -51,7 +50,7 @@ export default function App() {
|
||||||
const refreshVersion = useDarkStore((state) => state.refreshVersion);
|
const refreshVersion = useDarkStore((state) => state.refreshVersion);
|
||||||
const refreshStars = useDarkStore((state) => state.refreshStars);
|
const refreshStars = useDarkStore((state) => state.refreshStars);
|
||||||
const setGlobalVariables = useGlobalVariablesStore(
|
const setGlobalVariables = useGlobalVariablesStore(
|
||||||
(state) => state.setGlobalVariables,
|
(state) => state.setGlobalVariables
|
||||||
);
|
);
|
||||||
const checkHasStore = useStoreStore((state) => state.checkHasStore);
|
const checkHasStore = useStoreStore((state) => state.checkHasStore);
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
|
||||||
|
|
@ -16,13 +16,13 @@ export default function AlertDropdown({
|
||||||
}: AlertDropdownType): JSX.Element {
|
}: AlertDropdownType): JSX.Element {
|
||||||
const notificationList = useAlertStore((state) => state.notificationList);
|
const notificationList = useAlertStore((state) => state.notificationList);
|
||||||
const clearNotificationList = useAlertStore(
|
const clearNotificationList = useAlertStore(
|
||||||
(state) => state.clearNotificationList,
|
(state) => state.clearNotificationList
|
||||||
);
|
);
|
||||||
const removeFromNotificationList = useAlertStore(
|
const removeFromNotificationList = useAlertStore(
|
||||||
(state) => state.removeFromNotificationList,
|
(state) => state.removeFromNotificationList
|
||||||
);
|
);
|
||||||
const setNotificationCenter = useAlertStore(
|
const setNotificationCenter = useAlertStore(
|
||||||
(state) => state.setNotificationCenter,
|
(state) => state.setNotificationCenter
|
||||||
);
|
);
|
||||||
|
|
||||||
const [open, setOpen] = useState(false);
|
const [open, setOpen] = useState(false);
|
||||||
|
|
|
||||||
|
|
@ -31,14 +31,14 @@ export default function ImageViewer({ image }) {
|
||||||
const fullPageButton = document.getElementById("full-page-button");
|
const fullPageButton = document.getElementById("full-page-button");
|
||||||
|
|
||||||
zoomInButton!.addEventListener("click", () =>
|
zoomInButton!.addEventListener("click", () =>
|
||||||
viewer.viewport.zoomBy(1.2),
|
viewer.viewport.zoomBy(1.2)
|
||||||
);
|
);
|
||||||
zoomOutButton!.addEventListener("click", () =>
|
zoomOutButton!.addEventListener("click", () =>
|
||||||
viewer.viewport.zoomBy(0.8),
|
viewer.viewport.zoomBy(0.8)
|
||||||
);
|
);
|
||||||
homeButton!.addEventListener("click", () => viewer.viewport.goHome());
|
homeButton!.addEventListener("click", () => viewer.viewport.goHome());
|
||||||
fullPageButton!.addEventListener("click", () =>
|
fullPageButton!.addEventListener("click", () =>
|
||||||
viewer.setFullScreen(true),
|
viewer.setFullScreen(true)
|
||||||
);
|
);
|
||||||
|
|
||||||
// Optionally, you can set additional viewer options here
|
// Optionally, you can set additional viewer options here
|
||||||
|
|
@ -47,16 +47,16 @@ export default function ImageViewer({ image }) {
|
||||||
return () => {
|
return () => {
|
||||||
viewer.destroy();
|
viewer.destroy();
|
||||||
zoomInButton!.removeEventListener("click", () =>
|
zoomInButton!.removeEventListener("click", () =>
|
||||||
viewer.viewport.zoomBy(1.2),
|
viewer.viewport.zoomBy(1.2)
|
||||||
);
|
);
|
||||||
zoomOutButton!.removeEventListener("click", () =>
|
zoomOutButton!.removeEventListener("click", () =>
|
||||||
viewer.viewport.zoomBy(0.8),
|
viewer.viewport.zoomBy(0.8)
|
||||||
);
|
);
|
||||||
homeButton!.removeEventListener("click", () =>
|
homeButton!.removeEventListener("click", () =>
|
||||||
viewer.viewport.goHome(),
|
viewer.viewport.goHome()
|
||||||
);
|
);
|
||||||
fullPageButton!.removeEventListener("click", () =>
|
fullPageButton!.removeEventListener("click", () =>
|
||||||
viewer.setFullScreen(true),
|
viewer.setFullScreen(true)
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@ import {
|
||||||
} from "../../components/ui/accordion";
|
} from "../../components/ui/accordion";
|
||||||
import { AccordionComponentType } from "../../types/components";
|
import { AccordionComponentType } from "../../types/components";
|
||||||
import { cn } from "../../utils/utils";
|
import { cn } from "../../utils/utils";
|
||||||
import ShadTooltip from "../shadTooltipComponent";
|
|
||||||
|
|
||||||
export default function AccordionComponent({
|
export default function AccordionComponent({
|
||||||
trigger,
|
trigger,
|
||||||
|
|
@ -18,7 +17,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 {
|
||||||
|
|
@ -53,7 +52,7 @@ export default function AccordionComponent({
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
className={cn(
|
className={cn(
|
||||||
sideBar ? "w-full bg-muted px-[0.75rem] py-[0.5rem]" : "ml-3",
|
sideBar ? "w-full bg-muted px-[0.75rem] py-[0.5rem]" : "ml-3",
|
||||||
disabled ? "cursor-not-allowed" : "cursor-pointer",
|
disabled ? "cursor-not-allowed" : "cursor-pointer"
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
{trigger}
|
{trigger}
|
||||||
|
|
|
||||||
|
|
@ -27,8 +27,8 @@ import {
|
||||||
import { Checkbox } from "../ui/checkbox";
|
import { Checkbox } from "../ui/checkbox";
|
||||||
import { FormControl, FormField } from "../ui/form";
|
import { FormControl, FormField } from "../ui/form";
|
||||||
import Loading from "../ui/loading";
|
import Loading from "../ui/loading";
|
||||||
import { convertTestName } from "./utils/convert-test-name";
|
|
||||||
import DragCardComponent from "./components/dragCardComponent";
|
import DragCardComponent from "./components/dragCardComponent";
|
||||||
|
import { convertTestName } from "./utils/convert-test-name";
|
||||||
|
|
||||||
export default function CollectionCardComponent({
|
export default function CollectionCardComponent({
|
||||||
data,
|
data,
|
||||||
|
|
@ -60,11 +60,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);
|
||||||
|
|
@ -75,12 +75,12 @@ 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);
|
||||||
|
|
||||||
const selectedFlowsComponentsCards = useFlowsManagerStore(
|
const selectedFlowsComponentsCards = useFlowsManagerStore(
|
||||||
(state) => state.selectedFlowsComponentsCards,
|
(state) => state.selectedFlowsComponentsCards
|
||||||
);
|
);
|
||||||
|
|
||||||
const name = data.is_component ? "Component" : "Flow";
|
const name = data.is_component ? "Component" : "Flow";
|
||||||
|
|
@ -220,7 +220,7 @@ export default function CollectionCardComponent({
|
||||||
"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" : "",
|
||||||
isSelectedCard ? "border border-selected" : "",
|
isSelectedCard ? "border border-selected" : ""
|
||||||
)}
|
)}
|
||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
>
|
>
|
||||||
|
|
@ -233,7 +233,7 @@ export default function CollectionCardComponent({
|
||||||
"visible flex-shrink-0",
|
"visible 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"}
|
||||||
/>
|
/>
|
||||||
|
|
@ -428,7 +428,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>
|
||||||
|
|
@ -463,7 +463,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>
|
||||||
|
|
@ -501,7 +501,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>
|
||||||
|
|
|
||||||
|
|
@ -65,7 +65,7 @@ export default function CardsWrapComponent({
|
||||||
"h-full w-full",
|
"h-full w-full",
|
||||||
isDragging
|
isDragging
|
||||||
? "mb-36 flex flex-col items-center justify-center gap-4 text-2xl font-light"
|
? "mb-36 flex flex-col items-center justify-center gap-4 text-2xl font-light"
|
||||||
: "",
|
: ""
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
{isDragging ? (
|
{isDragging ? (
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -236,7 +236,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) => (
|
||||||
|
|
@ -275,8 +275,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 (
|
||||||
|
|
@ -334,7 +334,7 @@ export default function CodeTabsComponent({
|
||||||
target,
|
target,
|
||||||
node.data.node.template[
|
node.data.node.template[
|
||||||
templateField
|
templateField
|
||||||
],
|
]
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
@ -380,7 +380,7 @@ export default function CodeTabsComponent({
|
||||||
target,
|
target,
|
||||||
node.data.node.template[
|
node.data.node.template[
|
||||||
templateField
|
templateField
|
||||||
],
|
]
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
@ -433,7 +433,7 @@ export default function CodeTabsComponent({
|
||||||
target,
|
target,
|
||||||
node.data.node.template[
|
node.data.node.template[
|
||||||
templateField
|
templateField
|
||||||
],
|
]
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
@ -470,7 +470,7 @@ export default function CodeTabsComponent({
|
||||||
e,
|
e,
|
||||||
node.data.node.template[
|
node.data.node.template[
|
||||||
templateField
|
templateField
|
||||||
],
|
]
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
size="small"
|
size="small"
|
||||||
|
|
@ -501,7 +501,7 @@ export default function CodeTabsComponent({
|
||||||
].fileTypes
|
].fileTypes
|
||||||
}
|
}
|
||||||
onFileChange={(
|
onFileChange={(
|
||||||
value: any,
|
value: any
|
||||||
) => {
|
) => {
|
||||||
node.data.node.template[
|
node.data.node.template[
|
||||||
templateField
|
templateField
|
||||||
|
|
@ -554,7 +554,7 @@ export default function CodeTabsComponent({
|
||||||
target,
|
target,
|
||||||
node.data.node.template[
|
node.data.node.template[
|
||||||
templateField
|
templateField
|
||||||
],
|
]
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
@ -594,7 +594,7 @@ export default function CodeTabsComponent({
|
||||||
target,
|
target,
|
||||||
node.data.node.template[
|
node.data.node.template[
|
||||||
templateField
|
templateField
|
||||||
],
|
]
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
value={
|
value={
|
||||||
|
|
@ -656,7 +656,7 @@ export default function CodeTabsComponent({
|
||||||
target,
|
target,
|
||||||
node.data.node.template[
|
node.data.node.template[
|
||||||
templateField
|
templateField
|
||||||
],
|
]
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
@ -702,7 +702,7 @@ export default function CodeTabsComponent({
|
||||||
target,
|
target,
|
||||||
node.data.node.template[
|
node.data.node.template[
|
||||||
templateField
|
templateField
|
||||||
],
|
]
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
@ -748,7 +748,7 @@ export default function CodeTabsComponent({
|
||||||
target,
|
target,
|
||||||
node.data.node.template[
|
node.data.node.template[
|
||||||
templateField
|
templateField
|
||||||
],
|
]
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
@ -780,8 +780,8 @@ export default function CodeTabsComponent({
|
||||||
].value,
|
].value,
|
||||||
type(
|
type(
|
||||||
node,
|
node,
|
||||||
templateField,
|
templateField
|
||||||
),
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
duplicateKey={
|
duplicateKey={
|
||||||
|
|
@ -790,15 +790,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 =
|
||||||
|
|
@ -815,7 +815,7 @@ export default function CodeTabsComponent({
|
||||||
target,
|
target,
|
||||||
node.data.node.template[
|
node.data.node.template[
|
||||||
templateField
|
templateField
|
||||||
],
|
]
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
isList={
|
isList={
|
||||||
|
|
@ -863,7 +863,7 @@ export default function CodeTabsComponent({
|
||||||
target,
|
target,
|
||||||
node.data.node.template[
|
node.data.node.template[
|
||||||
templateField
|
templateField
|
||||||
],
|
]
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,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);
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ export default function DictComponent({
|
||||||
<div
|
<div
|
||||||
className={classNames(
|
className={classNames(
|
||||||
value.length > 1 && editNode ? "my-1" : "",
|
value.length > 1 && editNode ? "my-1" : "",
|
||||||
"flex flex-col gap-3",
|
"flex flex-col gap-3"
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -33,9 +33,8 @@ export default function Dropdown({
|
||||||
|
|
||||||
const refButton = useRef<HTMLButtonElement>(null);
|
const refButton = useRef<HTMLButtonElement>(null);
|
||||||
|
|
||||||
const PopoverContentDropdown = children
|
const PopoverContentDropdown =
|
||||||
? PopoverContent
|
children || editNode ? PopoverContent : PopoverContentWithoutPortal;
|
||||||
: PopoverContentWithoutPortal;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|
|
||||||
|
|
@ -99,7 +99,7 @@ export const EditFlowSettings: React.FC<InputProps> = ({
|
||||||
<span
|
<span
|
||||||
className={cn(
|
className={cn(
|
||||||
"font-normal text-muted-foreground word-break-break-word",
|
"font-normal text-muted-foreground word-break-break-word",
|
||||||
description === "" ? "font-light italic" : "",
|
description === "" ? "font-light italic" : ""
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
{description === "" ? "No description" : description}
|
{description === "" ? "No description" : description}
|
||||||
|
|
|
||||||
|
|
@ -113,7 +113,7 @@ export const MenuBar = ({}: {}): JSX.Element => {
|
||||||
title: UPLOAD_ERROR_ALERT,
|
title: UPLOAD_ERROR_ALERT,
|
||||||
list: [error],
|
list: [error],
|
||||||
});
|
});
|
||||||
},
|
}
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|
@ -195,7 +195,7 @@ export const MenuBar = ({}: {}): JSX.Element => {
|
||||||
name={isBuilding || saveLoading ? "Loader2" : "CheckCircle2"}
|
name={isBuilding || saveLoading ? "Loader2" : "CheckCircle2"}
|
||||||
className={cn(
|
className={cn(
|
||||||
"h-4 w-4",
|
"h-4 w-4",
|
||||||
isBuilding || saveLoading ? "animate-spin" : "animate-wiggle",
|
isBuilding || saveLoading ? "animate-spin" : "animate-wiggle"
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
{printByBuildStatus()}
|
{printByBuildStatus()}
|
||||||
|
|
|
||||||
|
|
@ -181,18 +181,6 @@ export default function Header(): JSX.Element {
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</AlertDropdown>
|
</AlertDropdown>
|
||||||
{autoLogin && (
|
|
||||||
<button
|
|
||||||
onClick={() => {
|
|
||||||
navigate("/account/api-keys");
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<IconComponent
|
|
||||||
name="Key"
|
|
||||||
className="side-bar-button-size text-muted-foreground hover:text-accent-foreground"
|
|
||||||
/>
|
|
||||||
</button>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<>
|
<>
|
||||||
<Separator orientation="vertical" />
|
<Separator orientation="vertical" />
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,11 @@ import {
|
||||||
CommandList,
|
CommandList,
|
||||||
} from "../../../ui/command";
|
} from "../../../ui/command";
|
||||||
import { Input } from "../../../ui/input";
|
import { Input } from "../../../ui/input";
|
||||||
import { Popover, PopoverContentWithoutPortal } from "../../../ui/popover";
|
import {
|
||||||
|
Popover,
|
||||||
|
PopoverContent,
|
||||||
|
PopoverContentWithoutPortal,
|
||||||
|
} from "../../../ui/popover";
|
||||||
const CustomInputPopover = ({
|
const CustomInputPopover = ({
|
||||||
id,
|
id,
|
||||||
refInput,
|
refInput,
|
||||||
|
|
@ -39,6 +43,9 @@ const CustomInputPopover = ({
|
||||||
showOptions,
|
showOptions,
|
||||||
}) => {
|
}) => {
|
||||||
const setErrorData = useAlertStore.getState().setErrorData;
|
const setErrorData = useAlertStore.getState().setErrorData;
|
||||||
|
const PopoverContentInput = editNode
|
||||||
|
? PopoverContent
|
||||||
|
: PopoverContentWithoutPortal;
|
||||||
|
|
||||||
const handleInputChange = (e) => {
|
const handleInputChange = (e) => {
|
||||||
if (password) {
|
if (password) {
|
||||||
|
|
@ -96,7 +103,7 @@ const CustomInputPopover = ({
|
||||||
(password && !(setSelectedOption || setSelectedOptions))
|
(password && !(setSelectedOption || setSelectedOptions))
|
||||||
? "pr-8"
|
? "pr-8"
|
||||||
: "",
|
: "",
|
||||||
className!,
|
className!
|
||||||
)}
|
)}
|
||||||
placeholder={password && editNode ? "Key" : placeholder}
|
placeholder={password && editNode ? "Key" : placeholder}
|
||||||
onChange={handleInputChange}
|
onChange={handleInputChange}
|
||||||
|
|
@ -107,7 +114,7 @@ const CustomInputPopover = ({
|
||||||
data-testid={editNode ? id + "-edit" : id}
|
data-testid={editNode ? id + "-edit" : id}
|
||||||
/>
|
/>
|
||||||
</PopoverAnchor>
|
</PopoverAnchor>
|
||||||
<PopoverContentWithoutPortal
|
<PopoverContentInput
|
||||||
className="nocopy nowheel nopan nodelete nodrag noundo p-0"
|
className="nocopy nowheel nopan nodelete nodrag noundo p-0"
|
||||||
style={{ minWidth: refInput?.current?.clientWidth ?? "200px" }}
|
style={{ minWidth: refInput?.current?.clientWidth ?? "200px" }}
|
||||||
side="bottom"
|
side="bottom"
|
||||||
|
|
@ -134,15 +141,15 @@ const CustomInputPopover = ({
|
||||||
onSelect={(currentValue) => {
|
onSelect={(currentValue) => {
|
||||||
setSelectedOption &&
|
setSelectedOption &&
|
||||||
setSelectedOption(
|
setSelectedOption(
|
||||||
currentValue === selectedOption ? "" : currentValue,
|
currentValue === selectedOption ? "" : 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);
|
||||||
}}
|
}}
|
||||||
|
|
@ -155,7 +162,7 @@ const CustomInputPopover = ({
|
||||||
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">
|
||||||
|
|
@ -184,7 +191,7 @@ const CustomInputPopover = ({
|
||||||
</CommandGroup>
|
</CommandGroup>
|
||||||
</CommandList>
|
</CommandList>
|
||||||
</Command>
|
</Command>
|
||||||
</PopoverContentWithoutPortal>
|
</PopoverContentInput>
|
||||||
</Popover>
|
</Popover>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,11 @@ import {
|
||||||
CommandList,
|
CommandList,
|
||||||
} from "../../../ui/command";
|
} from "../../../ui/command";
|
||||||
import { Input } from "../../../ui/input";
|
import { Input } from "../../../ui/input";
|
||||||
import { Popover, PopoverContentWithoutPortal } from "../../../ui/popover";
|
import {
|
||||||
|
Popover,
|
||||||
|
PopoverContent,
|
||||||
|
PopoverContentWithoutPortal,
|
||||||
|
} from "../../../ui/popover";
|
||||||
const CustomInputPopoverObject = ({
|
const CustomInputPopoverObject = ({
|
||||||
id,
|
id,
|
||||||
refInput,
|
refInput,
|
||||||
|
|
@ -23,6 +27,7 @@ const CustomInputPopoverObject = ({
|
||||||
disabled,
|
disabled,
|
||||||
setShowOptions,
|
setShowOptions,
|
||||||
required,
|
required,
|
||||||
|
editNode,
|
||||||
className,
|
className,
|
||||||
placeholder,
|
placeholder,
|
||||||
onChange,
|
onChange,
|
||||||
|
|
@ -34,6 +39,10 @@ const CustomInputPopoverObject = ({
|
||||||
handleKeyDown,
|
handleKeyDown,
|
||||||
showOptions,
|
showOptions,
|
||||||
}) => {
|
}) => {
|
||||||
|
const PopoverContentInput = editNode
|
||||||
|
? PopoverContent
|
||||||
|
: PopoverContentWithoutPortal;
|
||||||
|
|
||||||
const handleInputChange = (e) => {
|
const handleInputChange = (e) => {
|
||||||
onChange && onChange(e.target.value);
|
onChange && onChange(e.target.value);
|
||||||
};
|
};
|
||||||
|
|
@ -55,7 +64,7 @@ const CustomInputPopoverObject = ({
|
||||||
? selectedOptions
|
? selectedOptions
|
||||||
.map(
|
.map(
|
||||||
(optionId) =>
|
(optionId) =>
|
||||||
options.find((option) => option.id === optionId)?.name,
|
options.find((option) => option.id === optionId)?.name
|
||||||
)
|
)
|
||||||
.join(", ")
|
.join(", ")
|
||||||
: value
|
: value
|
||||||
|
|
@ -79,7 +88,7 @@ const CustomInputPopoverObject = ({
|
||||||
data-testid={id}
|
data-testid={id}
|
||||||
/>
|
/>
|
||||||
</PopoverAnchor>
|
</PopoverAnchor>
|
||||||
<PopoverContentWithoutPortal
|
<PopoverContentInput
|
||||||
className="nocopy nowheel nopan nodelete nodrag noundo p-0"
|
className="nocopy nowheel nopan nodelete nodrag noundo p-0"
|
||||||
style={{ minWidth: refInput?.current?.clientWidth ?? "200px" }}
|
style={{ minWidth: refInput?.current?.clientWidth ?? "200px" }}
|
||||||
side="bottom"
|
side="bottom"
|
||||||
|
|
@ -106,15 +115,15 @@ const CustomInputPopoverObject = ({
|
||||||
onSelect={(currentValue) => {
|
onSelect={(currentValue) => {
|
||||||
setSelectedOption &&
|
setSelectedOption &&
|
||||||
setSelectedOption(
|
setSelectedOption(
|
||||||
currentValue === selectedOption ? "" : currentValue,
|
currentValue === selectedOption ? "" : 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);
|
||||||
}}
|
}}
|
||||||
|
|
@ -127,7 +136,7 @@ const CustomInputPopoverObject = ({
|
||||||
selectedOption === option.id ||
|
selectedOption === option.id ||
|
||||||
selectedOptions?.includes(option.id)
|
selectedOptions?.includes(option.id)
|
||||||
? "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">
|
||||||
|
|
@ -159,7 +168,7 @@ const CustomInputPopoverObject = ({
|
||||||
</CommandGroup>
|
</CommandGroup>
|
||||||
</CommandList>
|
</CommandList>
|
||||||
</Command>
|
</Command>
|
||||||
</PopoverContentWithoutPortal>
|
</PopoverContentInput>
|
||||||
</Popover>
|
</Popover>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -71,7 +71,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) => {
|
||||||
|
|
@ -108,6 +108,7 @@ export default function InputComponent({
|
||||||
setSelectedOptions={setSelectedOptions}
|
setSelectedOptions={setSelectedOptions}
|
||||||
options={objectOptions}
|
options={objectOptions}
|
||||||
value={value}
|
value={value}
|
||||||
|
editNode={editNode}
|
||||||
autoFocus={autoFocus}
|
autoFocus={autoFocus}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
setShowOptions={setShowOptions}
|
setShowOptions={setShowOptions}
|
||||||
|
|
@ -153,7 +154,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
|
||||||
|
|
@ -166,7 +167,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
|
||||||
|
|
@ -186,7 +187,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();
|
||||||
|
|
@ -203,7 +204,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
|
||||||
|
|
@ -222,7 +223,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
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import {
|
import {
|
||||||
CONSOLE_ERROR_MSG,
|
CONSOLE_ERROR_MSG,
|
||||||
CONSOLE_SUCCESS_MSG,
|
|
||||||
INVALID_FILE_ALERT,
|
INVALID_FILE_ALERT,
|
||||||
} from "../../constants/alerts_constants";
|
} from "../../constants/alerts_constants";
|
||||||
import { uploadFile } from "../../controllers/API";
|
import { uploadFile } from "../../controllers/API";
|
||||||
|
|
|
||||||
|
|
@ -32,11 +32,11 @@ export default function InputGlobalComponent({
|
||||||
const setErrorData = useAlertStore((state) => state.setErrorData);
|
const setErrorData = useAlertStore((state) => state.setErrorData);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (data.node?.template[name])
|
if (data)
|
||||||
if (
|
if (
|
||||||
globalVariablesEntries &&
|
globalVariablesEntries &&
|
||||||
!globalVariablesEntries.includes(data.node?.template[name].value) &&
|
!globalVariablesEntries.includes(data.value) &&
|
||||||
data.node?.template[name].load_from_db
|
data.load_from_db
|
||||||
) {
|
) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
onChange("", true);
|
onChange("", true);
|
||||||
|
|
@ -46,17 +46,11 @@ export default function InputGlobalComponent({
|
||||||
}, [globalVariablesEntries]);
|
}, [globalVariablesEntries]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (
|
if (!data.value && data.display_name) {
|
||||||
!data.node?.template[name].value &&
|
if (unavaliableFields[data.display_name!] && !disabled) {
|
||||||
data.node?.template[name].display_name
|
|
||||||
) {
|
|
||||||
if (
|
|
||||||
unavaliableFields[data.node?.template[name].display_name!] &&
|
|
||||||
!disabled
|
|
||||||
) {
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
setDb(true);
|
setDb(true);
|
||||||
onChange(unavaliableFields[data.node?.template[name].display_name!]);
|
onChange(unavaliableFields[data.display_name!]);
|
||||||
}, 100);
|
}, 100);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -68,10 +62,7 @@ export default function InputGlobalComponent({
|
||||||
await deleteGlobalVariable(id)
|
await deleteGlobalVariable(id)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
removeGlobalVariable(key);
|
removeGlobalVariable(key);
|
||||||
if (
|
if (data?.value === key && data?.load_from_db) {
|
||||||
data?.node?.template[name].value === key &&
|
|
||||||
data?.node?.template[name].load_from_db
|
|
||||||
) {
|
|
||||||
onChange("");
|
onChange("");
|
||||||
setDb(false);
|
setDb(false);
|
||||||
}
|
}
|
||||||
|
|
@ -94,8 +85,8 @@ export default function InputGlobalComponent({
|
||||||
id={"input-" + name}
|
id={"input-" + name}
|
||||||
editNode={editNode}
|
editNode={editNode}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
password={data.node?.template[name].password ?? false}
|
password={data.password ?? false}
|
||||||
value={data.node?.template[name].value ?? ""}
|
value={data.value ?? ""}
|
||||||
options={globalVariablesEntries}
|
options={globalVariablesEntries}
|
||||||
optionsPlaceholder={"Global Variables"}
|
optionsPlaceholder={"Global Variables"}
|
||||||
optionsIcon="Globe"
|
optionsIcon="Globe"
|
||||||
|
|
@ -138,10 +129,10 @@ export default function InputGlobalComponent({
|
||||||
</DeleteConfirmationModal>
|
</DeleteConfirmationModal>
|
||||||
)}
|
)}
|
||||||
selectedOption={
|
selectedOption={
|
||||||
data?.node?.template[name].load_from_db &&
|
data?.load_from_db &&
|
||||||
globalVariablesEntries &&
|
globalVariablesEntries &&
|
||||||
globalVariablesEntries.includes(data?.node?.template[name].value ?? "")
|
globalVariablesEntries.includes(data?.value ?? "")
|
||||||
? data?.node?.template[name].value
|
? data?.value
|
||||||
: ""
|
: ""
|
||||||
}
|
}
|
||||||
setSelectedOption={(value) => {
|
setSelectedOption={(value) => {
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ export default function ShadTooltip({
|
||||||
delayDuration = 500,
|
delayDuration = 500,
|
||||||
}: ShadToolTipType): JSX.Element {
|
}: ShadToolTipType): JSX.Element {
|
||||||
return (
|
return (
|
||||||
<Tooltip delayDuration={delayDuration}>
|
<Tooltip defaultOpen={!children} delayDuration={delayDuration}>
|
||||||
<TooltipTrigger asChild={asChild}>{children}</TooltipTrigger>
|
<TooltipTrigger asChild={asChild}>{children}</TooltipTrigger>
|
||||||
<TooltipContent
|
<TooltipContent
|
||||||
className={cn(styleClasses, "max-w-96")}
|
className={cn(styleClasses, "max-w-96")}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
import { cn } from "../../../../utils/utils";
|
import { cn } from "../../../../utils/utils";
|
||||||
import { buttonVariants } from "../../../ui/button";
|
import { buttonVariants } from "../../../ui/button";
|
||||||
import ForwardedIconComponent from "../../../genericIconComponent";
|
|
||||||
|
|
||||||
type SideBarButtonsComponentProps = {
|
type SideBarButtonsComponentProps = {
|
||||||
items: {
|
items: {
|
||||||
|
|
@ -28,7 +27,7 @@ const SideBarButtonsComponent = ({
|
||||||
pathname === item.href
|
pathname === item.href
|
||||||
? "border border-border bg-muted hover:bg-muted"
|
? "border border-border bg-muted hover:bg-muted"
|
||||||
: "border border-transparent hover:border-border hover:bg-transparent",
|
: "border border-transparent hover:border-border hover:bg-transparent",
|
||||||
"flex w-full shrink-0 justify-start gap-4",
|
"flex w-full shrink-0 justify-start gap-4"
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
{item.icon}
|
{item.icon}
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ import { addVersionToDuplicates } from "../../../utils/reactflowUtils";
|
||||||
const useFileDrop = (folderId, folderChangeCallback) => {
|
const useFileDrop = (folderId, folderChangeCallback) => {
|
||||||
const setFolderDragging = useFolderStore((state) => state.setFolderDragging);
|
const setFolderDragging = useFolderStore((state) => state.setFolderDragging);
|
||||||
const setFolderIdDragging = useFolderStore(
|
const setFolderIdDragging = useFolderStore(
|
||||||
(state) => state.setFolderIdDragging,
|
(state) => state.setFolderIdDragging
|
||||||
);
|
);
|
||||||
|
|
||||||
const setErrorData = useAlertStore((state) => state.setErrorData);
|
const setErrorData = useAlertStore((state) => state.setErrorData);
|
||||||
|
|
@ -45,7 +45,7 @@ const useFileDrop = (folderId, folderChangeCallback) => {
|
||||||
| React.DragEvent<HTMLDivElement>
|
| React.DragEvent<HTMLDivElement>
|
||||||
| React.DragEvent<HTMLButtonElement>
|
| React.DragEvent<HTMLButtonElement>
|
||||||
| React.DragEvent<HTMLAnchorElement>,
|
| React.DragEvent<HTMLAnchorElement>,
|
||||||
folderId: string,
|
folderId: string
|
||||||
) => {
|
) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
|
|
@ -60,7 +60,7 @@ const useFileDrop = (folderId, folderChangeCallback) => {
|
||||||
| React.DragEvent<HTMLDivElement>
|
| React.DragEvent<HTMLDivElement>
|
||||||
| React.DragEvent<HTMLButtonElement>
|
| React.DragEvent<HTMLButtonElement>
|
||||||
| React.DragEvent<HTMLAnchorElement>,
|
| React.DragEvent<HTMLAnchorElement>,
|
||||||
folderId: string,
|
folderId: string
|
||||||
) => {
|
) => {
|
||||||
if (e.dataTransfer.types.some((types) => types === "Files")) {
|
if (e.dataTransfer.types.some((types) => types === "Files")) {
|
||||||
setFolderDragging(true);
|
setFolderDragging(true);
|
||||||
|
|
@ -73,7 +73,7 @@ const useFileDrop = (folderId, folderChangeCallback) => {
|
||||||
e:
|
e:
|
||||||
| React.DragEvent<HTMLDivElement>
|
| React.DragEvent<HTMLDivElement>
|
||||||
| React.DragEvent<HTMLButtonElement>
|
| React.DragEvent<HTMLButtonElement>
|
||||||
| React.DragEvent<HTMLAnchorElement>,
|
| React.DragEvent<HTMLAnchorElement>
|
||||||
) => {
|
) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
if (e.target === e.currentTarget) {
|
if (e.target === e.currentTarget) {
|
||||||
|
|
@ -87,7 +87,7 @@ const useFileDrop = (folderId, folderChangeCallback) => {
|
||||||
| React.DragEvent<HTMLDivElement>
|
| React.DragEvent<HTMLDivElement>
|
||||||
| React.DragEvent<HTMLButtonElement>
|
| React.DragEvent<HTMLButtonElement>
|
||||||
| React.DragEvent<HTMLAnchorElement>,
|
| React.DragEvent<HTMLAnchorElement>,
|
||||||
folderId: string,
|
folderId: string
|
||||||
) => {
|
) => {
|
||||||
if (e?.dataTransfer?.getData("flow")) {
|
if (e?.dataTransfer?.getData("flow")) {
|
||||||
const data = JSON.parse(e?.dataTransfer?.getData("flow"));
|
const data = JSON.parse(e?.dataTransfer?.getData("flow"));
|
||||||
|
|
|
||||||
|
|
@ -5,9 +5,6 @@ import { cn } from "../../utils/utils";
|
||||||
import HorizontalScrollFadeComponent from "../horizontalScrollFadeComponent";
|
import HorizontalScrollFadeComponent from "../horizontalScrollFadeComponent";
|
||||||
import SideBarButtonsComponent from "./components/sideBarButtons";
|
import SideBarButtonsComponent from "./components/sideBarButtons";
|
||||||
import SideBarFoldersButtonsComponent from "./components/sideBarFolderButtons";
|
import SideBarFoldersButtonsComponent from "./components/sideBarFolderButtons";
|
||||||
import { addFolder } from "../../pages/MainPage/services";
|
|
||||||
import { useNavigate } from "react-router-dom";
|
|
||||||
import useFlowStore from "../../stores/flowStore";
|
|
||||||
|
|
||||||
type SidebarNavProps = {
|
type SidebarNavProps = {
|
||||||
items: {
|
items: {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,4 @@
|
||||||
import { cn } from "../../../../utils/utils";
|
import { cn } from "../../../../utils/utils";
|
||||||
import ShadTooltip from "../../../shadTooltipComponent";
|
|
||||||
import { Toggle } from "../../../ui/toggle";
|
|
||||||
|
|
||||||
export default function ResetColumns({
|
export default function ResetColumns({
|
||||||
resetGrid,
|
resetGrid,
|
||||||
|
|
@ -8,15 +6,6 @@ export default function ResetColumns({
|
||||||
resetGrid: () => void;
|
resetGrid: () => void;
|
||||||
}): JSX.Element {
|
}): JSX.Element {
|
||||||
return (
|
return (
|
||||||
/*<div className="absolute left-2 bottom-1 cursor-pointer">
|
|
||||||
<div
|
|
||||||
className="flex h-10 items-center justify-center px-2 pl-3 rounded-md border border-ring/60 text-sm text-[#bccadc] ring-offset-background placeholder:text-muted-foreground hover:bg-muted focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50"
|
|
||||||
onClick={() => setShow(!show)}
|
|
||||||
>
|
|
||||||
<ForwardedIconComponent name="Settings"></ForwardedIconComponent>
|
|
||||||
<ForwardedIconComponent name={show ? "ChevronLeft" : "ChevronRight"} className="transition-all"></ForwardedIconComponent>
|
|
||||||
</div>
|
|
||||||
</div>*/
|
|
||||||
<div className={cn("absolute bottom-4 left-6")}>
|
<div className={cn("absolute bottom-4 left-6")}>
|
||||||
<span
|
<span
|
||||||
className="cursor-pointer underline"
|
className="cursor-pointer underline"
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
import { CustomCellRendererProps } from "ag-grid-react";
|
import { CustomCellRendererProps } from "ag-grid-react";
|
||||||
import { cn, isTimeStampString } from "../../utils/utils";
|
import { cn, isTimeStampString } from "../../../../utils/utils";
|
||||||
import ArrayReader from "../arrayReaderComponent";
|
import ArrayReader from "../../../arrayReaderComponent";
|
||||||
import DateReader from "../dateReaderComponent";
|
import DateReader from "../../../dateReaderComponent";
|
||||||
import NumberReader from "../numberReader";
|
import NumberReader from "../../../numberReader";
|
||||||
import ObjectRender from "../objectRender";
|
import ObjectRender from "../../../objectRender";
|
||||||
import StringReader from "../stringReaderComponent";
|
import StringReader from "../../../stringReaderComponent";
|
||||||
import { Badge } from "../ui/badge";
|
import { Badge } from "../../../ui/badge";
|
||||||
|
|
||||||
export default function TableAutoCellRender({
|
export default function TableAutoCellRender({
|
||||||
value,
|
value,
|
||||||
|
|
@ -43,7 +43,6 @@ export default function TableAutoCellRender({
|
||||||
} else {
|
} else {
|
||||||
return <StringReader string={value} />;
|
return <StringReader string={value} />;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
case "number":
|
case "number":
|
||||||
return <NumberReader number={value} />;
|
return <NumberReader number={value} />;
|
||||||
default:
|
default:
|
||||||
|
|
@ -0,0 +1,266 @@
|
||||||
|
import { CustomCellRendererProps } from "ag-grid-react";
|
||||||
|
import { cloneDeep } from "lodash";
|
||||||
|
import { useState } from "react";
|
||||||
|
import CodeAreaComponent from "../../../codeAreaComponent";
|
||||||
|
import DictComponent from "../../../dictComponent";
|
||||||
|
import Dropdown from "../../../dropdownComponent";
|
||||||
|
import FloatComponent from "../../../floatComponent";
|
||||||
|
import InputFileComponent from "../../../inputFileComponent";
|
||||||
|
import InputGlobalComponent from "../../../inputGlobalComponent";
|
||||||
|
import InputListComponent from "../../../inputListComponent";
|
||||||
|
import IntComponent from "../../../intComponent";
|
||||||
|
import KeypairListComponent from "../../../keypairListComponent";
|
||||||
|
import PromptAreaComponent from "../../../promptComponent";
|
||||||
|
import TextAreaComponent from "../../../textAreaComponent";
|
||||||
|
import ToggleShadComponent from "../../../toggleShadComponent";
|
||||||
|
import useFlowStore from "../../../../stores/flowStore";
|
||||||
|
import {
|
||||||
|
convertObjToArray,
|
||||||
|
convertValuesToNumbers,
|
||||||
|
hasDuplicateKeys,
|
||||||
|
scapedJSONStringfy,
|
||||||
|
} from "../../../../utils/reactflowUtils";
|
||||||
|
import { classNames } from "../../../../utils/utils";
|
||||||
|
|
||||||
|
export default function TableNodeCellRender({
|
||||||
|
node: { data },
|
||||||
|
value: {
|
||||||
|
value,
|
||||||
|
nodeClass,
|
||||||
|
handleOnNewValue: handleOnNewValueNode,
|
||||||
|
handleOnChangeDb,
|
||||||
|
},
|
||||||
|
}: CustomCellRendererProps) {
|
||||||
|
const handleOnNewValue = (newValue: any, name: string) => {
|
||||||
|
handleOnNewValueNode(newValue, name);
|
||||||
|
setTemplateData((old) => {
|
||||||
|
let newData = cloneDeep(old);
|
||||||
|
newData.value = newValue;
|
||||||
|
return newData;
|
||||||
|
});
|
||||||
|
setTemplateValue(newValue);
|
||||||
|
};
|
||||||
|
|
||||||
|
const [templateValue, setTemplateValue] = useState(value);
|
||||||
|
const [templateData, setTemplateData] = useState(data);
|
||||||
|
|
||||||
|
const [errorDuplicateKey, setErrorDuplicateKey] = useState(false);
|
||||||
|
const edges = useFlowStore((state) => state.edges);
|
||||||
|
|
||||||
|
const id = {
|
||||||
|
inputTypes: templateData.input_types,
|
||||||
|
type: templateData.type,
|
||||||
|
id: nodeClass.id,
|
||||||
|
fieldName: templateData.key,
|
||||||
|
};
|
||||||
|
const disabled =
|
||||||
|
edges.some(
|
||||||
|
(edge) =>
|
||||||
|
edge.targetHandle ===
|
||||||
|
scapedJSONStringfy(
|
||||||
|
templateData.proxy
|
||||||
|
? {
|
||||||
|
...id,
|
||||||
|
proxy: templateData.proxy,
|
||||||
|
}
|
||||||
|
: id,
|
||||||
|
),
|
||||||
|
) ?? false;
|
||||||
|
function getCellType() {
|
||||||
|
switch (templateData.type) {
|
||||||
|
case "str":
|
||||||
|
if (!templateData.options) {
|
||||||
|
return templateData?.list ? (
|
||||||
|
<InputListComponent
|
||||||
|
componentName={templateData.key ?? undefined}
|
||||||
|
editNode={true}
|
||||||
|
disabled={disabled}
|
||||||
|
value={
|
||||||
|
!templateValue || templateValue === "" ? [""] : templateValue
|
||||||
|
}
|
||||||
|
onChange={(value: string[]) => {
|
||||||
|
handleOnNewValue(value, templateData.key);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
) : templateData.multiline ? (
|
||||||
|
<TextAreaComponent
|
||||||
|
id={"textarea-edit-" + templateData.name}
|
||||||
|
data-testid={"textarea-edit-" + templateData.name}
|
||||||
|
disabled={disabled}
|
||||||
|
editNode={true}
|
||||||
|
value={templateValue ?? ""}
|
||||||
|
onChange={(value: string | string[]) => {
|
||||||
|
handleOnNewValue(value, templateData.key);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<InputGlobalComponent
|
||||||
|
disabled={disabled}
|
||||||
|
editNode={true}
|
||||||
|
onChange={(value) => handleOnNewValue(value, templateData.key)}
|
||||||
|
setDb={(value) => {
|
||||||
|
handleOnChangeDb(value, templateData.key);
|
||||||
|
}}
|
||||||
|
name={templateData.key}
|
||||||
|
data={templateData}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return (
|
||||||
|
<Dropdown
|
||||||
|
editNode={true}
|
||||||
|
options={templateData.options}
|
||||||
|
onSelect={(value) => handleOnNewValue(value, templateData.key)}
|
||||||
|
value={templateValue ?? "Choose an option"}
|
||||||
|
id={"dropdown-edit-" + templateData.name}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
case "NestedDict":
|
||||||
|
return (
|
||||||
|
<DictComponent
|
||||||
|
disabled={disabled}
|
||||||
|
editNode={true}
|
||||||
|
value={templateValue.toString() === "{}" ? {} : templateValue}
|
||||||
|
onChange={(newValue) => {
|
||||||
|
handleOnNewValue(newValue, templateData.key);
|
||||||
|
}}
|
||||||
|
id="editnode-div-dict-input"
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
case "dict":
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={classNames(
|
||||||
|
"max-h-48 w-full overflow-auto custom-scroll",
|
||||||
|
templateValue?.length > 1 ? "my-3" : "",
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<KeypairListComponent
|
||||||
|
disabled={disabled}
|
||||||
|
editNode={true}
|
||||||
|
value={
|
||||||
|
templateValue?.length === 0 || !templateValue
|
||||||
|
? [{ "": "" }]
|
||||||
|
: convertObjToArray(templateValue, templateData.type)
|
||||||
|
}
|
||||||
|
duplicateKey={errorDuplicateKey}
|
||||||
|
onChange={(newValue) => {
|
||||||
|
const valueToNumbers = convertValuesToNumbers(newValue);
|
||||||
|
setErrorDuplicateKey(hasDuplicateKeys(valueToNumbers));
|
||||||
|
handleOnNewValue(valueToNumbers, templateData.key);
|
||||||
|
}}
|
||||||
|
isList={templateData.list ?? false}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
|
case "bool":
|
||||||
|
return (
|
||||||
|
<ToggleShadComponent
|
||||||
|
id={"toggle-edit-" + templateData.name}
|
||||||
|
disabled={disabled}
|
||||||
|
enabled={templateValue}
|
||||||
|
setEnabled={(isEnabled) => {
|
||||||
|
handleOnNewValue(isEnabled, templateData.key);
|
||||||
|
}}
|
||||||
|
size="small"
|
||||||
|
editNode={true}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
case "float":
|
||||||
|
return (
|
||||||
|
<FloatComponent
|
||||||
|
disabled={disabled}
|
||||||
|
editNode={true}
|
||||||
|
rangeSpec={templateData.rangeSpec}
|
||||||
|
value={templateValue ?? ""}
|
||||||
|
onChange={(value) => {
|
||||||
|
handleOnNewValue(value, templateData.key);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
case "int":
|
||||||
|
return (
|
||||||
|
<IntComponent
|
||||||
|
rangeSpec={templateData.rangeSpec}
|
||||||
|
id={"edit-int-input-" + templateData.name}
|
||||||
|
disabled={disabled}
|
||||||
|
editNode={true}
|
||||||
|
value={templateValue ?? ""}
|
||||||
|
onChange={(value) => {
|
||||||
|
handleOnNewValue(value, templateData.key);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
case "file":
|
||||||
|
return (
|
||||||
|
<InputFileComponent
|
||||||
|
editNode={true}
|
||||||
|
disabled={disabled}
|
||||||
|
value={templateValue ?? ""}
|
||||||
|
onChange={(value: string | string[]) => {
|
||||||
|
handleOnNewValue(value, templateData.key);
|
||||||
|
}}
|
||||||
|
fileTypes={templateData.fileTypes}
|
||||||
|
onFileChange={(filePath: string) => {
|
||||||
|
templateData.file_path = filePath;
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
case "prompt":
|
||||||
|
return (
|
||||||
|
<PromptAreaComponent
|
||||||
|
readonly={nodeClass.flow ? true : false}
|
||||||
|
field_name={templateData.key}
|
||||||
|
editNode={true}
|
||||||
|
disabled={disabled}
|
||||||
|
nodeClass={nodeClass}
|
||||||
|
setNodeClass={(value) => {
|
||||||
|
nodeClass = value;
|
||||||
|
}}
|
||||||
|
value={templateValue ?? ""}
|
||||||
|
onChange={(value: string | string[]) => {
|
||||||
|
handleOnNewValue(value, templateData.key);
|
||||||
|
}}
|
||||||
|
id={"prompt-area-edit-" + templateData.name}
|
||||||
|
data-testid={"modal-prompt-input-" + templateData.name}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
case "code":
|
||||||
|
return (
|
||||||
|
<CodeAreaComponent
|
||||||
|
readonly={nodeClass.flow && templateData.dynamic ? true : false}
|
||||||
|
dynamic={templateData.dynamic ?? false}
|
||||||
|
setNodeClass={(value) => {
|
||||||
|
nodeClass = value;
|
||||||
|
}}
|
||||||
|
nodeClass={nodeClass}
|
||||||
|
disabled={disabled}
|
||||||
|
editNode={true}
|
||||||
|
value={templateValue ?? ""}
|
||||||
|
onChange={(value: string | string[]) => {
|
||||||
|
handleOnNewValue(value, templateData.key);
|
||||||
|
}}
|
||||||
|
id={"code-area-edit" + templateData.name}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
case "Any":
|
||||||
|
return <>-</>;
|
||||||
|
default:
|
||||||
|
return String(templateValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="group flex h-full w-[300px] items-center justify-center py-2.5">
|
||||||
|
{getCellType()}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
import { CustomCellRendererProps } from "ag-grid-react";
|
||||||
|
import { useState } from "react";
|
||||||
|
import ToggleShadComponent from "../../../toggleShadComponent";
|
||||||
|
|
||||||
|
export default function TableToggleCellRender({
|
||||||
|
value: { name, enabled, setEnabled },
|
||||||
|
}: CustomCellRendererProps) {
|
||||||
|
const [value, setValue] = useState(enabled);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="flex h-full items-center">
|
||||||
|
<ToggleShadComponent
|
||||||
|
id={"show" + name}
|
||||||
|
enabled={value}
|
||||||
|
setEnabled={(e) => {
|
||||||
|
setValue(e);
|
||||||
|
setEnabled(e);
|
||||||
|
}}
|
||||||
|
size="small"
|
||||||
|
editNode={true}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
import { CustomTooltipProps } from "ag-grid-react";
|
||||||
|
|
||||||
|
export default function TableTooltipRender({ value }: CustomTooltipProps) {
|
||||||
|
return (
|
||||||
|
<div className="z-45 overflow-y-auto rounded-md border bg-popover px-3 py-1.5 text-sm text-popover-foreground shadow-md animate-in fade-in-50 data-[side=bottom]:slide-in-from-top-1 data-[side=left]:slide-in-from-right-1 data-[side=right]:slide-in-from-left-1 data-[side=top]:slide-in-from-bottom-1">
|
||||||
|
{value}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import "ag-grid-community/styles/ag-grid.css"; // Mandatory CSS required by the grid
|
import "ag-grid-community/styles/ag-grid.css"; // Mandatory CSS required by the grid
|
||||||
import "ag-grid-community/styles/ag-theme-quartz.css"; // Optional Theme applied to the grid
|
import "ag-grid-community/styles/ag-theme-quartz.css"; // Optional Theme applied to the grid
|
||||||
import { AgGridReact, AgGridReactProps } from "ag-grid-react";
|
import { AgGridReact, AgGridReactProps } from "ag-grid-react";
|
||||||
import { ElementRef, forwardRef, useEffect, useRef } from "react";
|
import { ElementRef, forwardRef, useRef } from "react";
|
||||||
import {
|
import {
|
||||||
DEFAULT_TABLE_ALERT_MSG,
|
DEFAULT_TABLE_ALERT_MSG,
|
||||||
DEFAULT_TABLE_ALERT_TITLE,
|
DEFAULT_TABLE_ALERT_TITLE,
|
||||||
|
|
@ -11,10 +11,8 @@ import "../../style/ag-theme-shadcn.css"; // Custom CSS applied to the grid
|
||||||
import { cn, toTitleCase } from "../../utils/utils";
|
import { cn, toTitleCase } from "../../utils/utils";
|
||||||
import ForwardedIconComponent from "../genericIconComponent";
|
import ForwardedIconComponent from "../genericIconComponent";
|
||||||
import { Alert, AlertDescription, AlertTitle } from "../ui/alert";
|
import { Alert, AlertDescription, AlertTitle } from "../ui/alert";
|
||||||
import { Toggle } from "../ui/toggle";
|
|
||||||
import ShadTooltip from "../shadTooltipComponent";
|
|
||||||
import resetGrid from "./utils/reset-grid-columns";
|
|
||||||
import ResetColumns from "./components/ResetColumns";
|
import ResetColumns from "./components/ResetColumns";
|
||||||
|
import resetGrid from "./utils/reset-grid-columns";
|
||||||
|
|
||||||
interface TableComponentProps extends AgGridReactProps {
|
interface TableComponentProps extends AgGridReactProps {
|
||||||
columnDefs: NonNullable<AgGridReactProps["columnDefs"]>;
|
columnDefs: NonNullable<AgGridReactProps["columnDefs"]>;
|
||||||
|
|
@ -34,7 +32,7 @@ const TableComponent = forwardRef<
|
||||||
alertDescription = DEFAULT_TABLE_ALERT_MSG,
|
alertDescription = DEFAULT_TABLE_ALERT_MSG,
|
||||||
...props
|
...props
|
||||||
},
|
},
|
||||||
ref,
|
ref
|
||||||
) => {
|
) => {
|
||||||
let colDef = props.columnDefs.map((col, index) => {
|
let colDef = props.columnDefs.map((col, index) => {
|
||||||
let newCol = {
|
let newCol = {
|
||||||
|
|
@ -91,7 +89,7 @@ const TableComponent = forwardRef<
|
||||||
|
|
||||||
const onColumnMoved = (params) => {
|
const onColumnMoved = (params) => {
|
||||||
const updatedColumnDefs = makeLastColumnNonResizable(
|
const updatedColumnDefs = makeLastColumnNonResizable(
|
||||||
params.columnApi.getAllGridColumns().map((col) => col.getColDef()),
|
params.columnApi.getAllGridColumns().map((col) => col.getColDef())
|
||||||
);
|
);
|
||||||
params.api.setColumnDefs(updatedColumnDefs);
|
params.api.setColumnDefs(updatedColumnDefs);
|
||||||
if (props.onColumnMoved) props.onColumnMoved(params);
|
if (props.onColumnMoved) props.onColumnMoved(params);
|
||||||
|
|
@ -116,7 +114,7 @@ const TableComponent = forwardRef<
|
||||||
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",
|
||||||
"relative",
|
"relative"
|
||||||
)} // applying the grid theme
|
)} // applying the grid theme
|
||||||
>
|
>
|
||||||
<AgGridReact
|
<AgGridReact
|
||||||
|
|
@ -126,9 +124,11 @@ const TableComponent = forwardRef<
|
||||||
minWidth: 100,
|
minWidth: 100,
|
||||||
autoHeight: true,
|
autoHeight: true,
|
||||||
}}
|
}}
|
||||||
tooltipInteraction={true}
|
|
||||||
columnDefs={colDef}
|
columnDefs={colDef}
|
||||||
ref={realRef}
|
ref={realRef}
|
||||||
|
getRowId={(params) => {
|
||||||
|
return params.data.id;
|
||||||
|
}}
|
||||||
pagination={true}
|
pagination={true}
|
||||||
onGridReady={onGridReady}
|
onGridReady={onGridReady}
|
||||||
onColumnMoved={onColumnMoved}
|
onColumnMoved={onColumnMoved}
|
||||||
|
|
@ -136,7 +136,7 @@ const TableComponent = forwardRef<
|
||||||
<ResetColumns resetGrid={() => resetGrid(realRef, initialColumnDefs)} />
|
<ResetColumns resetGrid={() => resetGrid(realRef, initialColumnDefs)} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
},
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
export default TableComponent;
|
export default TableComponent;
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,6 @@ export default function ToggleShadComponent({
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={disabled ? "pointer-events-none cursor-not-allowed " : ""}>
|
|
||||||
<Switch
|
<Switch
|
||||||
id={id}
|
id={id}
|
||||||
data-testid={id}
|
data-testid={id}
|
||||||
|
|
@ -43,6 +42,5 @@ export default function ToggleShadComponent({
|
||||||
setEnabled(isEnabled);
|
setEnabled(isEnabled);
|
||||||
}}
|
}}
|
||||||
></Switch>
|
></Switch>
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ const AccordionTrigger = React.forwardRef<
|
||||||
<div
|
<div
|
||||||
className={cn(
|
className={cn(
|
||||||
"flex flex-1 cursor-pointer items-center justify-between py-4 text-sm font-medium transition-all [&[data-state=open]>svg]:rotate-180",
|
"flex flex-1 cursor-pointer items-center justify-between py-4 text-sm font-medium transition-all [&[data-state=open]>svg]:rotate-180",
|
||||||
className,
|
className
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
|
|
@ -46,7 +46,7 @@ const AccordionTrigger = React.forwardRef<
|
||||||
<ChevronDownIcon
|
<ChevronDownIcon
|
||||||
className={cn(
|
className={cn(
|
||||||
"h-4 w-4 font-bold transition-transform duration-200",
|
"h-4 w-4 font-bold transition-transform duration-200",
|
||||||
disabled ? "text-muted-foreground" : "text-primary",
|
disabled ? "text-muted-foreground" : "text-primary"
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
</ShadTooltip>
|
</ShadTooltip>
|
||||||
|
|
@ -64,7 +64,7 @@ const AccordionContent = React.forwardRef<
|
||||||
ref={ref}
|
ref={ref}
|
||||||
className={cn(
|
className={cn(
|
||||||
"data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down overflow-hidden text-sm",
|
"data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down overflow-hidden text-sm",
|
||||||
className,
|
className
|
||||||
)}
|
)}
|
||||||
{...props}
|
{...props}
|
||||||
>
|
>
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ const buttonVariants = cva(
|
||||||
variant: "default",
|
variant: "default",
|
||||||
size: "default",
|
size: "default",
|
||||||
},
|
},
|
||||||
},
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
export interface ButtonProps
|
export interface ButtonProps
|
||||||
|
|
@ -59,12 +59,13 @@ const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
|
||||||
variant,
|
variant,
|
||||||
size,
|
size,
|
||||||
loading,
|
loading,
|
||||||
|
type,
|
||||||
disabled,
|
disabled,
|
||||||
asChild = false,
|
asChild = false,
|
||||||
children,
|
children,
|
||||||
...props
|
...props
|
||||||
},
|
},
|
||||||
ref,
|
ref
|
||||||
) => {
|
) => {
|
||||||
const Comp = asChild ? Slot : "button";
|
const Comp = asChild ? Slot : "button";
|
||||||
let newChildren = children;
|
let newChildren = children;
|
||||||
|
|
@ -76,6 +77,7 @@ const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
|
||||||
<Comp
|
<Comp
|
||||||
className={cn(buttonVariants({ variant, size, className }))}
|
className={cn(buttonVariants({ variant, size, className }))}
|
||||||
disabled={loading || disabled}
|
disabled={loading || disabled}
|
||||||
|
{...(asChild ? {} : { type: type || "button" })}
|
||||||
ref={ref}
|
ref={ref}
|
||||||
{...props}
|
{...props}
|
||||||
>
|
>
|
||||||
|
|
@ -95,7 +97,7 @@ const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
|
||||||
</Comp>
|
</Comp>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
},
|
}
|
||||||
);
|
);
|
||||||
Button.displayName = "Button";
|
Button.displayName = "Button";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ const Card = React.forwardRef<
|
||||||
ref={ref}
|
ref={ref}
|
||||||
className={cn(
|
className={cn(
|
||||||
"flex flex-col justify-between rounded-lg border bg-muted text-card-foreground shadow-sm transition-all",
|
"flex flex-col justify-between rounded-lg border bg-muted text-card-foreground shadow-sm transition-all",
|
||||||
className,
|
className
|
||||||
)}
|
)}
|
||||||
{...props}
|
{...props}
|
||||||
/>
|
/>
|
||||||
|
|
@ -36,7 +36,7 @@ const CardTitle = React.forwardRef<
|
||||||
ref={ref}
|
ref={ref}
|
||||||
className={cn(
|
className={cn(
|
||||||
"text-base font-semibold leading-tight tracking-tight",
|
"text-base font-semibold leading-tight tracking-tight",
|
||||||
className,
|
className
|
||||||
)}
|
)}
|
||||||
{...props}
|
{...props}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -31,11 +31,7 @@ function RefreshButton({
|
||||||
|
|
||||||
// icon class name should take into account the disabled state and the loading state
|
// icon class name should take into account the disabled state and the loading state
|
||||||
const disabledIconTextClass = disabled ? "text-muted-foreground" : "";
|
const disabledIconTextClass = disabled ? "text-muted-foreground" : "";
|
||||||
const iconClassName = cn(
|
const iconClassName = cn("h-4 w-4 animate-wiggle", disabledIconTextClass);
|
||||||
"h-4 w-4",
|
|
||||||
isLoading ? "animate-spin" : "animate-wiggle",
|
|
||||||
disabledIconTextClass
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Button
|
<Button
|
||||||
|
|
@ -44,10 +40,11 @@ function RefreshButton({
|
||||||
className={classNames}
|
className={classNames}
|
||||||
onClick={handleClick}
|
onClick={handleClick}
|
||||||
id={id}
|
id={id}
|
||||||
|
loading={isLoading}
|
||||||
>
|
>
|
||||||
{button_text && <span className="mr-1">{button_text}</span>}
|
{button_text && <span className="mr-1">{button_text}</span>}
|
||||||
<IconComponent
|
<IconComponent
|
||||||
name={isLoading ? "Loader2" : "RefreshCcw"}
|
name={"RefreshCcw"}
|
||||||
className={iconClassName}
|
className={iconClassName}
|
||||||
id={id + "-icon"}
|
id={id + "-icon"}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import * as React from "react";
|
|
||||||
import * as TogglePrimitive from "@radix-ui/react-toggle";
|
import * as TogglePrimitive from "@radix-ui/react-toggle";
|
||||||
import { cva, type VariantProps } from "class-variance-authority";
|
import { cva, type VariantProps } from "class-variance-authority";
|
||||||
|
import * as React from "react";
|
||||||
|
|
||||||
import { cn } from "../../utils/utils";
|
import { cn } from "../../utils/utils";
|
||||||
|
|
||||||
|
|
@ -25,7 +25,7 @@ const toggleVariants = cva(
|
||||||
variant: "default",
|
variant: "default",
|
||||||
size: "default",
|
size: "default",
|
||||||
},
|
},
|
||||||
},
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
const Toggle = React.forwardRef<
|
const Toggle = React.forwardRef<
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ const TooltipContent = React.forwardRef<
|
||||||
sideOffset={sideOffset}
|
sideOffset={sideOffset}
|
||||||
className={cn(
|
className={cn(
|
||||||
"z-45 overflow-y-auto rounded-md border bg-popover px-3 py-1.5 text-sm text-popover-foreground shadow-md animate-in fade-in-50 data-[side=bottom]:slide-in-from-top-1 data-[side=left]:slide-in-from-right-1 data-[side=right]:slide-in-from-left-1 data-[side=top]:slide-in-from-bottom-1",
|
"z-45 overflow-y-auto rounded-md border bg-popover px-3 py-1.5 text-sm text-popover-foreground shadow-md animate-in fade-in-50 data-[side=bottom]:slide-in-from-top-1 data-[side=left]:slide-in-from-right-1 data-[side=right]:slide-in-from-left-1 data-[side=top]:slide-in-from-bottom-1",
|
||||||
className,
|
className
|
||||||
)}
|
)}
|
||||||
{...props}
|
{...props}
|
||||||
/>
|
/>
|
||||||
|
|
@ -37,7 +37,7 @@ const TooltipContentWithoutPortal = React.forwardRef<
|
||||||
sideOffset={sideOffset}
|
sideOffset={sideOffset}
|
||||||
className={cn(
|
className={cn(
|
||||||
"z-45 overflow-y-auto rounded-md border bg-popover px-3 py-1.5 text-sm text-popover-foreground shadow-md animate-in fade-in-50 data-[side=bottom]:slide-in-from-top-1 data-[side=left]:slide-in-from-right-1 data-[side=right]:slide-in-from-left-1 data-[side=top]:slide-in-from-bottom-1",
|
"z-45 overflow-y-auto rounded-md border bg-popover px-3 py-1.5 text-sm text-popover-foreground shadow-md animate-in fade-in-50 data-[side=bottom]:slide-in-from-top-1 data-[side=left]:slide-in-from-right-1 data-[side=right]:slide-in-from-left-1 data-[side=top]:slide-in-from-bottom-1",
|
||||||
className,
|
className
|
||||||
)}
|
)}
|
||||||
{...props}
|
{...props}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ export const USER_EDIT_ERROR_ALERT = "Error on edit user";
|
||||||
export const USER_ADD_ERROR_ALERT = "Error when adding new user";
|
export const USER_ADD_ERROR_ALERT = "Error when adding new user";
|
||||||
export const SIGNIN_ERROR_ALERT = "Error signing in";
|
export const SIGNIN_ERROR_ALERT = "Error signing in";
|
||||||
export const DEL_KEY_ERROR_ALERT = "Error on delete key";
|
export const DEL_KEY_ERROR_ALERT = "Error on delete key";
|
||||||
|
export const DEL_KEY_ERROR_ALERT_PLURAL = "Error on delete keys";
|
||||||
export const UPLOAD_ERROR_ALERT = "Error uploading file";
|
export const UPLOAD_ERROR_ALERT = "Error uploading file";
|
||||||
export const WRONG_FILE_ERROR_ALERT = "Invalid file type";
|
export const WRONG_FILE_ERROR_ALERT = "Invalid file type";
|
||||||
export const UPLOAD_ALERT_LIST = "Please upload a JSON file";
|
export const UPLOAD_ALERT_LIST = "Please upload a JSON file";
|
||||||
|
|
@ -54,6 +55,7 @@ export const USER_DEL_SUCCESS_ALERT = "Success! User deleted!";
|
||||||
export const USER_EDIT_SUCCESS_ALERT = "Success! User edited!";
|
export const USER_EDIT_SUCCESS_ALERT = "Success! User edited!";
|
||||||
export const USER_ADD_SUCCESS_ALERT = "Success! New user added!";
|
export const USER_ADD_SUCCESS_ALERT = "Success! New user added!";
|
||||||
export const DEL_KEY_SUCCESS_ALERT = "Success! Key deleted!";
|
export const DEL_KEY_SUCCESS_ALERT = "Success! Key deleted!";
|
||||||
|
export const DEL_KEY_SUCCESS_ALERT_PLURAL = "Success! Keys deleted!";
|
||||||
export const FLOW_BUILD_SUCCESS_ALERT = `Flow built successfully`;
|
export const FLOW_BUILD_SUCCESS_ALERT = `Flow built successfully`;
|
||||||
export const SAVE_SUCCESS_ALERT = "Changes saved successfully!";
|
export const SAVE_SUCCESS_ALERT = "Changes saved successfully!";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -613,11 +613,8 @@ export const FETCH_ERROR_DESCRIPION =
|
||||||
|
|
||||||
export const SIGN_UP_SUCCESS = "Account created! Await admin activation. ";
|
export const SIGN_UP_SUCCESS = "Account created! Await admin activation. ";
|
||||||
|
|
||||||
export const API_PAGE_PARAGRAPH_1 =
|
export const API_PAGE_PARAGRAPH =
|
||||||
"Your secret API keys are listed below. Please note that we do not display your secret API keys again after you generate them.";
|
"Your secret API keys are listed below. Do not share your API key with others, or expose it in the browser or other client-side code.";
|
||||||
|
|
||||||
export const API_PAGE_PARAGRAPH_2 =
|
|
||||||
"Do not share your API key with others, or expose it in the browser or other client-side code.";
|
|
||||||
|
|
||||||
export const API_PAGE_USER_KEYS =
|
export const API_PAGE_USER_KEYS =
|
||||||
"This user does not have any keys assigned at the moment.";
|
"This user does not have any keys assigned at the moment.";
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ export function checkDuplicateRequestAndStoreRequest(config) {
|
||||||
const currentTime = Date.now();
|
const currentTime = Date.now();
|
||||||
|
|
||||||
const isContained = AUTHORIZED_DUPLICATE_REQUESTS.some((request) =>
|
const isContained = AUTHORIZED_DUPLICATE_REQUESTS.some((request) =>
|
||||||
config?.url!.includes(request),
|
config?.url!.includes(request)
|
||||||
);
|
);
|
||||||
|
|
||||||
if (
|
if (
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ import {
|
||||||
} from "../../types/api/index";
|
} from "../../types/api/index";
|
||||||
import { UserInputType } from "../../types/components";
|
import { UserInputType } from "../../types/components";
|
||||||
import { FlowStyleType, FlowType } from "../../types/flow";
|
import { FlowStyleType, FlowType } from "../../types/flow";
|
||||||
|
import { Message } from "../../types/messages";
|
||||||
import { StoreComponentResponse } from "../../types/store";
|
import { StoreComponentResponse } from "../../types/store";
|
||||||
import { FlowPoolType } from "../../types/zustand/flow";
|
import { FlowPoolType } from "../../types/zustand/flow";
|
||||||
import { extractColumnsFromRows } from "../../utils/utils";
|
import { extractColumnsFromRows } from "../../utils/utils";
|
||||||
|
|
@ -28,7 +29,6 @@ import {
|
||||||
UploadFileTypeAPI,
|
UploadFileTypeAPI,
|
||||||
errorsTypeAPI,
|
errorsTypeAPI,
|
||||||
} from "./../../types/api/index";
|
} from "./../../types/api/index";
|
||||||
import { Message } from "../../types/messages";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetches all objects from the API endpoint.
|
* Fetches all objects from the API endpoint.
|
||||||
|
|
@ -62,7 +62,7 @@ export async function sendAll(data: sendAllProps) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function postValidateCode(
|
export async function postValidateCode(
|
||||||
code: string,
|
code: string
|
||||||
): Promise<AxiosResponse<errorsTypeAPI>> {
|
): Promise<AxiosResponse<errorsTypeAPI>> {
|
||||||
return await api.post(`${BASE_URL_API}validate/code`, { code });
|
return await api.post(`${BASE_URL_API}validate/code`, { code });
|
||||||
}
|
}
|
||||||
|
|
@ -77,7 +77,7 @@ export async function postValidateCode(
|
||||||
export async function postValidatePrompt(
|
export async function postValidatePrompt(
|
||||||
name: string,
|
name: string,
|
||||||
template: string,
|
template: string,
|
||||||
frontend_node: APIClassType,
|
frontend_node: APIClassType
|
||||||
): Promise<AxiosResponse<PromptTypeAPI>> {
|
): Promise<AxiosResponse<PromptTypeAPI>> {
|
||||||
return api.post(`${BASE_URL_API}validate/prompt`, {
|
return api.post(`${BASE_URL_API}validate/prompt`, {
|
||||||
name,
|
name,
|
||||||
|
|
@ -150,7 +150,7 @@ export async function saveFlowToDatabase(newFlow: {
|
||||||
* @throws Will throw an error if the update fails.
|
* @throws Will throw an error if the update fails.
|
||||||
*/
|
*/
|
||||||
export async function updateFlowInDatabase(
|
export async function updateFlowInDatabase(
|
||||||
updatedFlow: FlowType,
|
updatedFlow: FlowType
|
||||||
): Promise<FlowType> {
|
): Promise<FlowType> {
|
||||||
try {
|
try {
|
||||||
const response = await api.patch(`${BASE_URL_API}flows/${updatedFlow.id}`, {
|
const response = await api.patch(`${BASE_URL_API}flows/${updatedFlow.id}`, {
|
||||||
|
|
@ -328,7 +328,7 @@ export async function getHealth() {
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
export async function getBuildStatus(
|
export async function getBuildStatus(
|
||||||
flowId: string,
|
flowId: string
|
||||||
): Promise<AxiosResponse<BuildStatusTypeAPI>> {
|
): Promise<AxiosResponse<BuildStatusTypeAPI>> {
|
||||||
return await api.get(`${BASE_URL_API}build/${flowId}/status`);
|
return await api.get(`${BASE_URL_API}build/${flowId}/status`);
|
||||||
}
|
}
|
||||||
|
|
@ -341,7 +341,7 @@ export async function getBuildStatus(
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
export async function postBuildInit(
|
export async function postBuildInit(
|
||||||
flow: FlowType,
|
flow: FlowType
|
||||||
): Promise<AxiosResponse<InitTypeAPI>> {
|
): Promise<AxiosResponse<InitTypeAPI>> {
|
||||||
return await api.post(`${BASE_URL_API}build/init/${flow.id}`, flow);
|
return await api.post(`${BASE_URL_API}build/init/${flow.id}`, flow);
|
||||||
}
|
}
|
||||||
|
|
@ -357,7 +357,7 @@ export async function postBuildInit(
|
||||||
*/
|
*/
|
||||||
export async function uploadFile(
|
export async function uploadFile(
|
||||||
file: File,
|
file: File,
|
||||||
id: string,
|
id: string
|
||||||
): Promise<AxiosResponse<UploadFileTypeAPI>> {
|
): Promise<AxiosResponse<UploadFileTypeAPI>> {
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
formData.append("file", file);
|
formData.append("file", file);
|
||||||
|
|
@ -366,7 +366,7 @@ export async function uploadFile(
|
||||||
|
|
||||||
export async function postCustomComponent(
|
export async function postCustomComponent(
|
||||||
code: string,
|
code: string,
|
||||||
apiClass: APIClassType,
|
apiClass: APIClassType
|
||||||
): Promise<AxiosResponse<APIClassType>> {
|
): Promise<AxiosResponse<APIClassType>> {
|
||||||
// let template = apiClass.template;
|
// let template = apiClass.template;
|
||||||
return await api.post(`${BASE_URL_API}custom_component`, {
|
return await api.post(`${BASE_URL_API}custom_component`, {
|
||||||
|
|
@ -379,7 +379,7 @@ export async function postCustomComponentUpdate(
|
||||||
code: string,
|
code: string,
|
||||||
template: APITemplateType,
|
template: APITemplateType,
|
||||||
field: string,
|
field: string,
|
||||||
field_value: any,
|
field_value: any
|
||||||
): Promise<AxiosResponse<APIClassType>> {
|
): Promise<AxiosResponse<APIClassType>> {
|
||||||
return await api.post(`${BASE_URL_API}custom_component/update`, {
|
return await api.post(`${BASE_URL_API}custom_component/update`, {
|
||||||
code,
|
code,
|
||||||
|
|
@ -401,7 +401,7 @@ export async function onLogin(user: LoginType) {
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/x-www-form-urlencoded",
|
"Content-Type": "application/x-www-form-urlencoded",
|
||||||
},
|
},
|
||||||
},
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
if (response.status === 200) {
|
if (response.status === 200) {
|
||||||
|
|
@ -463,11 +463,11 @@ export async function addUser(user: UserInputType): Promise<Array<Users>> {
|
||||||
|
|
||||||
export async function getUsersPage(
|
export async function getUsersPage(
|
||||||
skip: number,
|
skip: number,
|
||||||
limit: number,
|
limit: number
|
||||||
): Promise<Array<Users>> {
|
): Promise<Array<Users>> {
|
||||||
try {
|
try {
|
||||||
const res = await api.get(
|
const res = await api.get(
|
||||||
`${BASE_URL_API}users/?skip=${skip}&limit=${limit}`,
|
`${BASE_URL_API}users/?skip=${skip}&limit=${limit}`
|
||||||
);
|
);
|
||||||
if (res.status === 200) {
|
if (res.status === 200) {
|
||||||
return res.data;
|
return res.data;
|
||||||
|
|
@ -504,7 +504,7 @@ export async function resetPassword(user_id: string, user: resetPasswordType) {
|
||||||
try {
|
try {
|
||||||
const res = await api.patch(
|
const res = await api.patch(
|
||||||
`${BASE_URL_API}users/${user_id}/reset-password`,
|
`${BASE_URL_API}users/${user_id}/reset-password`,
|
||||||
user,
|
user
|
||||||
);
|
);
|
||||||
if (res.status === 200) {
|
if (res.status === 200) {
|
||||||
return res.data;
|
return res.data;
|
||||||
|
|
@ -578,7 +578,7 @@ export async function saveFlowStore(
|
||||||
last_tested_version?: string;
|
last_tested_version?: string;
|
||||||
},
|
},
|
||||||
tags: string[],
|
tags: string[],
|
||||||
publicFlow = false,
|
publicFlow = false
|
||||||
): Promise<FlowType> {
|
): Promise<FlowType> {
|
||||||
try {
|
try {
|
||||||
const response = await api.post(`${BASE_URL_API}store/components/`, {
|
const response = await api.post(`${BASE_URL_API}store/components/`, {
|
||||||
|
|
@ -707,7 +707,7 @@ export async function postStoreComponents(component: Component) {
|
||||||
export async function getComponent(component_id: string) {
|
export async function getComponent(component_id: string) {
|
||||||
try {
|
try {
|
||||||
const res = await api.get(
|
const res = await api.get(
|
||||||
`${BASE_URL_API}store/components/${component_id}`,
|
`${BASE_URL_API}store/components/${component_id}`
|
||||||
);
|
);
|
||||||
if (res.status === 200) {
|
if (res.status === 200) {
|
||||||
return res.data;
|
return res.data;
|
||||||
|
|
@ -722,7 +722,7 @@ export async function searchComponent(
|
||||||
page?: number | null,
|
page?: number | null,
|
||||||
limit?: number | null,
|
limit?: number | null,
|
||||||
status?: string | null,
|
status?: string | null,
|
||||||
tags?: string[],
|
tags?: string[]
|
||||||
): Promise<StoreComponentResponse | undefined> {
|
): Promise<StoreComponentResponse | undefined> {
|
||||||
try {
|
try {
|
||||||
let url = `${BASE_URL_API}store/components/`;
|
let url = `${BASE_URL_API}store/components/`;
|
||||||
|
|
@ -834,7 +834,7 @@ export async function updateFlowStore(
|
||||||
},
|
},
|
||||||
tags: string[],
|
tags: string[],
|
||||||
publicFlow = false,
|
publicFlow = false,
|
||||||
id: string,
|
id: string
|
||||||
): Promise<FlowType> {
|
): Promise<FlowType> {
|
||||||
try {
|
try {
|
||||||
const response = await api.patch(`${BASE_URL_API}store/components/${id}`, {
|
const response = await api.patch(`${BASE_URL_API}store/components/${id}`, {
|
||||||
|
|
@ -918,7 +918,7 @@ export async function deleteGlobalVariable(id: string) {
|
||||||
export async function updateGlobalVariable(
|
export async function updateGlobalVariable(
|
||||||
name: string,
|
name: string,
|
||||||
value: string,
|
value: string,
|
||||||
id: string,
|
id: string
|
||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
const response = api.patch(`${BASE_URL_API}variables/${id}`, {
|
const response = api.patch(`${BASE_URL_API}variables/${id}`, {
|
||||||
|
|
@ -937,7 +937,7 @@ export async function getVerticesOrder(
|
||||||
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
|
||||||
|
|
@ -957,7 +957,7 @@ export async function getVerticesOrder(
|
||||||
return await api.post(
|
return await api.post(
|
||||||
`${BASE_URL_API}build/${flowId}/vertices`,
|
`${BASE_URL_API}build/${flowId}/vertices`,
|
||||||
data,
|
data,
|
||||||
config,
|
config
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -965,7 +965,7 @@ export async function postBuildVertex(
|
||||||
flowId: string,
|
flowId: string,
|
||||||
vertexId: string,
|
vertexId: string,
|
||||||
input_value: string,
|
input_value: string,
|
||||||
files?: string[],
|
files?: string[]
|
||||||
): Promise<AxiosResponse<VertexBuildTypeAPI>> {
|
): Promise<AxiosResponse<VertexBuildTypeAPI>> {
|
||||||
// input_value is optional and is a query parameter
|
// input_value is optional and is a query parameter
|
||||||
const data = input_value
|
const data = input_value
|
||||||
|
|
@ -976,7 +976,7 @@ export async function postBuildVertex(
|
||||||
}
|
}
|
||||||
return await api.post(
|
return await api.post(
|
||||||
`${BASE_URL_API}build/${flowId}/vertices/${vertexId}`,
|
`${BASE_URL_API}build/${flowId}/vertices/${vertexId}`,
|
||||||
data,
|
data
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1000,7 +1000,7 @@ export async function getFlowPool({
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function deleteFlowPool(
|
export async function deleteFlowPool(
|
||||||
flowId: string,
|
flowId: string
|
||||||
): Promise<AxiosResponse<any>> {
|
): Promise<AxiosResponse<any>> {
|
||||||
const config = {};
|
const config = {};
|
||||||
config["params"] = { flow_id: flowId };
|
config["params"] = { flow_id: flowId };
|
||||||
|
|
@ -1014,7 +1014,7 @@ export async function deleteFlowPool(
|
||||||
* @returns A promise that resolves to an array of AxiosResponse objects representing the delete responses.
|
* @returns A promise that resolves to an array of AxiosResponse objects representing the delete responses.
|
||||||
*/
|
*/
|
||||||
export async function multipleDeleteFlowsComponents(
|
export async function multipleDeleteFlowsComponents(
|
||||||
flowIds: string[],
|
flowIds: string[]
|
||||||
): Promise<AxiosResponse<any>[]> {
|
): Promise<AxiosResponse<any>[]> {
|
||||||
const batches: string[][] = [];
|
const batches: string[][] = [];
|
||||||
|
|
||||||
|
|
@ -1037,7 +1037,7 @@ export async function multipleDeleteFlowsComponents(
|
||||||
|
|
||||||
// Execute all delete requests
|
// Execute all delete requests
|
||||||
const responses: Promise<AxiosResponse<any>>[] = batches.map((batch) =>
|
const responses: Promise<AxiosResponse<any>>[] = batches.map((batch) =>
|
||||||
deleteBatch(batch),
|
deleteBatch(batch)
|
||||||
);
|
);
|
||||||
|
|
||||||
// Return the responses after all requests are completed
|
// Return the responses after all requests are completed
|
||||||
|
|
@ -1047,7 +1047,7 @@ export async function multipleDeleteFlowsComponents(
|
||||||
export async function getTransactionTable(
|
export async function getTransactionTable(
|
||||||
id: string,
|
id: string,
|
||||||
mode: "intersection" | "union",
|
mode: "intersection" | "union",
|
||||||
params = {},
|
params = {}
|
||||||
): Promise<{ rows: Array<object>; columns: Array<ColDef | ColGroupDef> }> {
|
): Promise<{ rows: Array<object>; columns: Array<ColDef | ColGroupDef> }> {
|
||||||
const config = {};
|
const config = {};
|
||||||
config["params"] = { flow_id: id };
|
config["params"] = { flow_id: id };
|
||||||
|
|
@ -1063,7 +1063,7 @@ export async function getMessagesTable(
|
||||||
mode: "intersection" | "union",
|
mode: "intersection" | "union",
|
||||||
id?: string,
|
id?: string,
|
||||||
excludedFields?: string[],
|
excludedFields?: string[],
|
||||||
params = {},
|
params = {}
|
||||||
): Promise<{ rows: Array<Message>; columns: Array<ColDef | ColGroupDef> }> {
|
): Promise<{ rows: Array<Message>; columns: Array<ColDef | ColGroupDef> }> {
|
||||||
const config = {};
|
const config = {};
|
||||||
if (id) {
|
if (id) {
|
||||||
|
|
|
||||||
|
|
@ -98,7 +98,7 @@ export default function ParameterComponent({
|
||||||
debouncedHandleUpdateValues,
|
debouncedHandleUpdateValues,
|
||||||
setNode,
|
setNode,
|
||||||
renderTooltips,
|
renderTooltips,
|
||||||
setIsLoading,
|
setIsLoading
|
||||||
);
|
);
|
||||||
|
|
||||||
const { handleNodeClass: handleNodeClassHook } = useHandleNodeClass(
|
const { handleNodeClass: handleNodeClassHook } = useHandleNodeClass(
|
||||||
|
|
@ -107,7 +107,7 @@ export default function ParameterComponent({
|
||||||
takeSnapshot,
|
takeSnapshot,
|
||||||
setNode,
|
setNode,
|
||||||
updateNodeInternals,
|
updateNodeInternals,
|
||||||
renderTooltips,
|
renderTooltips
|
||||||
);
|
);
|
||||||
|
|
||||||
const { handleRefreshButtonPress: handleRefreshButtonPressHook } =
|
const { handleRefreshButtonPress: handleRefreshButtonPressHook } =
|
||||||
|
|
@ -116,7 +116,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 handleRefreshButtonPress = async (name, data) => {
|
const handleRefreshButtonPress = async (name, data) => {
|
||||||
|
|
@ -129,12 +129,12 @@ export default function ParameterComponent({
|
||||||
handleUpdateValues,
|
handleUpdateValues,
|
||||||
setNode,
|
setNode,
|
||||||
renderTooltips,
|
renderTooltips,
|
||||||
setIsLoading,
|
setIsLoading
|
||||||
);
|
);
|
||||||
|
|
||||||
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> => {
|
||||||
handleOnNewValueHook(newValue, skipSnapshot);
|
handleOnNewValueHook(newValue, skipSnapshot);
|
||||||
};
|
};
|
||||||
|
|
@ -216,7 +216,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,
|
||||||
|
|
@ -334,7 +334,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={{ borderColor: color ?? nodeColors.unknown }}
|
style={{ borderColor: color ?? nodeColors.unknown }}
|
||||||
onClick={() => setFilterEdge(groupedEdge.current)}
|
onClick={() => setFilterEdge(groupedEdge.current)}
|
||||||
|
|
@ -430,7 +430,7 @@ export default function ParameterComponent({
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
name={name}
|
name={name}
|
||||||
data={data}
|
data={data.node?.template[name]}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
{data.node?.template[name]?.refresh_button && (
|
{data.node?.template[name]?.refresh_button && (
|
||||||
|
|
@ -486,8 +486,8 @@ export default function ParameterComponent({
|
||||||
data.node?.template[name]?.real_time_refresh)
|
data.node?.template[name]?.real_time_refresh)
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<div className="mt-2 flex w-full items-center">
|
<div className="mt-2 flex w-full items-center gap-2">
|
||||||
<div className="w-5/6 flex-grow">
|
<div className="flex-1">
|
||||||
<Dropdown
|
<Dropdown
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
isLoading={isLoading}
|
isLoading={isLoading}
|
||||||
|
|
@ -505,7 +505,6 @@ export default function ParameterComponent({
|
||||||
name={name}
|
name={name}
|
||||||
data={data}
|
data={data}
|
||||||
button_text={data.node?.template[name]?.refresh_button_text}
|
button_text={data.node?.template[name]?.refresh_button_text}
|
||||||
className="extra-side-bar-buttons ml-2 mt-1"
|
|
||||||
handleUpdateValues={handleRefreshButtonPress}
|
handleUpdateValues={handleRefreshButtonPress}
|
||||||
id={"refresh-button-" + name}
|
id={"refresh-button-" + name}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -54,10 +54,10 @@ export default function GenericNode({
|
||||||
const setErrorData = useAlertStore((state) => state.setErrorData);
|
const setErrorData = useAlertStore((state) => state.setErrorData);
|
||||||
const isDark = useDarkStore((state) => state.dark);
|
const isDark = useDarkStore((state) => state.dark);
|
||||||
const buildStatus = useFlowStore(
|
const buildStatus = useFlowStore(
|
||||||
(state) => state.flowBuildStatus[data.id]?.status,
|
(state) => state.flowBuildStatus[data.id]?.status
|
||||||
);
|
);
|
||||||
const lastRunTime = useFlowStore(
|
const lastRunTime = useFlowStore(
|
||||||
(state) => state.flowBuildStatus[data.id]?.timestamp,
|
(state) => state.flowBuildStatus[data.id]?.timestamp
|
||||||
);
|
);
|
||||||
const takeSnapshot = useFlowsManagerStore((state) => state.takeSnapshot);
|
const takeSnapshot = useFlowsManagerStore((state) => state.takeSnapshot);
|
||||||
|
|
||||||
|
|
@ -65,7 +65,7 @@ export default function GenericNode({
|
||||||
const [nodeName, setNodeName] = useState(data.node!.display_name);
|
const [nodeName, setNodeName] = useState(data.node!.display_name);
|
||||||
const [inputDescription, setInputDescription] = useState(false);
|
const [inputDescription, setInputDescription] = useState(false);
|
||||||
const [nodeDescription, setNodeDescription] = useState(
|
const [nodeDescription, setNodeDescription] = useState(
|
||||||
data.node?.description!,
|
data.node?.description!
|
||||||
);
|
);
|
||||||
const [isOutdated, setIsOutdated] = useState(false);
|
const [isOutdated, setIsOutdated] = useState(false);
|
||||||
const [validationStatus, setValidationStatus] =
|
const [validationStatus, setValidationStatus] =
|
||||||
|
|
@ -83,7 +83,7 @@ export default function GenericNode({
|
||||||
data.node!,
|
data.node!,
|
||||||
setNode,
|
setNode,
|
||||||
setIsOutdated,
|
setIsOutdated,
|
||||||
updateNodeInternals,
|
updateNodeInternals
|
||||||
);
|
);
|
||||||
|
|
||||||
const name = nodeIconsLucide[data.type] ? data.type : types[data.type];
|
const name = nodeIconsLucide[data.type] ? data.type : types[data.type];
|
||||||
|
|
@ -114,12 +114,12 @@ export default function GenericNode({
|
||||||
selected: boolean,
|
selected: boolean,
|
||||||
showNode: boolean,
|
showNode: boolean,
|
||||||
buildStatus: BuildStatus | undefined,
|
buildStatus: BuildStatus | undefined,
|
||||||
validationStatus: VertexBuildTypeAPI | null,
|
validationStatus: validationStatusType | null
|
||||||
) => {
|
) => {
|
||||||
const specificClassFromBuildStatus = getSpecificClassFromBuildStatus(
|
const specificClassFromBuildStatus = getSpecificClassFromBuildStatus(
|
||||||
buildStatus,
|
buildStatus,
|
||||||
validationStatus,
|
validationStatus,
|
||||||
isDark,
|
isDark
|
||||||
);
|
);
|
||||||
|
|
||||||
const baseBorderClass = getBaseBorderClass(selected);
|
const baseBorderClass = getBaseBorderClass(selected);
|
||||||
|
|
@ -128,7 +128,7 @@ export default function GenericNode({
|
||||||
baseBorderClass,
|
baseBorderClass,
|
||||||
nodeSizeClass,
|
nodeSizeClass,
|
||||||
"generic-node-div",
|
"generic-node-div",
|
||||||
specificClassFromBuildStatus,
|
specificClassFromBuildStatus
|
||||||
);
|
);
|
||||||
return names;
|
return names;
|
||||||
};
|
};
|
||||||
|
|
@ -170,7 +170,7 @@ export default function GenericNode({
|
||||||
showNode,
|
showNode,
|
||||||
isEmoji,
|
isEmoji,
|
||||||
nodeIconFragment,
|
nodeIconFragment,
|
||||||
checkNodeIconFragment,
|
checkNodeIconFragment
|
||||||
);
|
);
|
||||||
|
|
||||||
function countHandles(): void {
|
function countHandles(): void {
|
||||||
|
|
@ -247,7 +247,7 @@ export default function GenericNode({
|
||||||
selected,
|
selected,
|
||||||
showNode,
|
showNode,
|
||||||
buildStatus,
|
buildStatus,
|
||||||
validationStatus,
|
validationStatus
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
{data.node?.beta && showNode && (
|
{data.node?.beta && showNode && (
|
||||||
|
|
@ -378,7 +378,7 @@ export default function GenericNode({
|
||||||
}
|
}
|
||||||
title={getFieldTitle(
|
title={getFieldTitle(
|
||||||
data.node?.template!,
|
data.node?.template!,
|
||||||
templateField,
|
templateField
|
||||||
)}
|
)}
|
||||||
info={data.node?.template[templateField].info}
|
info={data.node?.template[templateField].info}
|
||||||
name={templateField}
|
name={templateField}
|
||||||
|
|
@ -406,7 +406,7 @@ export default function GenericNode({
|
||||||
proxy={data.node?.template[templateField].proxy}
|
proxy={data.node?.template[templateField].proxy}
|
||||||
showNode={showNode}
|
showNode={showNode}
|
||||||
/>
|
/>
|
||||||
),
|
)
|
||||||
)}
|
)}
|
||||||
<ParameterComponent
|
<ParameterComponent
|
||||||
key={scapedJSONStringfy({
|
key={scapedJSONStringfy({
|
||||||
|
|
@ -552,7 +552,7 @@ export default function GenericNode({
|
||||||
!data.node?.description) &&
|
!data.node?.description) &&
|
||||||
nameEditable
|
nameEditable
|
||||||
? "font-light italic"
|
? "font-light italic"
|
||||||
: "",
|
: ""
|
||||||
)}
|
)}
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
setInputDescription(true);
|
setInputDescription(true);
|
||||||
|
|
@ -614,13 +614,13 @@ export default function GenericNode({
|
||||||
}
|
}
|
||||||
title={getFieldTitle(
|
title={getFieldTitle(
|
||||||
data.node?.template!,
|
data.node?.template!,
|
||||||
templateField,
|
templateField
|
||||||
)}
|
)}
|
||||||
info={data.node?.template[templateField].info}
|
info={data.node?.template[templateField].info}
|
||||||
name={templateField}
|
name={templateField}
|
||||||
tooltipTitle={
|
tooltipTitle={
|
||||||
data.node?.template[templateField].input_types?.join(
|
data.node?.template[templateField].input_types?.join(
|
||||||
"\n",
|
"\n"
|
||||||
) ?? data.node?.template[templateField].type
|
) ?? data.node?.template[templateField].type
|
||||||
}
|
}
|
||||||
required={data.node!.template[templateField].required}
|
required={data.node!.template[templateField].required}
|
||||||
|
|
@ -647,7 +647,7 @@ export default function GenericNode({
|
||||||
<div
|
<div
|
||||||
className={classNames(
|
className={classNames(
|
||||||
Object.keys(data.node!.template).length < 1 ? "hidden" : "",
|
Object.keys(data.node!.template).length < 1 ? "hidden" : "",
|
||||||
"flex-max-width justify-center",
|
"flex-max-width justify-center"
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
{" "}
|
{" "}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ import { APITemplateType } from "../../types/api";
|
||||||
|
|
||||||
export default function getFieldTitle(
|
export default function getFieldTitle(
|
||||||
template: APITemplateType,
|
template: APITemplateType,
|
||||||
templateField: string,
|
templateField: string
|
||||||
): string {
|
): string {
|
||||||
return template[templateField].display_name
|
return template[templateField].display_name
|
||||||
? template[templateField].display_name!
|
? template[templateField].display_name!
|
||||||
|
|
|
||||||
25
src/frontend/src/icons/Streamlit/SvgStreamlit.jsx
Normal file
25
src/frontend/src/icons/Streamlit/SvgStreamlit.jsx
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
export default function SvgStreamlit(props) {
|
||||||
|
return (
|
||||||
|
<svg
|
||||||
|
width="301"
|
||||||
|
height="165"
|
||||||
|
viewBox="0 0 301 165"
|
||||||
|
fill="none"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M150.731 101.547L98.1387 73.7471L6.84674 25.4969C6.7634 25.4136 6.59674 25.4136 6.51341 25.4136C3.18007 23.8303 -0.236608 27.1636 1.0134 30.497L47.5302 149.139L47.5385 149.164C47.5885 149.281 47.6302 149.397 47.6802 149.514C49.5885 153.939 53.7552 156.672 58.2886 157.747C58.6719 157.831 58.9461 157.906 59.4064 157.998C59.8645 158.1 60.5052 158.239 61.0552 158.281C61.1469 158.289 61.2302 158.289 61.3219 158.297H61.3886C61.4552 158.306 61.5219 158.306 61.5886 158.314H61.6802C61.7386 158.322 61.8052 158.322 61.8636 158.322H61.9719C62.0386 158.331 62.1052 158.331 62.1719 158.331V158.331C121.084 164.754 180.519 164.754 239.431 158.331V158.331C240.139 158.331 240.831 158.297 241.497 158.231C241.714 158.206 241.922 158.181 242.131 158.156C242.156 158.147 242.189 158.147 242.214 158.139C242.356 158.122 242.497 158.097 242.639 158.072C242.847 158.047 243.056 158.006 243.264 157.964C243.681 157.872 243.87 157.806 244.436 157.611C245.001 157.417 245.94 157.077 246.527 156.794C247.115 156.511 247.522 156.239 248.014 155.931C248.622 155.547 249.201 155.155 249.788 154.715C250.041 154.521 250.214 154.397 250.397 154.222L250.297 154.164L150.731 101.547Z"
|
||||||
|
fill="#FF4B4B"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
d="M294.766 25.4981H294.683L203.357 73.7483L254.124 149.357L300.524 30.4981V30.3315C301.691 26.8314 298.108 23.6648 294.766 25.4981"
|
||||||
|
fill="#7D353B"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
d="M155.598 2.55572C153.264 -0.852624 148.181 -0.852624 145.931 2.55572L98.1389 73.7477L150.731 101.548L250.398 154.222C251.024 153.609 251.526 153.012 252.056 152.381C252.806 151.456 253.506 150.465 254.123 149.356L203.356 73.7477L155.598 2.55572Z"
|
||||||
|
fill="#BD4043"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
}
|
||||||
8
src/frontend/src/icons/Streamlit/index.tsx
Normal file
8
src/frontend/src/icons/Streamlit/index.tsx
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
import React, { forwardRef } from "react";
|
||||||
|
import SvgStreamlit from "./SvgStreamlit";
|
||||||
|
|
||||||
|
export const Streamlit = forwardRef<SVGSVGElement, React.PropsWithChildren<{}>>(
|
||||||
|
(props, ref) => {
|
||||||
|
return <SvgStreamlit className="icon" ref={ref} {...props} />;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
@ -27,7 +27,7 @@ const useFolderSubmit = (setOpen, folderToEdit) => {
|
||||||
getFoldersApi(true);
|
getFoldersApi(true);
|
||||||
setOpen(false);
|
setOpen(false);
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
addFolder(data).then(
|
addFolder(data).then(
|
||||||
|
|
@ -42,7 +42,7 @@ const useFolderSubmit = (setOpen, folderToEdit) => {
|
||||||
setErrorData({
|
setErrorData({
|
||||||
title: `Error creating folder.`,
|
title: `Error creating folder.`,
|
||||||
});
|
});
|
||||||
},
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -114,19 +114,19 @@ export default function ChatMessage({
|
||||||
<div
|
<div
|
||||||
className={classNames(
|
className={classNames(
|
||||||
"form-modal-chat-position",
|
"form-modal-chat-position",
|
||||||
chat.isSend ? "" : " ",
|
chat.isSend ? "" : " "
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className={classNames(
|
className={classNames(
|
||||||
"mr-3 mt-1 flex w-24 flex-col items-center gap-1 overflow-hidden px-3 pb-3",
|
"mr-3 mt-1 flex w-24 flex-col items-center gap-1 overflow-hidden px-3 pb-3"
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<div className="flex flex-col items-center gap-1">
|
<div className="flex flex-col items-center gap-1">
|
||||||
<div
|
<div
|
||||||
className={cn(
|
className={cn(
|
||||||
"relative flex h-8 w-8 items-center justify-center overflow-hidden rounded-md p-5 text-2xl",
|
"relative flex h-8 w-8 items-center justify-center overflow-hidden rounded-md p-5 text-2xl",
|
||||||
!chat.isSend ? "bg-chat-bot-icon" : "bg-chat-user-icon",
|
!chat.isSend ? "bg-chat-bot-icon" : "bg-chat-user-icon"
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
|
|
@ -210,12 +210,12 @@ dark:prose-invert"
|
||||||
|
|
||||||
children[0] = (children[0] as string).replace(
|
children[0] = (children[0] as string).replace(
|
||||||
"`▍`",
|
"`▍`",
|
||||||
"▍",
|
"▍"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const match = /language-(\w+)/.exec(
|
const match = /language-(\w+)/.exec(
|
||||||
className || "",
|
className || ""
|
||||||
);
|
);
|
||||||
|
|
||||||
return !inline ? (
|
return !inline ? (
|
||||||
|
|
@ -230,7 +230,7 @@ dark:prose-invert"
|
||||||
language: (match && match[1]) || "",
|
language: (match && match[1]) || "",
|
||||||
code: String(children).replace(
|
code: String(children).replace(
|
||||||
/\n$/,
|
/\n$/,
|
||||||
"",
|
""
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
|
|
@ -248,7 +248,7 @@ dark:prose-invert"
|
||||||
{chatMessage}
|
{chatMessage}
|
||||||
</Markdown>
|
</Markdown>
|
||||||
),
|
),
|
||||||
[chat.message, chatMessage],
|
[chat.message, chatMessage]
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,6 @@
|
||||||
import { useEffect, useRef, useState } from "react";
|
import { useEffect, useRef, useState } from "react";
|
||||||
import IconComponent from "../../../../components/genericIconComponent";
|
import IconComponent from "../../../../components/genericIconComponent";
|
||||||
import {
|
import { Button } from "../../../../components/ui/button";
|
||||||
Select,
|
|
||||||
SelectContent,
|
|
||||||
SelectItem,
|
|
||||||
SelectTrigger,
|
|
||||||
} from "../../../../components/ui/select";
|
|
||||||
import {
|
import {
|
||||||
CHAT_FIRST_INITIAL_TEXT,
|
CHAT_FIRST_INITIAL_TEXT,
|
||||||
CHAT_SECOND_INITIAL_TEXT,
|
CHAT_SECOND_INITIAL_TEXT,
|
||||||
|
|
@ -67,7 +62,7 @@ export default function ChatView({
|
||||||
.sort((a, b) => Date.parse(a.timestamp) - Date.parse(b.timestamp))
|
.sort((a, b) => Date.parse(a.timestamp) - Date.parse(b.timestamp))
|
||||||
//
|
//
|
||||||
.filter(
|
.filter(
|
||||||
(output) => output.data.messages && output.data.messages.length > 0,
|
(output) => output.data.messages && output.data.messages.length > 0
|
||||||
)
|
)
|
||||||
.map((output, index) => {
|
.map((output, index) => {
|
||||||
try {
|
try {
|
||||||
|
|
@ -136,7 +131,7 @@ export default function ChatView({
|
||||||
function updateChat(
|
function updateChat(
|
||||||
chat: ChatMessageType,
|
chat: ChatMessageType,
|
||||||
message: string,
|
message: string,
|
||||||
stream_url?: string,
|
stream_url?: string
|
||||||
) {
|
) {
|
||||||
// if (message === "") return;
|
// if (message === "") return;
|
||||||
chat.message = message;
|
chat.message = message;
|
||||||
|
|
@ -164,19 +159,21 @@ export default function ChatView({
|
||||||
<div className="eraser-column-arrangement">
|
<div className="eraser-column-arrangement">
|
||||||
<div className="eraser-size">
|
<div className="eraser-size">
|
||||||
<div className="eraser-position">
|
<div className="eraser-position">
|
||||||
<button
|
<Button
|
||||||
className="flex gap-1"
|
className="flex gap-1"
|
||||||
|
size="none"
|
||||||
|
variant="none"
|
||||||
onClick={() => handleSelectChange("builds")}
|
onClick={() => handleSelectChange("builds")}
|
||||||
>
|
>
|
||||||
<IconComponent
|
<IconComponent
|
||||||
name="Eraser"
|
name="Eraser"
|
||||||
className={classNames(
|
className={classNames(
|
||||||
"h-5 w-5 transition-all duration-100",
|
"h-5 w-5 transition-all duration-100",
|
||||||
lockChat ? "animate-pulse text-primary" : "text-primary",
|
lockChat ? "animate-pulse text-primary" : "text-primary"
|
||||||
)}
|
)}
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
/>
|
/>
|
||||||
</button>
|
</Button>
|
||||||
{/* <Select
|
{/* <Select
|
||||||
onValueChange={handleSelectChange}
|
onValueChange={handleSelectChange}
|
||||||
value=""
|
value=""
|
||||||
|
|
|
||||||
|
|
@ -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() {
|
||||||
|
|
@ -161,7 +161,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
|
||||||
|
|
@ -197,11 +197,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
|
||||||
|
|
@ -265,11 +265,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
|
||||||
|
|
@ -336,7 +336,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">
|
||||||
|
|
@ -355,7 +355,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}
|
||||||
|
|
@ -377,7 +377,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 ? (
|
||||||
|
|
@ -409,7 +409,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"
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ export function getCurlRunCode(
|
||||||
flowId: string,
|
flowId: string,
|
||||||
isAuth: boolean,
|
isAuth: boolean,
|
||||||
tweaksBuildedObject,
|
tweaksBuildedObject,
|
||||||
endpointName?: string,
|
endpointName?: string
|
||||||
): string {
|
): string {
|
||||||
const tweaksObject = tweaksBuildedObject[0];
|
const tweaksObject = tweaksBuildedObject[0];
|
||||||
// show the endpoint name in the curl command if it exists
|
// show the endpoint name in the curl command if it exists
|
||||||
|
|
|
||||||
|
|
@ -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"]);
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
*/
|
*/
|
||||||
export default function getPythonCode(
|
export default function getPythonCode(
|
||||||
flowName: string,
|
flowName: string,
|
||||||
tweaksBuildedObject,
|
tweaksBuildedObject
|
||||||
): string {
|
): string {
|
||||||
const tweaksObject = tweaksBuildedObject[0];
|
const tweaksObject = tweaksBuildedObject[0];
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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 ?? "";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
export default function getWidgetCode(
|
export default function getWidgetCode(
|
||||||
flowId: string,
|
flowId: string,
|
||||||
flowName: string,
|
flowName: string,
|
||||||
isAuth: boolean,
|
isAuth: boolean
|
||||||
): string {
|
): string {
|
||||||
return `<script src="https://cdn.jsdelivr.net/gh/langflow-ai/langflow-embedded-chat@1.0_alpha/dist/build/static/js/bundle.min.js"></script>
|
return `<script src="https://cdn.jsdelivr.net/gh/langflow-ai/langflow-embedded-chat@1.0_alpha/dist/build/static/js/bundle.min.js"></script>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
export function createTabsArray(
|
export function createTabsArray(
|
||||||
codes,
|
codes,
|
||||||
includeWebhookCurl = false,
|
includeWebhookCurl = false,
|
||||||
includeTweaks = false,
|
includeTweaks = false
|
||||||
) {
|
) {
|
||||||
const tabs = [
|
const tabs = [
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ const ApiModal = forwardRef(
|
||||||
flow: FlowType;
|
flow: FlowType;
|
||||||
children: ReactNode;
|
children: ReactNode;
|
||||||
},
|
},
|
||||||
ref,
|
ref
|
||||||
) => {
|
) => {
|
||||||
const tweak = useTweaksStore((state) => state.tweak);
|
const tweak = useTweaksStore((state) => state.tweak);
|
||||||
const addTweaks = useTweaksStore((state) => state.setTweak);
|
const addTweaks = useTweaksStore((state) => state.setTweak);
|
||||||
|
|
@ -50,22 +50,21 @@ const ApiModal = forwardRef(
|
||||||
flow?.id,
|
flow?.id,
|
||||||
autoLogin,
|
autoLogin,
|
||||||
tweak,
|
tweak,
|
||||||
flow?.endpoint_name,
|
flow?.endpoint_name
|
||||||
);
|
);
|
||||||
const curl_run_code = getCurlRunCode(
|
const curl_run_code = getCurlRunCode(
|
||||||
flow?.id,
|
flow?.id,
|
||||||
autoLogin,
|
autoLogin,
|
||||||
tweak,
|
tweak,
|
||||||
flow?.endpoint_name,
|
flow?.endpoint_name
|
||||||
);
|
);
|
||||||
const curl_webhook_code = getCurlWebhookCode(
|
const curl_webhook_code = getCurlWebhookCode(
|
||||||
flow?.id,
|
flow?.id,
|
||||||
autoLogin,
|
autoLogin,
|
||||||
flow?.endpoint_name,
|
flow?.endpoint_name
|
||||||
);
|
);
|
||||||
const pythonCode = getPythonCode(flow?.name, tweak);
|
const pythonCode = getPythonCode(flow?.name, tweak);
|
||||||
const widgetCode = getWidgetCode(flow?.id, flow?.name, autoLogin);
|
const widgetCode = getWidgetCode(flow?.id, flow?.name, autoLogin);
|
||||||
|
|
||||||
const includeWebhook = flow.webhook;
|
const includeWebhook = flow.webhook;
|
||||||
const tweaksCode = buildTweaks(flow);
|
const tweaksCode = buildTweaks(flow);
|
||||||
const codesArray = [
|
const codesArray = [
|
||||||
|
|
@ -77,7 +76,7 @@ const ApiModal = forwardRef(
|
||||||
pythonCode,
|
pythonCode,
|
||||||
];
|
];
|
||||||
const [tabs, setTabs] = useState(
|
const [tabs, setTabs] = useState(
|
||||||
createTabsArray(codesArray, includeWebhook),
|
createTabsArray(codesArray, includeWebhook)
|
||||||
);
|
);
|
||||||
|
|
||||||
const canShowTweaks =
|
const canShowTweaks =
|
||||||
|
|
@ -126,7 +125,7 @@ const ApiModal = forwardRef(
|
||||||
buildTweakObject(
|
buildTweakObject(
|
||||||
nodeId,
|
nodeId,
|
||||||
element.data.node.template[templateField].value,
|
element.data.node.template[templateField].value,
|
||||||
element.data.node.template[templateField],
|
element.data.node.template[templateField]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -143,7 +142,7 @@ const ApiModal = forwardRef(
|
||||||
async function buildTweakObject(
|
async function buildTweakObject(
|
||||||
tw: string,
|
tw: string,
|
||||||
changes: string | string[] | boolean | number | Object[] | Object,
|
changes: string | string[] | boolean | number | Object[] | Object,
|
||||||
template: TemplateVariableType,
|
template: TemplateVariableType
|
||||||
) {
|
) {
|
||||||
changes = getChangesType(changes, template);
|
changes = getChangesType(changes, template);
|
||||||
|
|
||||||
|
|
@ -185,7 +184,7 @@ const ApiModal = forwardRef(
|
||||||
flow?.id,
|
flow?.id,
|
||||||
autoLogin,
|
autoLogin,
|
||||||
cloneTweak,
|
cloneTweak,
|
||||||
flow?.endpoint_name,
|
flow?.endpoint_name
|
||||||
);
|
);
|
||||||
const pythonCode = getPythonCode(flow?.name, cloneTweak);
|
const pythonCode = getPythonCode(flow?.name, cloneTweak);
|
||||||
const widgetCode = getWidgetCode(flow?.id, flow?.name, autoLogin);
|
const widgetCode = getWidgetCode(flow?.id, flow?.name, autoLogin);
|
||||||
|
|
@ -229,7 +228,7 @@ const ApiModal = forwardRef(
|
||||||
</BaseModal.Content>
|
</BaseModal.Content>
|
||||||
</BaseModal>
|
</BaseModal>
|
||||||
);
|
);
|
||||||
},
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
export default ApiModal;
|
export default ApiModal;
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ export const switchCaseModalSize = (size: string) => {
|
||||||
switch (size) {
|
switch (size) {
|
||||||
case "x-small":
|
case "x-small":
|
||||||
minWidth = "min-w-[20vw]";
|
minWidth = "min-w-[20vw]";
|
||||||
height = "h-full";
|
height = "";
|
||||||
break;
|
break;
|
||||||
case "smaller":
|
case "smaller":
|
||||||
minWidth = "min-w-[40vw]";
|
minWidth = "min-w-[40vw]";
|
||||||
|
|
@ -12,7 +12,7 @@ export const switchCaseModalSize = (size: string) => {
|
||||||
break;
|
break;
|
||||||
case "smaller-h-full":
|
case "smaller-h-full":
|
||||||
minWidth = "min-w-[40vw]";
|
minWidth = "min-w-[40vw]";
|
||||||
height = "h-full";
|
height = "";
|
||||||
break;
|
break;
|
||||||
case "small":
|
case "small":
|
||||||
minWidth = "min-w-[40vw]";
|
minWidth = "min-w-[40vw]";
|
||||||
|
|
@ -20,16 +20,19 @@ export const switchCaseModalSize = (size: string) => {
|
||||||
break;
|
break;
|
||||||
case "small-h-full":
|
case "small-h-full":
|
||||||
minWidth = "min-w-[40vw]";
|
minWidth = "min-w-[40vw]";
|
||||||
height = "h-full";
|
height = "";
|
||||||
break;
|
break;
|
||||||
case "medium":
|
case "medium":
|
||||||
minWidth = "min-w-[60vw]";
|
minWidth = "min-w-[60vw]";
|
||||||
height = "h-[60vh]";
|
height = "h-[60vh]";
|
||||||
break;
|
break;
|
||||||
|
case "medium-tall":
|
||||||
|
minWidth = "min-w-[60vw]";
|
||||||
|
height = "h-[90vh]";
|
||||||
|
break;
|
||||||
case "medium-h-full":
|
case "medium-h-full":
|
||||||
minWidth = "min-w-[60vw]";
|
minWidth = "min-w-[60vw]";
|
||||||
height = "h-full";
|
height = "";
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case "large":
|
case "large":
|
||||||
minWidth = "min-w-[85vw]";
|
minWidth = "min-w-[85vw]";
|
||||||
|
|
@ -56,11 +59,11 @@ export const switchCaseModalSize = (size: string) => {
|
||||||
|
|
||||||
case "large-h-full":
|
case "large-h-full":
|
||||||
minWidth = "min-w-[80vw]";
|
minWidth = "min-w-[80vw]";
|
||||||
height = "h-full";
|
height = "";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
minWidth = "min-w-[80vw]";
|
minWidth = "min-w-[80vw]";
|
||||||
height = "h-[80vh]";
|
height = "h-[90vh]";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return { minWidth, height };
|
return { minWidth, height };
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ import { Button } from "../../components/ui/button";
|
||||||
import { modalHeaderType } from "../../types/components";
|
import { modalHeaderType } from "../../types/components";
|
||||||
import { cn } from "../../utils/utils";
|
import { cn } from "../../utils/utils";
|
||||||
import { switchCaseModalSize } from "./helpers/switch-case-size";
|
import { switchCaseModalSize } from "./helpers/switch-case-size";
|
||||||
|
import * as Form from "@radix-ui/react-form";
|
||||||
|
|
||||||
type ContentProps = { children: ReactNode };
|
type ContentProps = { children: ReactNode };
|
||||||
type HeaderProps = { children: ReactNode; description: string };
|
type HeaderProps = { children: ReactNode; description: string };
|
||||||
|
|
@ -52,10 +53,10 @@ const Trigger: React.FC<TriggerProps> = ({
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const Header: React.FC<{ children: ReactNode; description: string | null }> = ({
|
const Header: React.FC<{
|
||||||
children,
|
children: ReactNode;
|
||||||
description,
|
description: string | JSX.Element | null;
|
||||||
}: modalHeaderType): JSX.Element => {
|
}> = ({ children, description }: modalHeaderType): JSX.Element => {
|
||||||
return (
|
return (
|
||||||
<DialogHeader>
|
<DialogHeader>
|
||||||
<DialogTitle className="flex items-center">{children}</DialogTitle>
|
<DialogTitle className="flex items-center">{children}</DialogTitle>
|
||||||
|
|
@ -102,7 +103,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;
|
||||||
|
|
@ -111,6 +112,7 @@ interface BaseModalProps {
|
||||||
| "smaller"
|
| "smaller"
|
||||||
| "small"
|
| "small"
|
||||||
| "medium"
|
| "medium"
|
||||||
|
| "medium-tall"
|
||||||
| "large"
|
| "large"
|
||||||
| "three-cards"
|
| "three-cards"
|
||||||
| "large-thin"
|
| "large-thin"
|
||||||
|
|
@ -137,16 +139,16 @@ function BaseModal({
|
||||||
onSubmit,
|
onSubmit,
|
||||||
}: 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, height } = switchCaseModalSize(size);
|
let { minWidth, height } = switchCaseModalSize(size);
|
||||||
|
|
@ -180,31 +182,33 @@ function BaseModal({
|
||||||
) : (
|
) : (
|
||||||
<Dialog open={open} onOpenChange={setOpen}>
|
<Dialog open={open} onOpenChange={setOpen}>
|
||||||
{triggerChild}
|
{triggerChild}
|
||||||
<DialogContent className={cn(minWidth, "duration-300")}>
|
<DialogContent
|
||||||
|
className={cn(minWidth, height, "flex flex-col duration-300")}
|
||||||
|
>
|
||||||
<div className="truncate-doubleline word-break-break-word">
|
<div className="truncate-doubleline word-break-break-word">
|
||||||
{headerChild}
|
{headerChild}
|
||||||
</div>
|
</div>
|
||||||
{onSubmit ? (
|
{onSubmit ? (
|
||||||
<form
|
<Form.Root
|
||||||
onSubmit={(event) => {
|
onSubmit={(event) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
onSubmit();
|
onSubmit();
|
||||||
}}
|
}}
|
||||||
className="flex flex-col gap-6"
|
className="flex flex-1 flex-col gap-6"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className={`flex flex-col ${height} w-full transition-all duration-300`}
|
className={`flex w-full flex-1 flex-col transition-all duration-300`}
|
||||||
>
|
>
|
||||||
{ContentChild}
|
{ContentChild}
|
||||||
</div>
|
</div>
|
||||||
{ContentFooter && (
|
{ContentFooter && (
|
||||||
<div className="flex flex-row-reverse">{ContentFooter}</div>
|
<div className="flex flex-row-reverse">{ContentFooter}</div>
|
||||||
)}
|
)}
|
||||||
</form>
|
</Form.Root>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
<div
|
<div
|
||||||
className={`flex flex-col ${height} w-full transition-all duration-300`}
|
className={`flex w-full flex-1 flex-col transition-all duration-300`}
|
||||||
>
|
>
|
||||||
{ContentChild}
|
{ContentChild}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,91 @@
|
||||||
|
import { ColDef, ValueGetterParams } from "ag-grid-community";
|
||||||
|
import { useMemo } from "react";
|
||||||
|
import TableAutoCellRender from "../../../components/tableComponent/components/tableAutoCellRender";
|
||||||
|
import TableNodeCellRender from "../../../components/tableComponent/components/tableNodeCellRender";
|
||||||
|
import TableToggleCellRender from "../../../components/tableComponent/components/tableToggleCellRender";
|
||||||
|
import TableTooltipRender from "../../../components/tableComponent/components/tableTooltipRender";
|
||||||
|
|
||||||
|
const useColumnDefs = (
|
||||||
|
myData: any,
|
||||||
|
handleOnNewValue: (newValue: any, name: string) => void,
|
||||||
|
changeAdvanced: (n: string) => void,
|
||||||
|
open: boolean,
|
||||||
|
) => {
|
||||||
|
const columnDefs: ColDef[] = useMemo(
|
||||||
|
() => [
|
||||||
|
{
|
||||||
|
headerName: "Name",
|
||||||
|
field: "display_name",
|
||||||
|
valueGetter: (params) => {
|
||||||
|
const templateParam = params.data;
|
||||||
|
return (
|
||||||
|
(templateParam.display_name
|
||||||
|
? templateParam.display_name
|
||||||
|
: templateParam.name) ?? params.data.key
|
||||||
|
);
|
||||||
|
},
|
||||||
|
tooltipField: "display_name",
|
||||||
|
tooltipComponent: TableTooltipRender,
|
||||||
|
wrapText: true,
|
||||||
|
autoHeight: true,
|
||||||
|
flex: 1,
|
||||||
|
resizable: false,
|
||||||
|
cellClass: "no-border",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
headerName: "Description",
|
||||||
|
field: "info",
|
||||||
|
tooltipField: "info",
|
||||||
|
tooltipComponent: TableTooltipRender,
|
||||||
|
wrapText: true,
|
||||||
|
autoHeight: true,
|
||||||
|
flex: 2,
|
||||||
|
resizable: false,
|
||||||
|
cellClass: "no-border",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
headerName: "Value",
|
||||||
|
field: "value",
|
||||||
|
cellRenderer: TableNodeCellRender,
|
||||||
|
valueGetter: (params: ValueGetterParams) => {
|
||||||
|
return {
|
||||||
|
value: params.data.value,
|
||||||
|
nodeClass: myData.node,
|
||||||
|
handleOnNewValue: handleOnNewValue,
|
||||||
|
handleOnChangeDb: (value, key) => {
|
||||||
|
myData.node!.template[key].load_from_db = value;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
minWidth: 330,
|
||||||
|
autoHeight: true,
|
||||||
|
flex: 1,
|
||||||
|
resizable: false,
|
||||||
|
cellClass: "no-border",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
headerName: "Show",
|
||||||
|
field: "advanced",
|
||||||
|
cellRenderer: TableToggleCellRender,
|
||||||
|
valueGetter: (params: ValueGetterParams) => {
|
||||||
|
return {
|
||||||
|
name: params.data.name,
|
||||||
|
enabled: !params.data.advanced,
|
||||||
|
setEnabled: () => {
|
||||||
|
changeAdvanced(params.data.key);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
editable: false,
|
||||||
|
maxWidth: 80,
|
||||||
|
resizable: false,
|
||||||
|
cellClass: "no-border",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
[open, myData],
|
||||||
|
);
|
||||||
|
|
||||||
|
return columnDefs;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default useColumnDefs;
|
||||||
37
src/frontend/src/modals/editNodeModal/hooks/use-row-data.tsx
Normal file
37
src/frontend/src/modals/editNodeModal/hooks/use-row-data.tsx
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
import { useMemo } from "react";
|
||||||
|
import { LANGFLOW_SUPPORTED_TYPES } from "../../../constants/constants";
|
||||||
|
import { TemplateVariableType } from "../../../types/api";
|
||||||
|
|
||||||
|
const useRowData = (myData, open) => {
|
||||||
|
const rowData = useMemo(() => {
|
||||||
|
return Object.keys(myData.node!.template)
|
||||||
|
.filter((key: string) => {
|
||||||
|
const templateParam = myData.node!.template[
|
||||||
|
key
|
||||||
|
] as TemplateVariableType;
|
||||||
|
return (
|
||||||
|
key.charAt(0) !== "_" &&
|
||||||
|
templateParam.show &&
|
||||||
|
LANGFLOW_SUPPORTED_TYPES.has(templateParam.type) &&
|
||||||
|
!(
|
||||||
|
(key === "code" && templateParam.type === "code") ||
|
||||||
|
(key.includes("code") && templateParam.proxy)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.map((key: string) => {
|
||||||
|
const templateParam = myData.node!.template[
|
||||||
|
key
|
||||||
|
] as TemplateVariableType;
|
||||||
|
return {
|
||||||
|
...templateParam,
|
||||||
|
key: key,
|
||||||
|
id: key,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}, [open, myData]);
|
||||||
|
|
||||||
|
return rowData;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default useRowData;
|
||||||
|
|
@ -1,43 +1,13 @@
|
||||||
import { cloneDeep } from "lodash";
|
import { ColDef, GridApi } from "ag-grid-community";
|
||||||
import { forwardRef, useEffect, useState } from "react";
|
import { forwardRef, useEffect, useRef, useState } from "react";
|
||||||
import CodeAreaComponent from "../../components/codeAreaComponent";
|
|
||||||
import DictComponent from "../../components/dictComponent";
|
|
||||||
import Dropdown from "../../components/dropdownComponent";
|
|
||||||
import FloatComponent from "../../components/floatComponent";
|
|
||||||
import IconComponent from "../../components/genericIconComponent";
|
import IconComponent from "../../components/genericIconComponent";
|
||||||
import InputFileComponent from "../../components/inputFileComponent";
|
import TableComponent from "../../components/tableComponent";
|
||||||
import InputGlobalComponent from "../../components/inputGlobalComponent";
|
|
||||||
import InputListComponent from "../../components/inputListComponent";
|
|
||||||
import IntComponent from "../../components/intComponent";
|
|
||||||
import KeypairListComponent from "../../components/keypairListComponent";
|
|
||||||
import PromptAreaComponent from "../../components/promptComponent";
|
|
||||||
import ShadTooltip from "../../components/shadTooltipComponent";
|
|
||||||
import TextAreaComponent from "../../components/textAreaComponent";
|
|
||||||
import ToggleShadComponent from "../../components/toggleShadComponent";
|
|
||||||
import { Badge } from "../../components/ui/badge";
|
import { Badge } from "../../components/ui/badge";
|
||||||
import {
|
|
||||||
Table,
|
|
||||||
TableBody,
|
|
||||||
TableCell,
|
|
||||||
TableHead,
|
|
||||||
TableHeader,
|
|
||||||
TableRow,
|
|
||||||
} from "../../components/ui/table";
|
|
||||||
import {
|
|
||||||
LANGFLOW_SUPPORTED_TYPES,
|
|
||||||
limitScrollFieldsModal,
|
|
||||||
} from "../../constants/constants";
|
|
||||||
import { Case } from "../../shared/components/caseComponent";
|
|
||||||
import useFlowStore from "../../stores/flowStore";
|
import useFlowStore from "../../stores/flowStore";
|
||||||
import { NodeDataType } from "../../types/flow";
|
import { NodeDataType } from "../../types/flow";
|
||||||
import {
|
|
||||||
convertObjToArray,
|
|
||||||
convertValuesToNumbers,
|
|
||||||
hasDuplicateKeys,
|
|
||||||
scapedJSONStringfy,
|
|
||||||
} from "../../utils/reactflowUtils";
|
|
||||||
import { classNames } from "../../utils/utils";
|
|
||||||
import BaseModal from "../baseModal";
|
import BaseModal from "../baseModal";
|
||||||
|
import useColumnDefs from "./hooks/use-column-defs";
|
||||||
|
import useRowData from "./hooks/use-row-data";
|
||||||
|
|
||||||
const EditNodeModal = forwardRef(
|
const EditNodeModal = forwardRef(
|
||||||
(
|
(
|
||||||
|
|
@ -52,61 +22,51 @@ const EditNodeModal = forwardRef(
|
||||||
setOpen: (open: boolean) => void;
|
setOpen: (open: boolean) => void;
|
||||||
data: NodeDataType;
|
data: NodeDataType;
|
||||||
},
|
},
|
||||||
ref,
|
ref
|
||||||
) => {
|
) => {
|
||||||
const nodes = useFlowStore((state) => state.nodes);
|
const myData = useRef(data);
|
||||||
|
|
||||||
const dataFromStore = nodes.find((node) => node.id === node.id)?.data;
|
|
||||||
|
|
||||||
const [myData, setMyData] = useState(dataFromStore ?? data);
|
|
||||||
|
|
||||||
const edges = useFlowStore((state) => state.edges);
|
|
||||||
const setNode = useFlowStore((state) => state.setNode);
|
const setNode = useFlowStore((state) => state.setNode);
|
||||||
|
|
||||||
function changeAdvanced(n) {
|
function changeAdvanced(n) {
|
||||||
setMyData((old) => {
|
myData.current.node!.template[n].advanced =
|
||||||
let newData = cloneDeep(old);
|
!myData.current.node!.template[n]?.advanced;
|
||||||
newData.node!.template[n].advanced =
|
|
||||||
!newData.node!.template[n].advanced;
|
|
||||||
return newData;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleOnNewValue = (newValue: any, name) => {
|
const handleOnNewValue = (newValue: any, name) => {
|
||||||
setMyData((old) => {
|
myData.current.node!.template[name].value = newValue;
|
||||||
let newData = cloneDeep(old);
|
|
||||||
newData.node!.template[name].value = newValue;
|
|
||||||
return newData;
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const rowData = useRowData(data, open);
|
||||||
|
|
||||||
|
const columnDefs: ColDef[] = useColumnDefs(
|
||||||
|
data,
|
||||||
|
handleOnNewValue,
|
||||||
|
changeAdvanced,
|
||||||
|
open
|
||||||
|
);
|
||||||
|
|
||||||
|
const [gridApi, setGridApi] = useState<GridApi | null>(null);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (open) {
|
if (gridApi && open) {
|
||||||
setMyData(data); // reset data to what it is on node when opening modal
|
myData.current = data;
|
||||||
|
gridApi.refreshCells();
|
||||||
}
|
}
|
||||||
}, [open]);
|
}, [gridApi, open]);
|
||||||
|
|
||||||
const [errorDuplicateKey, setErrorDuplicateKey] = useState(false);
|
|
||||||
|
|
||||||
const type = (templateParam) => {
|
|
||||||
return myData.node?.template[templateParam].type;
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<BaseModal
|
<BaseModal
|
||||||
key={data.id}
|
key={data.id}
|
||||||
size="large-h-full"
|
size="medium-tall"
|
||||||
open={open}
|
open={open}
|
||||||
setOpen={setOpen}
|
setOpen={setOpen}
|
||||||
onChangeOpenModal={(open) => {
|
|
||||||
setMyData(data);
|
|
||||||
}}
|
|
||||||
onSubmit={() => {
|
onSubmit={() => {
|
||||||
setNode(data.id, (old) => ({
|
setNode(data.id, (old) => ({
|
||||||
...old,
|
...old,
|
||||||
data: {
|
data: {
|
||||||
...old.data,
|
...old.data,
|
||||||
node: myData.node,
|
node: myData.current.node,
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
setOpen(false);
|
setOpen(false);
|
||||||
|
|
@ -115,11 +75,12 @@ const EditNodeModal = forwardRef(
|
||||||
<BaseModal.Trigger>
|
<BaseModal.Trigger>
|
||||||
<></>
|
<></>
|
||||||
</BaseModal.Trigger>
|
</BaseModal.Trigger>
|
||||||
<BaseModal.Header description={myData.node?.description!}>
|
<BaseModal.Header description={data.node?.description!}>
|
||||||
<span className="pr-2">{myData.type}</span>
|
<span className="pr-2">{data.type}</span>
|
||||||
<Badge variant="secondary">ID: {myData.id}</Badge>
|
<Badge variant="secondary">ID: {data.id}</Badge>
|
||||||
</BaseModal.Header>
|
</BaseModal.Header>
|
||||||
<BaseModal.Content>
|
<BaseModal.Content>
|
||||||
|
<div className="flex h-full flex-col">
|
||||||
<div className="flex pb-2">
|
<div className="flex pb-2">
|
||||||
<IconComponent
|
<IconComponent
|
||||||
name="Variable"
|
name="Variable"
|
||||||
|
|
@ -128,513 +89,16 @@ const EditNodeModal = forwardRef(
|
||||||
<span className="edit-node-modal-span">Parameters</span>
|
<span className="edit-node-modal-span">Parameters</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="edit-node-modal-arrangement">
|
<div className="h-full">
|
||||||
<div
|
|
||||||
className={classNames(
|
|
||||||
"edit-node-modal-box",
|
|
||||||
nodeLength > limitScrollFieldsModal
|
|
||||||
? "overflow-scroll overflow-x-hidden custom-scroll"
|
|
||||||
: "",
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
{nodeLength > 0 && (
|
{nodeLength > 0 && (
|
||||||
<div className="edit-node-modal-table">
|
<TableComponent
|
||||||
<Table className="table-fixed bg-muted outline-1">
|
onGridReady={(params) => {
|
||||||
<TableHeader className="edit-node-modal-table-header">
|
setGridApi(params.api);
|
||||||
<TableRow className="">
|
|
||||||
<TableHead className="h-7 text-center">PARAM</TableHead>
|
|
||||||
<TableHead className="h-7 text-center">DESC</TableHead>
|
|
||||||
<TableHead className="h-7 p-0 text-center">
|
|
||||||
VALUE
|
|
||||||
</TableHead>
|
|
||||||
<TableHead className="h-7 text-center">SHOW</TableHead>
|
|
||||||
</TableRow>
|
|
||||||
</TableHeader>
|
|
||||||
<TableBody className="p-0">
|
|
||||||
{Object.keys(myData.node!.template)
|
|
||||||
.filter(
|
|
||||||
(templateParam) =>
|
|
||||||
templateParam.charAt(0) !== "_" &&
|
|
||||||
myData.node?.template[templateParam].show &&
|
|
||||||
LANGFLOW_SUPPORTED_TYPES.has(
|
|
||||||
myData.node!.template[templateParam].type,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.map((templateParam, index) => {
|
|
||||||
let id = {
|
|
||||||
inputTypes:
|
|
||||||
myData.node!.template[templateParam].input_types,
|
|
||||||
type: myData.node!.template[templateParam].type,
|
|
||||||
id: myData.id,
|
|
||||||
fieldName: templateParam,
|
|
||||||
};
|
|
||||||
let disabled =
|
|
||||||
edges.some(
|
|
||||||
(edge) =>
|
|
||||||
edge.targetHandle ===
|
|
||||||
scapedJSONStringfy(
|
|
||||||
myData.node!.template[templateParam].proxy
|
|
||||||
? {
|
|
||||||
...id,
|
|
||||||
proxy:
|
|
||||||
myData.node?.template[templateParam]
|
|
||||||
.proxy,
|
|
||||||
}
|
|
||||||
: id,
|
|
||||||
),
|
|
||||||
) ?? false;
|
|
||||||
return (
|
|
||||||
<TableRow
|
|
||||||
key={index}
|
|
||||||
className={
|
|
||||||
"h-10 " +
|
|
||||||
((templateParam === "code" &&
|
|
||||||
type(templateParam) === "code") ||
|
|
||||||
(templateParam.includes("code") &&
|
|
||||||
myData.node?.template[templateParam].proxy)
|
|
||||||
? " hidden "
|
|
||||||
: "")
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<TableCell className="truncate p-0 text-center text-sm text-foreground sm:px-3">
|
|
||||||
<ShadTooltip
|
|
||||||
styleClasses="z-50"
|
|
||||||
content={
|
|
||||||
myData.node?.template[templateParam].proxy
|
|
||||||
? myData.node?.template[templateParam]
|
|
||||||
.proxy?.id
|
|
||||||
: myData.node?.template[templateParam]
|
|
||||||
.display_name
|
|
||||||
? myData.node!.template[templateParam]
|
|
||||||
.display_name
|
|
||||||
: myData.node?.template[templateParam]
|
|
||||||
.name
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<span>
|
|
||||||
{myData.node?.template[templateParam]
|
|
||||||
.display_name
|
|
||||||
? myData.node!.template[templateParam]
|
|
||||||
.display_name
|
|
||||||
: myData.node?.template[templateParam]
|
|
||||||
.name}
|
|
||||||
</span>
|
|
||||||
</ShadTooltip>
|
|
||||||
</TableCell>
|
|
||||||
<TableCell className="truncate p-0 text-center text-sm text-foreground sm:px-3">
|
|
||||||
<ShadTooltip
|
|
||||||
styleClasses="z-50"
|
|
||||||
content={
|
|
||||||
data.node?.template[templateParam]?.info ??
|
|
||||||
null
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<span>
|
|
||||||
{data.node?.template[templateParam]?.info ??
|
|
||||||
""}
|
|
||||||
</span>
|
|
||||||
</ShadTooltip>
|
|
||||||
</TableCell>
|
|
||||||
<TableCell className="w-[300px] p-0 text-center text-xs text-foreground ">
|
|
||||||
<Case
|
|
||||||
condition={
|
|
||||||
type(templateParam) === "str" &&
|
|
||||||
!myData.node!.template[templateParam]
|
|
||||||
.options
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<div className="mx-auto">
|
|
||||||
{myData.node!.template[templateParam]
|
|
||||||
?.list ? (
|
|
||||||
<InputListComponent
|
|
||||||
componentName={templateParam}
|
|
||||||
editNode={true}
|
|
||||||
disabled={disabled}
|
|
||||||
value={
|
|
||||||
!myData.node!.template[templateParam]
|
|
||||||
.value ||
|
|
||||||
myData.node!.template[templateParam]
|
|
||||||
.value === ""
|
|
||||||
? [""]
|
|
||||||
: myData.node!.template[
|
|
||||||
templateParam
|
|
||||||
].value
|
|
||||||
}
|
|
||||||
onChange={(value: string[]) => {
|
|
||||||
handleOnNewValue(
|
|
||||||
value,
|
|
||||||
templateParam,
|
|
||||||
);
|
|
||||||
}}
|
}}
|
||||||
|
tooltipShowDelay={0.5}
|
||||||
|
columnDefs={columnDefs}
|
||||||
|
rowData={rowData}
|
||||||
/>
|
/>
|
||||||
) : myData.node!.template[templateParam]
|
|
||||||
.multiline ? (
|
|
||||||
<TextAreaComponent
|
|
||||||
id={
|
|
||||||
"textarea-edit-" +
|
|
||||||
myData.node!.template[templateParam]
|
|
||||||
.name
|
|
||||||
}
|
|
||||||
data-testid={
|
|
||||||
"textarea-edit-" +
|
|
||||||
myData.node!.template[templateParam]
|
|
||||||
.name
|
|
||||||
}
|
|
||||||
disabled={disabled}
|
|
||||||
editNode={true}
|
|
||||||
value={
|
|
||||||
myData.node!.template[templateParam]
|
|
||||||
.value ?? ""
|
|
||||||
}
|
|
||||||
onChange={(
|
|
||||||
value: string | string[],
|
|
||||||
) => {
|
|
||||||
handleOnNewValue(
|
|
||||||
value,
|
|
||||||
templateParam,
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
) : (
|
|
||||||
<InputGlobalComponent
|
|
||||||
disabled={disabled}
|
|
||||||
editNode={true}
|
|
||||||
onChange={(value) =>
|
|
||||||
handleOnNewValue(value, templateParam)
|
|
||||||
}
|
|
||||||
setDb={(value) => {
|
|
||||||
setMyData((oldData) => {
|
|
||||||
let newData = cloneDeep(oldData);
|
|
||||||
newData.node!.template[
|
|
||||||
templateParam
|
|
||||||
].load_from_db = value;
|
|
||||||
return newData;
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
name={templateParam}
|
|
||||||
data={myData}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</Case>
|
|
||||||
|
|
||||||
<Case
|
|
||||||
condition={
|
|
||||||
type(templateParam) === "NestedDict"
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<div className=" w-full">
|
|
||||||
<DictComponent
|
|
||||||
disabled={disabled}
|
|
||||||
editNode={true}
|
|
||||||
value={
|
|
||||||
myData.node!.template[
|
|
||||||
templateParam
|
|
||||||
]?.value?.toString() === "{}"
|
|
||||||
? {}
|
|
||||||
: myData.node!.template[templateParam]
|
|
||||||
.value
|
|
||||||
}
|
|
||||||
onChange={(newValue) => {
|
|
||||||
myData.node!.template[
|
|
||||||
templateParam
|
|
||||||
].value = newValue;
|
|
||||||
handleOnNewValue(
|
|
||||||
newValue,
|
|
||||||
templateParam,
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
id="editnode-div-dict-input"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</Case>
|
|
||||||
|
|
||||||
<Case
|
|
||||||
condition={type(templateParam) === "dict"}
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
className={classNames(
|
|
||||||
"max-h-48 w-full overflow-auto custom-scroll",
|
|
||||||
myData.node!.template[templateParam].value
|
|
||||||
?.length > 1
|
|
||||||
? "my-3"
|
|
||||||
: "",
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
<KeypairListComponent
|
|
||||||
disabled={disabled}
|
|
||||||
editNode={true}
|
|
||||||
value={
|
|
||||||
myData.node!.template[templateParam]
|
|
||||||
.value?.length === 0 ||
|
|
||||||
!myData.node!.template[templateParam]
|
|
||||||
.value
|
|
||||||
? [{ "": "" }]
|
|
||||||
: convertObjToArray(
|
|
||||||
myData.node!.template[
|
|
||||||
templateParam
|
|
||||||
].value,
|
|
||||||
type(templateParam)!,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
duplicateKey={errorDuplicateKey}
|
|
||||||
onChange={(newValue) => {
|
|
||||||
const valueToNumbers =
|
|
||||||
convertValuesToNumbers(newValue);
|
|
||||||
myData.node!.template[
|
|
||||||
templateParam
|
|
||||||
].value = valueToNumbers;
|
|
||||||
setErrorDuplicateKey(
|
|
||||||
hasDuplicateKeys(valueToNumbers),
|
|
||||||
);
|
|
||||||
handleOnNewValue(
|
|
||||||
valueToNumbers,
|
|
||||||
templateParam,
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
isList={
|
|
||||||
data.node?.template[templateParam]
|
|
||||||
?.list ?? false
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</Case>
|
|
||||||
|
|
||||||
<Case
|
|
||||||
condition={type(templateParam) === "bool"}
|
|
||||||
>
|
|
||||||
<div className="ml-auto">
|
|
||||||
{" "}
|
|
||||||
<ToggleShadComponent
|
|
||||||
id={
|
|
||||||
"toggle-edit-" +
|
|
||||||
myData.node!.template[templateParam]
|
|
||||||
.name
|
|
||||||
}
|
|
||||||
disabled={disabled}
|
|
||||||
enabled={
|
|
||||||
myData.node!.template[templateParam]
|
|
||||||
.value
|
|
||||||
}
|
|
||||||
setEnabled={(isEnabled) => {
|
|
||||||
handleOnNewValue(
|
|
||||||
isEnabled,
|
|
||||||
templateParam,
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
size="small"
|
|
||||||
editNode={true}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</Case>
|
|
||||||
|
|
||||||
<Case
|
|
||||||
condition={type(templateParam) === "float"}
|
|
||||||
>
|
|
||||||
<div className="mx-auto">
|
|
||||||
<FloatComponent
|
|
||||||
disabled={disabled}
|
|
||||||
editNode={true}
|
|
||||||
rangeSpec={
|
|
||||||
myData.node!.template[templateParam]
|
|
||||||
.rangeSpec
|
|
||||||
}
|
|
||||||
value={
|
|
||||||
myData.node!.template[templateParam]
|
|
||||||
.value ?? ""
|
|
||||||
}
|
|
||||||
onChange={(value) => {
|
|
||||||
handleOnNewValue(value, templateParam);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</Case>
|
|
||||||
|
|
||||||
<Case
|
|
||||||
condition={
|
|
||||||
type(templateParam) === "str" &&
|
|
||||||
myData.node!.template[templateParam].options
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<div className="mx-auto">
|
|
||||||
<Dropdown
|
|
||||||
editNode={true}
|
|
||||||
options={
|
|
||||||
myData.node!.template[templateParam]
|
|
||||||
.options
|
|
||||||
}
|
|
||||||
onSelect={(value) =>
|
|
||||||
handleOnNewValue(value, templateParam)
|
|
||||||
}
|
|
||||||
value={
|
|
||||||
myData.node!.template[templateParam]
|
|
||||||
.value ?? "Choose an option"
|
|
||||||
}
|
|
||||||
id={
|
|
||||||
"dropdown-edit-" +
|
|
||||||
myData.node!.template[templateParam]
|
|
||||||
.name
|
|
||||||
}
|
|
||||||
></Dropdown>
|
|
||||||
</div>
|
|
||||||
</Case>
|
|
||||||
|
|
||||||
<Case condition={type(templateParam) === "int"}>
|
|
||||||
<div className="mx-auto">
|
|
||||||
<IntComponent
|
|
||||||
rangeSpec={
|
|
||||||
data.node?.template[templateParam]
|
|
||||||
?.rangeSpec
|
|
||||||
}
|
|
||||||
id={
|
|
||||||
"edit-int-input-" +
|
|
||||||
myData.node!.template[templateParam]
|
|
||||||
.name
|
|
||||||
}
|
|
||||||
disabled={disabled}
|
|
||||||
editNode={true}
|
|
||||||
value={
|
|
||||||
myData.node!.template[templateParam]
|
|
||||||
.value ?? ""
|
|
||||||
}
|
|
||||||
onChange={(value) => {
|
|
||||||
handleOnNewValue(value, templateParam);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</Case>
|
|
||||||
|
|
||||||
<Case
|
|
||||||
condition={type(templateParam) === "file"}
|
|
||||||
>
|
|
||||||
<div className="mx-auto">
|
|
||||||
<InputFileComponent
|
|
||||||
editNode={true}
|
|
||||||
disabled={disabled}
|
|
||||||
value={
|
|
||||||
myData.node!.template[templateParam]
|
|
||||||
.value ?? ""
|
|
||||||
}
|
|
||||||
onChange={(value: string | string[]) => {
|
|
||||||
handleOnNewValue(value, templateParam);
|
|
||||||
}}
|
|
||||||
fileTypes={
|
|
||||||
myData.node!.template[templateParam]
|
|
||||||
.fileTypes
|
|
||||||
}
|
|
||||||
onFileChange={(filePath: string) => {
|
|
||||||
data.node!.template[
|
|
||||||
templateParam
|
|
||||||
].file_path = filePath;
|
|
||||||
}}
|
|
||||||
></InputFileComponent>
|
|
||||||
</div>
|
|
||||||
</Case>
|
|
||||||
|
|
||||||
<Case
|
|
||||||
condition={type(templateParam) === "prompt"}
|
|
||||||
>
|
|
||||||
<div className="mx-auto">
|
|
||||||
<PromptAreaComponent
|
|
||||||
readonly={
|
|
||||||
myData.node?.flow ? true : false
|
|
||||||
}
|
|
||||||
field_name={templateParam}
|
|
||||||
editNode={true}
|
|
||||||
disabled={disabled}
|
|
||||||
nodeClass={myData.node}
|
|
||||||
setNodeClass={(nodeClass) => {
|
|
||||||
myData.node = nodeClass;
|
|
||||||
}}
|
|
||||||
value={
|
|
||||||
myData.node!.template[templateParam]
|
|
||||||
.value ?? ""
|
|
||||||
}
|
|
||||||
onChange={(value: string | string[]) => {
|
|
||||||
handleOnNewValue(value, templateParam);
|
|
||||||
}}
|
|
||||||
id={
|
|
||||||
"prompt-area-edit-" +
|
|
||||||
myData.node!.template[templateParam]
|
|
||||||
.name
|
|
||||||
}
|
|
||||||
data-testid={
|
|
||||||
"modal-prompt-input-" +
|
|
||||||
myData.node!.template[templateParam]
|
|
||||||
.name
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</Case>
|
|
||||||
|
|
||||||
<Case
|
|
||||||
condition={type(templateParam) === "code"}
|
|
||||||
>
|
|
||||||
<div className="mx-auto">
|
|
||||||
<CodeAreaComponent
|
|
||||||
readonly={
|
|
||||||
myData.node?.flow &&
|
|
||||||
myData.node!.template[templateParam]
|
|
||||||
.dynamic
|
|
||||||
? true
|
|
||||||
: false
|
|
||||||
}
|
|
||||||
dynamic={
|
|
||||||
data.node!.template[templateParam]
|
|
||||||
?.dynamic ?? false
|
|
||||||
}
|
|
||||||
setNodeClass={(nodeClass) => {
|
|
||||||
data.node = nodeClass;
|
|
||||||
}}
|
|
||||||
nodeClass={data.node}
|
|
||||||
disabled={disabled}
|
|
||||||
editNode={true}
|
|
||||||
value={
|
|
||||||
myData.node!.template[templateParam]
|
|
||||||
.value ?? ""
|
|
||||||
}
|
|
||||||
onChange={(value: string | string[]) => {
|
|
||||||
handleOnNewValue(value, templateParam);
|
|
||||||
}}
|
|
||||||
id={
|
|
||||||
"code-area-edit" +
|
|
||||||
myData.node!.template[templateParam]
|
|
||||||
.name
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</Case>
|
|
||||||
|
|
||||||
<Case condition={type(templateParam) === "Any"}>
|
|
||||||
<>-</>
|
|
||||||
</Case>
|
|
||||||
</TableCell>
|
|
||||||
<TableCell className="p-0 text-right">
|
|
||||||
<div className="items-center text-center">
|
|
||||||
<ToggleShadComponent
|
|
||||||
id={
|
|
||||||
"show" +
|
|
||||||
myData.node?.template[templateParam].name
|
|
||||||
}
|
|
||||||
enabled={
|
|
||||||
!myData.node?.template[templateParam]
|
|
||||||
.advanced
|
|
||||||
}
|
|
||||||
setEnabled={(e) => {
|
|
||||||
changeAdvanced(templateParam);
|
|
||||||
}}
|
|
||||||
disabled={disabled}
|
|
||||||
size="small"
|
|
||||||
editNode={true}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</TableCell>
|
|
||||||
</TableRow>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</TableBody>
|
|
||||||
</Table>
|
|
||||||
</div>
|
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -643,7 +107,7 @@ const EditNodeModal = forwardRef(
|
||||||
<BaseModal.Footer submit={{ label: "Save Changes" }} />
|
<BaseModal.Footer submit={{ label: "Save Changes" }} />
|
||||||
</BaseModal>
|
</BaseModal>
|
||||||
);
|
);
|
||||||
},
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
export default EditNodeModal;
|
export default EditNodeModal;
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,7 @@ const ExportModal = forwardRef(
|
||||||
is_component: false,
|
is_component: false,
|
||||||
},
|
},
|
||||||
name!,
|
name!,
|
||||||
description,
|
description
|
||||||
);
|
);
|
||||||
setNoticeData({
|
setNoticeData({
|
||||||
title: API_WARNING_NOTICE_ALERT,
|
title: API_WARNING_NOTICE_ALERT,
|
||||||
|
|
@ -61,7 +61,7 @@ const ExportModal = forwardRef(
|
||||||
is_component: false,
|
is_component: false,
|
||||||
}),
|
}),
|
||||||
name!,
|
name!,
|
||||||
description,
|
description
|
||||||
);
|
);
|
||||||
setOpen(false);
|
setOpen(false);
|
||||||
}}
|
}}
|
||||||
|
|
@ -102,6 +102,6 @@ const ExportModal = forwardRef(
|
||||||
<BaseModal.Footer submit={{ label: "Download Flow" }} />
|
<BaseModal.Footer submit={{ label: "Download Flow" }} />
|
||||||
</BaseModal>
|
</BaseModal>
|
||||||
);
|
);
|
||||||
},
|
}
|
||||||
);
|
);
|
||||||
export default ExportModal;
|
export default ExportModal;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
import { ColDef, ColGroupDef } from "ag-grid-community";
|
import { ColDef, ColGroupDef } from "ag-grid-community";
|
||||||
import { AxiosError } from "axios";
|
|
||||||
import { useEffect, useRef, useState } from "react";
|
import { useEffect, useRef, useState } from "react";
|
||||||
import IconComponent from "../../components/genericIconComponent";
|
import IconComponent from "../../components/genericIconComponent";
|
||||||
import TableComponent from "../../components/tableComponent";
|
import TableComponent from "../../components/tableComponent";
|
||||||
|
|
@ -9,7 +8,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 { FlowSettingsPropsType } from "../../types/components";
|
import { FlowSettingsPropsType } from "../../types/components";
|
||||||
import { FlowType, NodeDataType } from "../../types/flow";
|
import { NodeDataType } from "../../types/flow";
|
||||||
import BaseModal from "../baseModal";
|
import BaseModal from "../baseModal";
|
||||||
|
|
||||||
export default function FlowLogsModal({
|
export default function FlowLogsModal({
|
||||||
|
|
@ -38,7 +37,7 @@ export default function FlowLogsModal({
|
||||||
const { columns, rows } = data;
|
const { columns, rows } = data;
|
||||||
setColumns(columns.map((col) => ({ ...col, editable: true })));
|
setColumns(columns.map((col) => ({ ...col, editable: true })));
|
||||||
setRows(rows);
|
setRows(rows);
|
||||||
},
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -48,7 +47,7 @@ export default function FlowLogsModal({
|
||||||
.some((template) => template["stream"] && template["stream"].value);
|
.some((template) => template["stream"] && template["stream"].value);
|
||||||
console.log(
|
console.log(
|
||||||
haStream,
|
haStream,
|
||||||
nodes.map((nodes) => (nodes.data as NodeDataType).node!.template),
|
nodes.map((nodes) => (nodes.data as NodeDataType).node!.template)
|
||||||
);
|
);
|
||||||
if (haStream) {
|
if (haStream) {
|
||||||
setNoticeData({
|
setNoticeData({
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import InputComponent from "../../../components/inputComponent";
|
|
||||||
import {
|
import {
|
||||||
FormControl,
|
FormControl,
|
||||||
FormField,
|
FormField,
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ const useFolderSubmit = (setOpen, folderToEdit) => {
|
||||||
getFoldersApi(true);
|
getFoldersApi(true);
|
||||||
setOpen(false);
|
setOpen(false);
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
addFolder(data).then(
|
addFolder(data).then(
|
||||||
|
|
@ -49,7 +49,7 @@ const useFolderSubmit = (setOpen, folderToEdit) => {
|
||||||
setErrorData({
|
setErrorData({
|
||||||
title: `Error creating folder.`,
|
title: `Error creating folder.`,
|
||||||
});
|
});
|
||||||
},
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ export default function NewFlowModal({
|
||||||
key={0}
|
key={0}
|
||||||
flow={
|
flow={
|
||||||
examples.find(
|
examples.find(
|
||||||
(e) => e.name == "Basic Prompting (Hello, World)",
|
(e) => e.name == "Basic Prompting (Hello, World)"
|
||||||
)!
|
)!
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -11,15 +11,10 @@ import { nodeIconsLucide } from "../../utils/styleUtils";
|
||||||
import BaseModal from "../baseModal";
|
import BaseModal from "../baseModal";
|
||||||
|
|
||||||
export default function SecretKeyModal({
|
export default function SecretKeyModal({
|
||||||
title,
|
|
||||||
cancelText,
|
|
||||||
confirmationText,
|
|
||||||
children,
|
children,
|
||||||
icon,
|
|
||||||
data,
|
data,
|
||||||
onCloseModal,
|
onCloseModal,
|
||||||
}: ApiKeyType) {
|
}: ApiKeyType) {
|
||||||
const Icon: any = nodeIconsLucide[icon];
|
|
||||||
const [open, setOpen] = useState(false);
|
const [open, setOpen] = useState(false);
|
||||||
const [apiKeyName, setApiKeyName] = useState(data?.apikeyname ?? "");
|
const [apiKeyName, setApiKeyName] = useState(data?.apikeyname ?? "");
|
||||||
const [apiKeyValue, setApiKeyValue] = useState("");
|
const [apiKeyValue, setApiKeyValue] = useState("");
|
||||||
|
|
@ -66,38 +61,60 @@ export default function SecretKeyModal({
|
||||||
.catch((err) => {});
|
.catch((err) => {});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function handleSubmitForm() {
|
||||||
|
if (!renderKey) {
|
||||||
|
setRenderKey(true);
|
||||||
|
handleAddNewKey();
|
||||||
|
} else {
|
||||||
|
setOpen(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<BaseModal size="small-h-full" open={open} setOpen={setOpen}>
|
<BaseModal
|
||||||
|
onSubmit={handleSubmitForm}
|
||||||
|
size="small-h-full"
|
||||||
|
open={open}
|
||||||
|
setOpen={setOpen}
|
||||||
|
>
|
||||||
<BaseModal.Trigger>{children}</BaseModal.Trigger>
|
<BaseModal.Trigger>{children}</BaseModal.Trigger>
|
||||||
<BaseModal.Header description={""}>
|
<BaseModal.Header
|
||||||
<span className="pr-2">{title}</span>
|
description={
|
||||||
<Icon
|
renderKey ? (
|
||||||
name="icon"
|
|
||||||
className="h-6 w-6 pl-1 text-foreground"
|
|
||||||
aria-hidden="true"
|
|
||||||
/>
|
|
||||||
</BaseModal.Header>
|
|
||||||
<BaseModal.Content>
|
|
||||||
{renderKey === true && (
|
|
||||||
<>
|
<>
|
||||||
<span className="text-xs">
|
{" "}
|
||||||
Please save this secret key somewhere safe and accessible. For
|
Please save this secret key somewhere safe and accessible. For
|
||||||
security reasons,{" "}
|
security reasons,{" "}
|
||||||
<strong>you won't be able to view it again</strong> through your
|
<strong>you won't be able to view it again</strong> through your
|
||||||
account. If you lose this secret key, you'll need to generate a
|
account. If you lose this secret key, you'll need to generate a
|
||||||
new one.
|
new one.
|
||||||
</span>
|
</>
|
||||||
<div className="flex pt-3">
|
) : (
|
||||||
|
<>Create a secret API Key to use Langflow API.</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<span className="pr-2">Create API Key</span>
|
||||||
|
<IconComponent
|
||||||
|
name="Key"
|
||||||
|
className="h-6 w-6 pl-1 text-foreground"
|
||||||
|
aria-hidden="true"
|
||||||
|
/>
|
||||||
|
</BaseModal.Header>
|
||||||
|
<BaseModal.Content>
|
||||||
|
{renderKey ? (
|
||||||
|
<>
|
||||||
|
<div className="flex items-center gap-3">
|
||||||
<div className="w-full">
|
<div className="w-full">
|
||||||
<Input ref={inputRef} readOnly={true} value={apiKeyValue} />
|
<Input ref={inputRef} readOnly={true} value={apiKeyValue} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
|
||||||
<Button
|
<Button
|
||||||
className="ml-3"
|
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
handleCopyClick();
|
handleCopyClick();
|
||||||
}}
|
}}
|
||||||
|
variant="none"
|
||||||
|
size="none"
|
||||||
>
|
>
|
||||||
{textCopied ? (
|
{textCopied ? (
|
||||||
<IconComponent name="Copy" className="h-4 w-4" />
|
<IconComponent name="Copy" className="h-4 w-4" />
|
||||||
|
|
@ -106,78 +123,29 @@ export default function SecretKeyModal({
|
||||||
)}
|
)}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</>
|
</>
|
||||||
)}
|
) : (
|
||||||
|
<Form.Field name="apikey">
|
||||||
<Form.Root
|
<div className="flex items-center justify-between gap-2">
|
||||||
onSubmit={(event) => {
|
|
||||||
setRenderKey(true);
|
|
||||||
handleAddNewKey();
|
|
||||||
event.preventDefault();
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{renderKey === false && (
|
|
||||||
<div className="grid gap-5">
|
|
||||||
<Form.Field name="username">
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
display: "flex",
|
|
||||||
alignItems: "baseline",
|
|
||||||
justifyContent: "space-between",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Form.Label className="data-[invalid]:label-invalid">
|
|
||||||
Name (optional){" "}
|
|
||||||
</Form.Label>
|
|
||||||
</div>
|
|
||||||
<Form.Control asChild>
|
<Form.Control asChild>
|
||||||
<input
|
<Input
|
||||||
|
//fake api key
|
||||||
|
id="primary-input"
|
||||||
|
value={apiKeyName}
|
||||||
|
ref={inputRef}
|
||||||
onChange={({ target: { value } }) => {
|
onChange={({ target: { value } }) => {
|
||||||
setApiKeyName(value);
|
setApiKeyName(value);
|
||||||
}}
|
}}
|
||||||
value={apiKeyName}
|
placeholder="Insert a name for your API Key"
|
||||||
className="primary-input"
|
|
||||||
placeholder="My key name"
|
|
||||||
/>
|
/>
|
||||||
</Form.Control>
|
</Form.Control>
|
||||||
|
</div>
|
||||||
</Form.Field>
|
</Form.Field>
|
||||||
</div>
|
|
||||||
)}
|
)}
|
||||||
{renderKey === false && (
|
|
||||||
<div className="float-right">
|
|
||||||
<Button
|
|
||||||
type="button"
|
|
||||||
className="mr-3"
|
|
||||||
variant="outline"
|
|
||||||
onClick={() => {
|
|
||||||
setOpen(false);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{cancelText}
|
|
||||||
</Button>
|
|
||||||
|
|
||||||
<Form.Submit asChild>
|
|
||||||
<Button className="mt-8">{confirmationText}</Button>
|
|
||||||
</Form.Submit>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{renderKey === true && (
|
|
||||||
<div className="float-right">
|
|
||||||
<Button
|
|
||||||
onClick={() => {
|
|
||||||
setOpen(false);
|
|
||||||
setRenderKey(false);
|
|
||||||
}}
|
|
||||||
className="mt-8"
|
|
||||||
>
|
|
||||||
Done
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</Form.Root>
|
|
||||||
</BaseModal.Content>
|
</BaseModal.Content>
|
||||||
|
<BaseModal.Footer
|
||||||
|
submit={{ label: renderKey ? "Done" : "Create Secret Key" }}
|
||||||
|
/>
|
||||||
</BaseModal>
|
</BaseModal>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -128,14 +128,14 @@ export default function ShareModal({
|
||||||
title: "Error sharing " + is_component ? "component" : "flow",
|
title: "Error sharing " + is_component ? "component" : "flow",
|
||||||
list: [err["response"]["data"]["detail"]],
|
list: [err["response"]["data"]["detail"]],
|
||||||
});
|
});
|
||||||
},
|
}
|
||||||
);
|
);
|
||||||
else
|
else
|
||||||
updateFlowStore(
|
updateFlowStore(
|
||||||
flow!,
|
flow!,
|
||||||
getTagsIds(selectedTags, tags),
|
getTagsIds(selectedTags, tags),
|
||||||
sharePublic,
|
sharePublic,
|
||||||
unavaliableNames.find((e) => e.name === name)!.id,
|
unavaliableNames.find((e) => e.name === name)!.id
|
||||||
).then(successShare, (err) => {
|
).then(successShare, (err) => {
|
||||||
setErrorData({
|
setErrorData({
|
||||||
title: "Error sharing " + is_component ? "component" : "flow",
|
title: "Error sharing " + is_component ? "component" : "flow",
|
||||||
|
|
@ -203,7 +203,7 @@ export default function ShareModal({
|
||||||
setOpen={setOpen ?? internalSetOpen}
|
setOpen={setOpen ?? internalSetOpen}
|
||||||
onSubmit={() => {
|
onSubmit={() => {
|
||||||
const isNameAvailable = !unavaliableNames.some(
|
const isNameAvailable = !unavaliableNames.some(
|
||||||
(element) => element.name === name,
|
(element) => element.name === name
|
||||||
);
|
);
|
||||||
|
|
||||||
if (isNameAvailable) {
|
if (isNameAvailable) {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
export default function getTagsIds(
|
export default function getTagsIds(
|
||||||
tags: string[],
|
tags: string[],
|
||||||
tagListId: { name: string; id: string }[],
|
tagListId: { name: string; id: string }[]
|
||||||
) {
|
) {
|
||||||
return tags
|
return tags
|
||||||
.map((tag) => tagListId.find((tagObj) => tagObj.name === tag))!
|
.map((tag) => tagListId.find((tagObj) => tagObj.name === tag))!
|
||||||
|
|
|
||||||
|
|
@ -1,291 +0,0 @@
|
||||||
import { useContext, useEffect, useRef, useState } from "react";
|
|
||||||
import IconComponent from "../../components/genericIconComponent";
|
|
||||||
import ShadTooltip from "../../components/shadTooltipComponent";
|
|
||||||
import { Button } from "../../components/ui/button";
|
|
||||||
import {
|
|
||||||
Table,
|
|
||||||
TableBody,
|
|
||||||
TableCell,
|
|
||||||
TableHead,
|
|
||||||
TableHeader,
|
|
||||||
TableRow,
|
|
||||||
} from "../../components/ui/table";
|
|
||||||
import { AuthContext } from "../../contexts/authContext";
|
|
||||||
import { deleteApiKey, getApiKey } from "../../controllers/API";
|
|
||||||
import ConfirmationModal from "../../modals/confirmationModal";
|
|
||||||
import SecretKeyModal from "../../modals/secretKeyModal";
|
|
||||||
|
|
||||||
import moment from "moment";
|
|
||||||
import Header from "../../components/headerComponent";
|
|
||||||
import {
|
|
||||||
DEL_KEY_ERROR_ALERT,
|
|
||||||
DEL_KEY_SUCCESS_ALERT,
|
|
||||||
} from "../../constants/alerts_constants";
|
|
||||||
import {
|
|
||||||
API_PAGE_PARAGRAPH_1,
|
|
||||||
API_PAGE_PARAGRAPH_2,
|
|
||||||
API_PAGE_USER_KEYS,
|
|
||||||
LAST_USED_SPAN_1,
|
|
||||||
LAST_USED_SPAN_2,
|
|
||||||
} from "../../constants/constants";
|
|
||||||
import useAlertStore from "../../stores/alertStore";
|
|
||||||
import { ApiKey } from "../../types/components";
|
|
||||||
|
|
||||||
export default function ApiKeysPage() {
|
|
||||||
const [loadingKeys, setLoadingKeys] = useState(true);
|
|
||||||
const setSuccessData = useAlertStore((state) => state.setSuccessData);
|
|
||||||
const setErrorData = useAlertStore((state) => state.setErrorData);
|
|
||||||
const { userData } = useContext(AuthContext);
|
|
||||||
const [userId, setUserId] = useState("");
|
|
||||||
const keysList = useRef([]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
getKeys();
|
|
||||||
}, [userData]);
|
|
||||||
|
|
||||||
function getKeys() {
|
|
||||||
setLoadingKeys(true);
|
|
||||||
if (userData) {
|
|
||||||
getApiKey()
|
|
||||||
.then((keys: [ApiKey]) => {
|
|
||||||
keysList.current = keys["api_keys"];
|
|
||||||
setUserId(keys["user_id"]);
|
|
||||||
setLoadingKeys(false);
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
setLoadingKeys(false);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function resetFilter() {
|
|
||||||
getKeys();
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleDeleteKey(keys) {
|
|
||||||
deleteApiKey(keys)
|
|
||||||
.then((res) => {
|
|
||||||
resetFilter();
|
|
||||||
setSuccessData({
|
|
||||||
title: DEL_KEY_SUCCESS_ALERT,
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
setErrorData({
|
|
||||||
title: DEL_KEY_ERROR_ALERT,
|
|
||||||
list: [error["response"]["data"]["detail"]],
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function lastUsedMessage() {
|
|
||||||
return (
|
|
||||||
<div className="text-xs">
|
|
||||||
<span>
|
|
||||||
{LAST_USED_SPAN_1}
|
|
||||||
<br></br> {LAST_USED_SPAN_2}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Header></Header>
|
|
||||||
{userData && (
|
|
||||||
<div className="main-page-panel">
|
|
||||||
<div className="m-auto flex h-full flex-row justify-center">
|
|
||||||
<div className="basis-5/6">
|
|
||||||
<div className="m-auto flex h-full flex-col space-y-8 p-8 ">
|
|
||||||
<div className="flex items-center justify-between space-y-2">
|
|
||||||
<div>
|
|
||||||
<h2 className="text-2xl font-bold tracking-tight">
|
|
||||||
API keys
|
|
||||||
</h2>
|
|
||||||
<p className="text-muted-foreground">
|
|
||||||
{API_PAGE_PARAGRAPH_1}
|
|
||||||
<br />
|
|
||||||
{API_PAGE_PARAGRAPH_2}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div className="flex items-center space-x-2"></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{keysList.current &&
|
|
||||||
keysList.current.length === 0 &&
|
|
||||||
!loadingKeys && (
|
|
||||||
<>
|
|
||||||
<div className="flex items-center justify-between">
|
|
||||||
<h2>{API_PAGE_USER_KEYS}</h2>
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
<>
|
|
||||||
{loadingKeys && (
|
|
||||||
<div>
|
|
||||||
<strong>Loading...</strong>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
<div
|
|
||||||
className={
|
|
||||||
"max-h-[15rem] overflow-scroll overflow-x-hidden rounded-md border-2 bg-muted custom-scroll" +
|
|
||||||
(loadingKeys ? " border-0" : "")
|
|
||||||
}
|
|
||||||
>
|
|
||||||
{keysList.current &&
|
|
||||||
keysList.current.length > 0 &&
|
|
||||||
!loadingKeys && (
|
|
||||||
<Table className={"table-fixed bg-muted outline-1"}>
|
|
||||||
<TableHeader
|
|
||||||
className={
|
|
||||||
loadingKeys
|
|
||||||
? "hidden"
|
|
||||||
: "table-fixed bg-muted outline-1"
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<TableRow>
|
|
||||||
<TableHead className="h-10">Name</TableHead>
|
|
||||||
<TableHead className="h-10">Key</TableHead>
|
|
||||||
<TableHead className="h-10">Created</TableHead>
|
|
||||||
<TableHead className="flex h-10 items-center">
|
|
||||||
Last Used
|
|
||||||
<ShadTooltip
|
|
||||||
side="top"
|
|
||||||
content={lastUsedMessage()}
|
|
||||||
>
|
|
||||||
<div>
|
|
||||||
<IconComponent
|
|
||||||
name="Info"
|
|
||||||
className="ml-1 h-3 w-3"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</ShadTooltip>
|
|
||||||
</TableHead>
|
|
||||||
<TableHead className="h-10">Total Uses</TableHead>
|
|
||||||
<TableHead className="h-10 w-[100px] text-right"></TableHead>
|
|
||||||
</TableRow>
|
|
||||||
</TableHeader>
|
|
||||||
{!loadingKeys && (
|
|
||||||
<TableBody>
|
|
||||||
{keysList.current.map(
|
|
||||||
(api_keys: ApiKey, index: number) => (
|
|
||||||
<TableRow key={index}>
|
|
||||||
<TableCell className="truncate py-2">
|
|
||||||
<ShadTooltip content={api_keys.name}>
|
|
||||||
<span className="cursor-default">
|
|
||||||
{api_keys.name ? api_keys.name : "-"}
|
|
||||||
</span>
|
|
||||||
</ShadTooltip>
|
|
||||||
</TableCell>
|
|
||||||
<TableCell className="truncate py-2">
|
|
||||||
<span className="cursor-default">
|
|
||||||
{api_keys.api_key}
|
|
||||||
</span>
|
|
||||||
</TableCell>
|
|
||||||
<TableCell className="truncate py-2 ">
|
|
||||||
<ShadTooltip
|
|
||||||
side="top"
|
|
||||||
content={moment(
|
|
||||||
api_keys.created_at
|
|
||||||
).format("YYYY-MM-DD HH:mm")}
|
|
||||||
>
|
|
||||||
<div>
|
|
||||||
{moment(api_keys.created_at).format(
|
|
||||||
"YYYY-MM-DD HH:mm"
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</ShadTooltip>
|
|
||||||
</TableCell>
|
|
||||||
<TableCell className="truncate py-2">
|
|
||||||
<ShadTooltip
|
|
||||||
side="top"
|
|
||||||
content={
|
|
||||||
moment(api_keys.last_used_at).format(
|
|
||||||
"YYYY-MM-DD HH:mm"
|
|
||||||
) === "Invalid date"
|
|
||||||
? "Never"
|
|
||||||
: moment(
|
|
||||||
api_keys.last_used_at
|
|
||||||
).format("YYYY-MM-DD HH:mm")
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<div>
|
|
||||||
{moment(api_keys.last_used_at).format(
|
|
||||||
"YYYY-MM-DD HH:mm"
|
|
||||||
) === "Invalid date"
|
|
||||||
? "Never"
|
|
||||||
: moment(
|
|
||||||
api_keys.last_used_at
|
|
||||||
).format("YYYY-MM-DD HH:mm")}
|
|
||||||
</div>
|
|
||||||
</ShadTooltip>
|
|
||||||
</TableCell>
|
|
||||||
<TableCell className="truncate py-2">
|
|
||||||
{api_keys.total_uses}
|
|
||||||
</TableCell>
|
|
||||||
<TableCell className="flex w-[100px] py-2 text-right">
|
|
||||||
<div className="flex">
|
|
||||||
<ConfirmationModal
|
|
||||||
title="Delete"
|
|
||||||
titleHeader="Delete User"
|
|
||||||
modalContentTitle="Attention!"
|
|
||||||
cancelText="Cancel"
|
|
||||||
confirmationText="Delete"
|
|
||||||
icon={"UserMinus2"}
|
|
||||||
data={api_keys.id}
|
|
||||||
index={index}
|
|
||||||
onConfirm={(index, keys) => {
|
|
||||||
handleDeleteKey(keys);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<ConfirmationModal.Content>
|
|
||||||
<span>
|
|
||||||
Are you sure you want to delete
|
|
||||||
this key? This action cannot be
|
|
||||||
undone.
|
|
||||||
</span>
|
|
||||||
</ConfirmationModal.Content>
|
|
||||||
<ConfirmationModal.Trigger>
|
|
||||||
<IconComponent
|
|
||||||
name="Trash2"
|
|
||||||
className="ml-2 h-4 w-4 cursor-pointer"
|
|
||||||
/>
|
|
||||||
</ConfirmationModal.Trigger>
|
|
||||||
</ConfirmationModal>
|
|
||||||
</div>
|
|
||||||
</TableCell>
|
|
||||||
</TableRow>
|
|
||||||
)
|
|
||||||
)}
|
|
||||||
</TableBody>
|
|
||||||
)}
|
|
||||||
</Table>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="flex items-center justify-between">
|
|
||||||
<div>
|
|
||||||
<SecretKeyModal
|
|
||||||
title="Create new secret key"
|
|
||||||
cancelText="Cancel"
|
|
||||||
confirmationText="Create secret key"
|
|
||||||
icon={"Key"}
|
|
||||||
data={userId}
|
|
||||||
onCloseModal={getKeys}
|
|
||||||
>
|
|
||||||
<Button>
|
|
||||||
<IconComponent name="Plus" className="mr-1 h-5 w-5" />
|
|
||||||
Create new secret key
|
|
||||||
</Button>
|
|
||||||
</SecretKeyModal>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
@ -36,8 +36,8 @@ import {
|
||||||
} from "../../../../utils/reactflowUtils";
|
} from "../../../../utils/reactflowUtils";
|
||||||
import ConnectionLineComponent from "../ConnectionLineComponent";
|
import ConnectionLineComponent from "../ConnectionLineComponent";
|
||||||
import SelectionMenu from "../SelectionMenuComponent";
|
import SelectionMenu from "../SelectionMenuComponent";
|
||||||
import isWrappedWithClass from "./utils/is-wrapped-with-class";
|
|
||||||
import getRandomName from "./utils/get-random-name";
|
import getRandomName from "./utils/get-random-name";
|
||||||
|
import isWrappedWithClass from "./utils/is-wrapped-with-class";
|
||||||
|
|
||||||
const nodeTypes = {
|
const nodeTypes = {
|
||||||
genericNode: GenericNode,
|
genericNode: GenericNode,
|
||||||
|
|
@ -52,19 +52,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);
|
||||||
|
|
@ -81,10 +81,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);
|
||||||
|
|
@ -107,7 +107,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);
|
||||||
|
|
@ -115,8 +115,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,
|
||||||
]);
|
]);
|
||||||
|
|
@ -126,8 +126,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,
|
||||||
]);
|
]);
|
||||||
|
|
@ -180,7 +180,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")) {
|
||||||
|
|
@ -276,7 +276,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]);
|
||||||
|
|
||||||
|
|
@ -285,7 +285,7 @@ export default function Page({
|
||||||
takeSnapshot();
|
takeSnapshot();
|
||||||
onConnect(params);
|
onConnect(params);
|
||||||
},
|
},
|
||||||
[takeSnapshot, onConnect],
|
[takeSnapshot, onConnect]
|
||||||
);
|
);
|
||||||
|
|
||||||
const onNodeDragStart: NodeDragHandler = useCallback(() => {
|
const onNodeDragStart: NodeDragHandler = useCallback(() => {
|
||||||
|
|
@ -326,7 +326,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);
|
||||||
|
|
@ -342,7 +342,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();
|
||||||
|
|
@ -371,7 +371,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(() => {
|
||||||
|
|
@ -387,7 +387,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 => {
|
||||||
|
|
@ -420,7 +420,7 @@ export default function Page({
|
||||||
(flow: OnSelectionChangeParams): void => {
|
(flow: OnSelectionChangeParams): void => {
|
||||||
setLastSelection(flow);
|
setLastSelection(flow);
|
||||||
},
|
},
|
||||||
[],
|
[]
|
||||||
);
|
);
|
||||||
|
|
||||||
const onPaneClick = useCallback((flow) => {
|
const onPaneClick = useCallback((flow) => {
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import { toTitleCase } from "../../../../../utils/utils";
|
||||||
export default function getRandomName(
|
export default function getRandomName(
|
||||||
retry: number = 0,
|
retry: number = 0,
|
||||||
noSpace: boolean = false,
|
noSpace: boolean = false,
|
||||||
maxRetries: number = 3,
|
maxRetries: number = 3
|
||||||
): string {
|
): string {
|
||||||
const left: string[] = ADJECTIVES;
|
const left: string[] = ADJECTIVES;
|
||||||
const right: string[] = NOUNS;
|
const right: string[] = NOUNS;
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@ export default function ExtraSidebar(): JSX.Element {
|
||||||
const [search, setSearch] = useState("");
|
const [search, setSearch] = useState("");
|
||||||
function onDragStart(
|
function onDragStart(
|
||||||
event: React.DragEvent<any>,
|
event: React.DragEvent<any>,
|
||||||
data: { type: string; node?: APIClassType },
|
data: { type: string; node?: APIClassType }
|
||||||
): void {
|
): void {
|
||||||
//start drag event
|
//start drag event
|
||||||
var crt = event.currentTarget.cloneNode(true);
|
var crt = event.currentTarget.cloneNode(true);
|
||||||
|
|
@ -67,7 +67,7 @@ export default function ExtraSidebar(): JSX.Element {
|
||||||
let keys = Object.keys(data[d]).filter(
|
let keys = Object.keys(data[d]).filter(
|
||||||
(nd) =>
|
(nd) =>
|
||||||
nd.toLowerCase().includes(e.toLowerCase()) ||
|
nd.toLowerCase().includes(e.toLowerCase()) ||
|
||||||
data[d][nd].display_name?.toLowerCase().includes(e.toLowerCase()),
|
data[d][nd].display_name?.toLowerCase().includes(e.toLowerCase())
|
||||||
);
|
);
|
||||||
keys.forEach((element) => {
|
keys.forEach((element) => {
|
||||||
ret[d][element] = data[d][element];
|
ret[d][element] = data[d][element];
|
||||||
|
|
@ -134,7 +134,7 @@ export default function ExtraSidebar(): JSX.Element {
|
||||||
|
|
||||||
if (filtered.some((x) => x !== "")) {
|
if (filtered.some((x) => x !== "")) {
|
||||||
let keys = Object.keys(dataClone[d]).filter((nd) =>
|
let keys = Object.keys(dataClone[d]).filter((nd) =>
|
||||||
filtered.includes(nd),
|
filtered.includes(nd)
|
||||||
);
|
);
|
||||||
Object.keys(dataClone[d]).forEach((element) => {
|
Object.keys(dataClone[d]).forEach((element) => {
|
||||||
if (!keys.includes(element)) {
|
if (!keys.includes(element)) {
|
||||||
|
|
@ -171,7 +171,7 @@ export default function ExtraSidebar(): JSX.Element {
|
||||||
|
|
||||||
if (filtered.some((x) => x !== "")) {
|
if (filtered.some((x) => x !== "")) {
|
||||||
let keys = Object.keys(dataClone[d]).filter((nd) =>
|
let keys = Object.keys(dataClone[d]).filter((nd) =>
|
||||||
filtered.includes(nd),
|
filtered.includes(nd)
|
||||||
);
|
);
|
||||||
Object.keys(dataClone[d]).forEach((element) => {
|
Object.keys(dataClone[d]).forEach((element) => {
|
||||||
if (!keys.includes(element)) {
|
if (!keys.includes(element)) {
|
||||||
|
|
@ -200,7 +200,7 @@ export default function ExtraSidebar(): JSX.Element {
|
||||||
"extra-side-bar-buttons gap-[4px] text-sm font-semibold",
|
"extra-side-bar-buttons gap-[4px] text-sm font-semibold",
|
||||||
!hasApiKey || !validApiKey || !hasStore
|
!hasApiKey || !validApiKey || !hasStore
|
||||||
? "button-disable cursor-default text-muted-foreground"
|
? "button-disable cursor-default text-muted-foreground"
|
||||||
: "",
|
: ""
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<IconComponent
|
<IconComponent
|
||||||
|
|
@ -209,14 +209,14 @@ export default function ExtraSidebar(): 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]
|
||||||
);
|
);
|
||||||
|
|
||||||
const ExportMemo = useMemo(
|
const ExportMemo = useMemo(
|
||||||
|
|
@ -227,7 +227,7 @@ export default function ExtraSidebar(): JSX.Element {
|
||||||
</button>
|
</button>
|
||||||
</ExportModal>
|
</ExportModal>
|
||||||
),
|
),
|
||||||
[],
|
[]
|
||||||
);
|
);
|
||||||
|
|
||||||
const getIcon = useMemo(() => {
|
const getIcon = useMemo(() => {
|
||||||
|
|
@ -311,8 +311,8 @@ export default function ExtraSidebar(): JSX.Element {
|
||||||
.sort((a, b) =>
|
.sort((a, b) =>
|
||||||
sensitiveSort(
|
sensitiveSort(
|
||||||
dataFilter[SBSectionName][a].display_name,
|
dataFilter[SBSectionName][a].display_name,
|
||||||
dataFilter[SBSectionName][b].display_name,
|
dataFilter[SBSectionName][b].display_name
|
||||||
),
|
)
|
||||||
)
|
)
|
||||||
.map((SBItemName: string, index) => (
|
.map((SBItemName: string, index) => (
|
||||||
<ShadTooltip
|
<ShadTooltip
|
||||||
|
|
@ -356,7 +356,7 @@ export default function ExtraSidebar(): JSX.Element {
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<div key={index}></div>
|
<div key={index}></div>
|
||||||
),
|
)
|
||||||
)}{" "}
|
)}{" "}
|
||||||
<ParentDisclosureComponent
|
<ParentDisclosureComponent
|
||||||
openDisc={false}
|
openDisc={false}
|
||||||
|
|
@ -393,8 +393,8 @@ export default function ExtraSidebar(): JSX.Element {
|
||||||
.sort((a, b) =>
|
.sort((a, b) =>
|
||||||
sensitiveSort(
|
sensitiveSort(
|
||||||
dataFilter[SBSectionName][a].display_name,
|
dataFilter[SBSectionName][a].display_name,
|
||||||
dataFilter[SBSectionName][b].display_name,
|
dataFilter[SBSectionName][b].display_name
|
||||||
),
|
)
|
||||||
)
|
)
|
||||||
.map((SBItemName: string, index) => (
|
.map((SBItemName: string, index) => (
|
||||||
<ShadTooltip
|
<ShadTooltip
|
||||||
|
|
@ -468,7 +468,7 @@ export default function ExtraSidebar(): JSX.Element {
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<div key={index}></div>
|
<div key={index}></div>
|
||||||
),
|
)
|
||||||
)}
|
)}
|
||||||
</ParentDisclosureComponent>
|
</ParentDisclosureComponent>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ import ExtraSidebar from "./components/extraSidebarComponent";
|
||||||
|
|
||||||
export default function FlowPage({ view }: { view?: boolean }): JSX.Element {
|
export default function FlowPage({ view }: { view?: boolean }): JSX.Element {
|
||||||
const setCurrentFlowId = useFlowsManagerStore(
|
const setCurrentFlowId = useFlowsManagerStore(
|
||||||
(state) => state.setCurrentFlowId,
|
(state) => state.setCurrentFlowId
|
||||||
);
|
);
|
||||||
const version = useDarkStore((state) => state.version);
|
const version = useDarkStore((state) => state.version);
|
||||||
const setOnFlowPage = useFlowStore((state) => state.setOnFlowPage);
|
const setOnFlowPage = useFlowStore((state) => state.setOnFlowPage);
|
||||||
|
|
|
||||||
|
|
@ -31,22 +31,22 @@ export default function ComponentsComponent({
|
||||||
const allFlows = useFlowsManagerStore((state) => state.allFlows);
|
const allFlows = useFlowsManagerStore((state) => state.allFlows);
|
||||||
|
|
||||||
const flowsFromFolder = useFolderStore(
|
const flowsFromFolder = useFolderStore(
|
||||||
(state) => state.selectedFolder?.flows,
|
(state) => state.selectedFolder?.flows
|
||||||
);
|
);
|
||||||
|
|
||||||
const setSuccessData = useAlertStore((state) => state.setSuccessData);
|
const setSuccessData = useAlertStore((state) => state.setSuccessData);
|
||||||
const setErrorData = useAlertStore((state) => state.setErrorData);
|
const setErrorData = useAlertStore((state) => state.setErrorData);
|
||||||
const [openDelete, setOpenDelete] = useState(false);
|
const [openDelete, setOpenDelete] = useState(false);
|
||||||
const searchFlowsComponents = useFlowsManagerStore(
|
const searchFlowsComponents = useFlowsManagerStore(
|
||||||
(state) => state.searchFlowsComponents,
|
(state) => state.searchFlowsComponents
|
||||||
);
|
);
|
||||||
|
|
||||||
const setSelectedFlowsComponentsCards = useFlowsManagerStore(
|
const setSelectedFlowsComponentsCards = useFlowsManagerStore(
|
||||||
(state) => state.setSelectedFlowsComponentsCards,
|
(state) => state.setSelectedFlowsComponentsCards
|
||||||
);
|
);
|
||||||
|
|
||||||
const selectedFlowsComponentsCards = useFlowsManagerStore(
|
const selectedFlowsComponentsCards = useFlowsManagerStore(
|
||||||
(state) => state.selectedFlowsComponentsCards,
|
(state) => state.selectedFlowsComponentsCards
|
||||||
);
|
);
|
||||||
|
|
||||||
const [handleFileDrop] = useFileDrop(uploadFlow, type)!;
|
const [handleFileDrop] = useFileDrop(uploadFlow, type)!;
|
||||||
|
|
@ -82,7 +82,7 @@ export default function ComponentsComponent({
|
||||||
f.name.toLowerCase().includes(searchFlowsComponents.toLowerCase()) ||
|
f.name.toLowerCase().includes(searchFlowsComponents.toLowerCase()) ||
|
||||||
f.description
|
f.description
|
||||||
.toLowerCase()
|
.toLowerCase()
|
||||||
.includes(searchFlowsComponents.toLowerCase()),
|
.includes(searchFlowsComponents.toLowerCase())
|
||||||
);
|
);
|
||||||
|
|
||||||
if (searchFlowsComponents === "") {
|
if (searchFlowsComponents === "") {
|
||||||
|
|
@ -137,9 +137,9 @@ export default function ComponentsComponent({
|
||||||
selectedFlowsComponentsCards.map((selectedFlow) =>
|
selectedFlowsComponentsCards.map((selectedFlow) =>
|
||||||
addFlow(
|
addFlow(
|
||||||
true,
|
true,
|
||||||
allFlows.find((flow) => flow.id === selectedFlow),
|
allFlows.find((flow) => flow.id === selectedFlow)
|
||||||
),
|
)
|
||||||
),
|
)
|
||||||
).then(() => {
|
).then(() => {
|
||||||
resetFilter();
|
resetFilter();
|
||||||
getFoldersApi(true);
|
getFoldersApi(true);
|
||||||
|
|
@ -180,7 +180,7 @@ export default function ComponentsComponent({
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
},
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
setSelectedFlowsComponentsCards(selectedFlows);
|
setSelectedFlowsComponentsCards(selectedFlows);
|
||||||
|
|
@ -215,7 +215,7 @@ export default function ComponentsComponent({
|
||||||
if (type === "all") return allFlows?.length;
|
if (type === "all") return allFlows?.length;
|
||||||
|
|
||||||
return allFlows?.filter(
|
return allFlows?.filter(
|
||||||
(f) => (f.is_component ?? false) === (type === "component"),
|
(f) => (f.is_component ?? false) === (type === "component")
|
||||||
)?.length;
|
)?.length;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import { useNavigate } from "react-router-dom";
|
|
||||||
import useFlowsManagerStore from "../../../../stores/flowsManagerStore";
|
|
||||||
import NewFlowModal from "../../../../modals/newFlowModal";
|
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
|
import { useNavigate } from "react-router-dom";
|
||||||
|
import NewFlowModal from "../../../../modals/newFlowModal";
|
||||||
|
import useFlowsManagerStore from "../../../../stores/flowsManagerStore";
|
||||||
|
|
||||||
type EmptyComponentProps = {};
|
type EmptyComponentProps = {};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,8 @@
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import IconComponent from "../../../../components/genericIconComponent";
|
import IconComponent from "../../../../components/genericIconComponent";
|
||||||
import {
|
|
||||||
Select,
|
|
||||||
SelectContent,
|
|
||||||
SelectGroup,
|
|
||||||
SelectItem,
|
|
||||||
SelectTrigger,
|
|
||||||
SelectValue,
|
|
||||||
} from "../../../../components/ui/select";
|
|
||||||
import { Checkbox } from "../../../../components/ui/checkbox";
|
|
||||||
import { Button } from "../../../../components/ui/button";
|
|
||||||
import { cn } from "../../../../utils/utils";
|
|
||||||
import ShadTooltip from "../../../../components/shadTooltipComponent";
|
import ShadTooltip from "../../../../components/shadTooltipComponent";
|
||||||
|
import { Checkbox } from "../../../../components/ui/checkbox";
|
||||||
|
import { cn } from "../../../../utils/utils";
|
||||||
|
|
||||||
type HeaderComponentProps = {
|
type HeaderComponentProps = {
|
||||||
handleSelectAll: (select) => void;
|
handleSelectAll: (select) => void;
|
||||||
|
|
@ -91,7 +82,7 @@ const HeaderComponent = ({
|
||||||
name="Trash2"
|
name="Trash2"
|
||||||
className={cn(
|
className={cn(
|
||||||
"h-5 w-5 text-primary transition-all",
|
"h-5 w-5 text-primary transition-all",
|
||||||
disableFunctions ? "" : "hover:text-destructive",
|
disableFunctions ? "" : "hover:text-destructive"
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
</button>
|
</button>
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,11 @@
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
|
import { useLocation } from "react-router-dom";
|
||||||
|
import useAlertStore from "../../../../../../stores/alertStore";
|
||||||
import useFlowsManagerStore from "../../../../../../stores/flowsManagerStore";
|
import useFlowsManagerStore from "../../../../../../stores/flowsManagerStore";
|
||||||
|
import { useFolderStore } from "../../../../../../stores/foldersStore";
|
||||||
|
import { handleDownloadFolderFn } from "../../../../utils/handle-download-folder";
|
||||||
import InputSearchComponent from "../inputSearchComponent";
|
import InputSearchComponent from "../inputSearchComponent";
|
||||||
import TabsSearchComponent from "../tabsComponent";
|
import TabsSearchComponent from "../tabsComponent";
|
||||||
import { Button } from "../../../../../../components/ui/button";
|
|
||||||
import ForwardedIconComponent from "../../../../../../components/genericIconComponent";
|
|
||||||
import useAlertStore from "../../../../../../stores/alertStore";
|
|
||||||
import { handleDownloadFolderFn } from "../../../../utils/handle-download-folder";
|
|
||||||
import { useFolderStore } from "../../../../../../stores/foldersStore";
|
|
||||||
import { useLocation } from "react-router-dom";
|
|
||||||
|
|
||||||
type HeaderTabsSearchComponentProps = {};
|
type HeaderTabsSearchComponentProps = {};
|
||||||
|
|
||||||
|
|
@ -22,7 +20,7 @@ const HeaderTabsSearchComponent = ({}: HeaderTabsSearchComponentProps) => {
|
||||||
const [inputValue, setInputValue] = useState("");
|
const [inputValue, setInputValue] = useState("");
|
||||||
|
|
||||||
const setSearchFlowsComponents = useFlowsManagerStore(
|
const setSearchFlowsComponents = useFlowsManagerStore(
|
||||||
(state) => state.setSearchFlowsComponents,
|
(state) => state.setSearchFlowsComponents
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleDownloadFolder = () => {
|
const handleDownloadFolder = () => {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import { ChangeEvent, KeyboardEvent } from "react";
|
import { ChangeEvent, KeyboardEvent } from "react";
|
||||||
|
import ForwardedIconComponent from "../../../../../../components/genericIconComponent";
|
||||||
import { Input } from "../../../../../../components/ui/input";
|
import { Input } from "../../../../../../components/ui/input";
|
||||||
import useFlowsManagerStore from "../../../../../../stores/flowsManagerStore";
|
import useFlowsManagerStore from "../../../../../../stores/flowsManagerStore";
|
||||||
import ForwardedIconComponent from "../../../../../../components/genericIconComponent";
|
|
||||||
|
|
||||||
type InputSearchComponentProps = {
|
type InputSearchComponentProps = {
|
||||||
loading: boolean;
|
loading: boolean;
|
||||||
|
|
@ -23,7 +23,7 @@ const InputSearchComponent = ({
|
||||||
const pagePath = window.location.pathname;
|
const pagePath = window.location.pathname;
|
||||||
const allFlows = useFlowsManagerStore((state) => state.allFlows);
|
const allFlows = useFlowsManagerStore((state) => state.allFlows);
|
||||||
const searchFlowsComponents = useFlowsManagerStore(
|
const searchFlowsComponents = useFlowsManagerStore(
|
||||||
(state) => state.searchFlowsComponents,
|
(state) => state.searchFlowsComponents
|
||||||
);
|
);
|
||||||
|
|
||||||
const disableInputSearch =
|
const disableInputSearch =
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ import useDropdownOptions from "../../hooks/use-dropdown-options";
|
||||||
export default function HomePage(): JSX.Element {
|
export default function HomePage(): JSX.Element {
|
||||||
const uploadFlow = useFlowsManagerStore((state) => state.uploadFlow);
|
const uploadFlow = useFlowsManagerStore((state) => state.uploadFlow);
|
||||||
const setCurrentFlowId = useFlowsManagerStore(
|
const setCurrentFlowId = useFlowsManagerStore(
|
||||||
(state) => state.setCurrentFlowId,
|
(state) => state.setCurrentFlowId
|
||||||
);
|
);
|
||||||
|
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue