Squashed commit of the following:
commit5c3f3dbb70Author: italojohnny <italojohnnydosanjos@gmail.com> Date: Wed Jun 5 17:57:08 2024 -0300 fix libs commit2c7d7616faAuthor: anovazzi1 <otavio2204@gmail.com> Date: Wed Jun 5 17:45:17 2024 -0300 fix selection bug on Messages Table commit183f0bcca5Author: anovazzi1 <otavio2204@gmail.com> Date: Wed Jun 5 17:28:01 2024 -0300 update route commit79f998333fMerge:be919f1bcbcdc329d1Author: anovazzi1 <otavio2204@gmail.com> Date: Wed Jun 5 16:51:59 2024 -0300 Merge remote-tracking branch 'origin/dev' into SessionManagment commitbe919f1bcaAuthor: anovazzi1 <otavio2204@gmail.com> Date: Tue Jun 4 17:06:16 2024 -0300 Refactor: Remove commented code for chat history tab in IOModal commit91e3bd9151Author: igorrCarvalho <igorsilvabhz6@gmail.com> Date: Tue Jun 4 16:33:05 2024 -0300 Refactor: Remove select from delete session button commit83b837966dAuthor: igorrCarvalho <igorsilvabhz6@gmail.com> Date: Tue Jun 4 15:53:51 2024 -0300 Refactor: Make Reset Column button reset columns order commit254a2c423cAuthor: anovazzi1 <otavio2204@gmail.com> Date: Tue Jun 4 14:38:40 2024 -0300 Refactor: Add ResetColumns component to improve table functionality commit5275126e64Author: anovazzi1 <otavio2204@gmail.com> Date: Tue Jun 4 14:06:38 2024 -0300 chore: Update description text in SettingsPage commitfb27528a00Merge:0024753313369b54b8Author: anovazzi1 <otavio2204@gmail.com> Date: Mon Jun 3 22:17:15 2024 -0300 Merge branch 'SessionManagment' of personal:langflow-ai/langflow into SessionManagment commit3369b54b83Author: igorrCarvalho <igorsilvabhz6@gmail.com> Date: Mon Jun 3 20:03:40 2024 -0300 Refactor: remove page size directly in css file commitc8fad13a3cAuthor: igorrCarvalho <igorsilvabhz6@gmail.com> Date: Mon Jun 3 19:42:06 2024 -0300 Refactor: Remove “Page size” from table pagination commit49882e4201Author: igorrCarvalho <igorsilvabhz6@gmail.com> Date: Mon Jun 3 19:34:43 2024 -0300 Remove unnused imports commitcd36ff8ad7Merge:cdf9d77b4adeaf4db9Author: igorrCarvalho <igorsilvabhz6@gmail.com> Date: Mon Jun 3 19:28:44 2024 -0300 Merge SessionManagement into SessionManagement commitcdf9d77b45Author: igorrCarvalho <igorsilvabhz6@gmail.com> Date: Mon Jun 3 19:25:47 2024 -0300 Feat: Make the table last column non-resizable and add a restore columns button commit002475331eAuthor: anovazzi1 <otavio2204@gmail.com> Date: Mon Jun 3 18:27:35 2024 -0300 update editable fields commitadeaf4db91Merge:d670ec8d6818696a66Author: cristhianzl <cristhian.lousa@gmail.com> Date: Mon Jun 3 18:17:19 2024 -0300 Merge branch 'SessionManagment' of https://github.com/langflow-ai/langflow into SessionManagment commitd670ec8d64Author: cristhianzl <cristhian.lousa@gmail.com> Date: Mon Jun 3 18:17:15 2024 -0300 🐛 (service.py): add missing 'id' column in SQL query to fix data retrieval issue 💡 (service.py): add print statement for debugging SQL query ♻️ (index.tsx): reorder imports for better readability and maintainability ♻️ (flowStore.ts): remove trailing commas to improve code consistency and readability 💡 (index.ts, storeUtils.ts): format type definitions for better readability commit818696a661Author: anovazzi1 <otavio2204@gmail.com> Date: Mon Jun 3 17:37:14 2024 -0300 refactor: Add getSessions function to fetch available sessions in IOModal commit895df8c050Author: cristhianzl <cristhian.lousa@gmail.com> Date: Mon Jun 3 17:05:50 2024 -0300 ♻️ (monitor.py, service.py): remove trailing whitespace to improve code cleanliness commit0e56617e26Author: cristhianzl <cristhian.lousa@gmail.com> Date: Mon Jun 3 17:05:39 2024 -0300 ♻️ (monitor.py): refactor update_message to return MessageModelResponse ♻️ (service.py): update SQL query to use index instead of id ♻️ (api.tsx): refactor duplicate request check logic ✨ (check-duplicate-requests.ts): add helper to check and store duplicate requests 🐛 (messagesStore.ts): fix message update logic to use index instead of id commit41c2d7feb5Author: anovazzi1 <otavio2204@gmail.com> Date: Mon Jun 3 14:48:05 2024 -0300 start history in playgroundModal commit93568b4c0dMerge:21a8545ddf3922dfffAuthor: cristhianzl <cristhian.lousa@gmail.com> Date: Mon Jun 3 10:31:46 2024 -0300 ✨ (tableComponent): add editable prop to TableComponent for column editing ✨ (API): add updateMessageApi function to update messages via API ✨ (chatView): add select dropdown for clearing builds and sessions ♻️ (use-messages-table): refactor to use messages store for setting messages ♻️ (use-remove-messages): remove setRows and use messages store for deletion ✨ (use-updateMessage): add hook for updating messages with API integration 📝 (headerMessages): update header message text in messages page ✨ (messagesPage): add cell edit request handling for message updates ♻️ (messagesPage): refactor state management and hooks usage ✨ (types): add new types for chat and message handling commit21a8545ddbAuthor: cristhianzl <cristhian.lousa@gmail.com> Date: Mon Jun 3 10:29:58 2024 -0300 ♻️ (monitor.py): change POST to DELETE for delete_messages endpoint ♻️ (schemas.py): remove unused MessageIds schema ♻️ (api.tsx): add missing commas in ApiInterceptor function 🐛 (api.tsx): fix duplicate request check to include method "get" ♻️ (index.ts): change deleteMessagesFn to use DELETE method instead of POST ♻️ (use-remove-messages.tsx): clean up comments and improve error handling commitf3922dfff6Author: anovazzi1 <otavio2204@gmail.com> Date: Sun Jun 2 19:38:15 2024 -0300 refactor: Move editable attribute to TableComponent add update function, need to fix backend commit1a65af7602Author: anovazzi1 <otavio2204@gmail.com> Date: Sun Jun 2 18:07:45 2024 -0300 move editable attribute to table Component commit729150a5a4Author: anovazzi1 <otavio2204@gmail.com> Date: Fri May 31 22:40:53 2024 -0300 refactor(headerMessages): update text content in HeaderMessagesComponent commit1d06969364Merge:57c38acac70f4fd077Author: anovazzi1 <otavio2204@gmail.com> Date: Fri May 31 17:47:08 2024 -0300 Merge remote-tracking branch 'origin/ic/flow_eraser_dropdown' into SessionManagment commit57c38acaceAuthor: cristhianzl <cristhian.lousa@gmail.com> Date: Fri May 31 13:43:41 2024 -0300 💡 (schemas.py): add newline at end of file to follow PEP 8 guidelines commit602ebf7b15Author: cristhianzl <cristhian.lousa@gmail.com> Date: Fri May 31 13:43:28 2024 -0300 ✨ (monitor.py): add MessageIds schema for structured message deletion ♻️ (monitor.py): change delete_messages endpoint to POST for better semantics ♻️ (monitor.py): update delete_messages to use MessageIds schema ✨ (schemas.py): add MessageIds schema for structured message deletion 🐛 (service.py): fix SQL query in delete_messages to use correct column name ✨ (index.tsx): add toTitleCase utility to format column headers ✨ (API/index.ts): add deleteMessagesFn to handle message deletion via API ✨ (headerMessages): add HeaderMessagesComponent for message management UI ✨ (use-messages-table): add useMessagesTable hook to fetch and manage messages ✨ (use-remove-messages): add useRemoveMessages hook to handle message deletion ♻️ (messagesPage): refactor messages page to use new messages store ✨ (messagesStore): create zustand store for managing messages state ✨ (types): add types for messages and zustand messages store commitf79289f966Author: ogabrielluiz <gabriel@langflow.org> Date: Fri May 31 09:38:05 2024 -0300 feat: Add API endpoints for managing messages This commit adds new API endpoints for managing messages. It includes the ability to delete messages by their IDs, update a specific message, and delete all messages associated with a session. These changes are implemented in the `monitor.py`, `schema.py`, and `service.py` files. commita99d0c7eb0Author: anovazzi1 <otavio2204@gmail.com> Date: Wed May 29 17:48:12 2024 -0300 refactor(tableComponent): update column definitions to include checkbox selection logic for first column feat(API): add support for excluding specific columns in getMessagesTable function fix(flowLogsModal): pass excludedFields parameter to getMessagesTable function refactor(GlobalVariablesPage): remove unnecessary checkbox selection properties from column definitions fix(messagesPage): pass excludedFields parameter to getMessagesTable function refactor(utils): add support for excluding specific columns in extractColumnsFromRows function commit022ef7c028Author: anovazzi1 <otavio2204@gmail.com> Date: Wed May 29 17:15:21 2024 -0300 feat: Add Messages page to SettingsPage Refactor the SettingsPage component to include a new "Messages" page. This page will be accessible through the "/settings/messages" route and will display messages related to user settings. The necessary changes have been made to the index.tsx file of the SettingsPage component and the routes.tsx file. commit70f4fd0770Author: igorrCarvalho <igorsilvabhz6@gmail.com> Date: Mon May 27 21:36:00 2024 -0300 Feat: Create the first version of the eraser tool
This commit is contained in:
parent
2f98d87731
commit
af80b4c4e1
69 changed files with 1433 additions and 758 deletions
|
|
@ -86,11 +86,12 @@ from langflow.load import run_flow_from_json
|
|||
|
||||
results = run_flow_from_json("path/to/flow.json", input_value="Hello, World!")
|
||||
```
|
||||
|
||||
# 部署
|
||||
|
||||
## 在Google Cloud Platform上部署Langflow
|
||||
|
||||
请按照我们的分步指南使用 Google Cloud Shell 在 Google Cloud Platform (GCP) 上部署 Langflow。该指南在 [**Langflow in Google Cloud Platform**](GCP_DEPLOYMENT.md) 文档中提供。
|
||||
请按照我们的分步指南使用 Google Cloud Shell 在 Google Cloud Platform (GCP) 上部署 Langflow。该指南在 [**Langflow in Google Cloud Platform**](GCP_DEPLOYMENT.md) 文档中提供。
|
||||
|
||||
或者,点击下面的 "Open in Cloud Shell" 按钮,启动 Google Cloud Shell,克隆 Langflow 仓库,并开始一个互动教程,该教程将指导您设置必要的资源并在 GCP 项目中部署 Langflow。
|
||||
|
||||
|
|
@ -168,4 +169,4 @@ langflow run [OPTIONS]
|
|||
|
||||
# 📄 许可证
|
||||
|
||||
Langflow 以 MIT 许可证发布。有关详细信息,请参阅 [LICENSE](LICENSE) 文件。
|
||||
Langflow 以 MIT 许可证发布。有关详细信息,请参阅 [LICENSE](LICENSE) 文件。
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@ Global Variables are a useful feature of Langflow, allowing you to define reusab
|
|||
- All Credential Global Variables are encrypted and accessible only by you.
|
||||
- Set _`LANGFLOW_STORE_ENVIRONMENT_VARIABLES`_ to _`true`_ in your `.env` file to add all variables in _`LANGFLOW_VARIABLES_TO_GET_FROM_ENVIRONMENT`_ to your user's Global Variables.
|
||||
|
||||
|
||||
## Creating and Adding a Global Variable
|
||||
|
||||
To create and add a global variable, click the 🌐 button in a Text field, and then click **+ Add New Variable**.
|
||||
|
|
@ -25,18 +24,20 @@ To create and add a global variable, click the 🌐 button in a Text field, and
|
|||
Text fields are where you write text without opening a Text area, and are identified with the 🌐 icon.
|
||||
|
||||
For example, to create an environment variable for the **OpenAI** component:
|
||||
1. In the **OpenAI API Key** text field, click the 🌐 button, then **Add New Variable**.
|
||||
2. Enter `openai_api_key` in the **Variable Name** field.
|
||||
3. Paste your OpenAI API Key (`sk-...`) in the **Value** field.
|
||||
4. Select **Credential** for the **Type**.
|
||||
5. Choose **OpenAI API Key** in the **Apply to Fields** field to apply this variable to all fields named **OpenAI API Key**.
|
||||
6. Click **Save Variable**.
|
||||
|
||||
1. In the **OpenAI API Key** text field, click the 🌐 button, then **Add New Variable**.
|
||||
2. Enter `openai_api_key` in the **Variable Name** field.
|
||||
3. Paste your OpenAI API Key (`sk-...`) in the **Value** field.
|
||||
4. Select **Credential** for the **Type**.
|
||||
5. Choose **OpenAI API Key** in the **Apply to Fields** field to apply this variable to all fields named **OpenAI API Key**.
|
||||
6. Click **Save Variable**.
|
||||
|
||||
You now have a `openai_api_key` global environment variable for your Langflow project.
|
||||
Subsequently, clicking the 🌐 button in a Text field will display the new variable in the dropdown.
|
||||
|
||||
<Admonition type="tip">
|
||||
You can also create global variables in **Settings** > **Variables and Secrets**.
|
||||
You can also create global variables in **Settings** > **Variables and
|
||||
Secrets**.
|
||||
</Admonition>
|
||||
|
||||
<ZoomableImage
|
||||
|
|
@ -65,7 +66,8 @@ Setting `LANGFLOW_STORE_ENVIRONMENT_VARIABLES` to `true` in your `.env` file (de
|
|||
These variables are accessible like any other Global Variable.
|
||||
|
||||
<Admonition type="tip">
|
||||
To prevent this behavior, set `LANGFLOW_STORE_ENVIRONMENT_VARIABLES` to `false` in your `.env` file.
|
||||
To prevent this behavior, set `LANGFLOW_STORE_ENVIRONMENT_VARIABLES` to
|
||||
`false` in your `.env` file.
|
||||
</Admonition>
|
||||
|
||||
You can specify variables to get from the environment by listing them in `LANGFLOW_VARIABLES_TO_GET_FROM_ENVIRONMENT`.
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import Admonition from '@theme/Admonition';
|
||||
import Admonition from "@theme/Admonition";
|
||||
import ZoomableImage from "/src/theme/ZoomableImage.js";
|
||||
|
||||
# Inputs and Outputs
|
||||
|
|
@ -29,9 +29,8 @@ This component collects user input from the chat.
|
|||
|
||||
<Admonition type="note" title="Note">
|
||||
<p>
|
||||
If `As Record` is `true` and the `Message` is a `Record`, the data
|
||||
of the `Record` will be updated with the `Sender`, `Sender Name`, and
|
||||
`Session ID`.
|
||||
If `As Record` is `true` and the `Message` is a `Record`, the data of the
|
||||
`Record` will be updated with the `Sender`, `Sender Name`, and `Session ID`.
|
||||
</p>
|
||||
</Admonition>
|
||||
|
||||
|
|
@ -112,9 +111,10 @@ This component sends a message to the chat.
|
|||
- **Message:** Specifies the text of the message.
|
||||
|
||||
<Admonition type="note" title="Note">
|
||||
<p>
|
||||
If `As Record` is `true` and the `Message` is a `Record`, the data in the `Record` is updated with the `Sender`, `Sender Name`, and `Session ID`.
|
||||
</p>
|
||||
<p>
|
||||
If `As Record` is `true` and the `Message` is a `Record`, the data in the
|
||||
`Record` is updated with the `Sender`, `Sender Name`, and `Session ID`.
|
||||
</p>
|
||||
</Admonition>
|
||||
|
||||
### Text Output
|
||||
|
|
@ -125,7 +125,6 @@ This component displays text data to the user. It is useful when you want to sho
|
|||
|
||||
- **Value:** Specifies the text data to be displayed. Defaults to an empty string.
|
||||
|
||||
|
||||
The `TextOutput` component provides a simple way to display text data. It allows textual data to be visible in the chat window during your interaction flow.
|
||||
|
||||
## Prompts
|
||||
|
|
@ -155,7 +154,8 @@ The `PromptTemplate` component enables users to create prompts and define variab
|
|||
|
||||
<Admonition type="info">
|
||||
After defining a variable in the prompt template, it acts as its own component
|
||||
input. See [Prompt Customization](../administration/prompt-customization) for more details.
|
||||
input. See [Prompt Customization](../administration/prompt-customization) for
|
||||
more details.
|
||||
</Admonition>
|
||||
|
||||
- **template:** The template used to format an individual request.
|
||||
- **template:** The template used to format an individual request.
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
In Langflow 1.0, we added two main input and output types: `Text` and `Record`.
|
||||
|
||||
`Text` is a simple string input and output type, while ``Record`` is a structure very similar to a dictionary in Python. It is a key-value pair data structure.
|
||||
`Text` is a simple string input and output type, while `Record` is a structure very similar to a dictionary in Python. It is a key-value pair data structure.
|
||||
|
||||
We've created a few components to help you work with these types. Let's see how a few of them work.
|
||||
|
||||
|
|
|
|||
798
poetry.lock
generated
798
poetry.lock
generated
File diff suppressed because it is too large
Load diff
|
|
@ -1,6 +1,6 @@
|
|||
[tool.poetry]
|
||||
name = "langflow"
|
||||
version = "1.0.0a46"
|
||||
version = "1.0.0a43"
|
||||
description = "A Python package with a built-in web application"
|
||||
authors = ["Langflow <contact@langflow.org>"]
|
||||
maintainers = [
|
||||
|
|
@ -81,7 +81,7 @@ langchain-google-vertexai = "^1.0.3"
|
|||
langchain-groq = "^0.1.3"
|
||||
langchain-pinecone = "^0.1.0"
|
||||
langchain-mistralai = "^0.1.6"
|
||||
couchbase = { extras = ["couchbase"], version = "^4.2.1", optional = true }
|
||||
couchbase = "^4.2.1"
|
||||
youtube-transcript-api = "^0.6.2"
|
||||
markdown = "^3.6"
|
||||
langchain-chroma = "^0.1.1"
|
||||
|
|
@ -118,7 +118,6 @@ vulture = "^2.11"
|
|||
|
||||
[tool.poetry.extras]
|
||||
deploy = ["celery", "redis", "flower"]
|
||||
couchbase = ["couchbase"]
|
||||
local = ["llama-cpp-python", "sentence-transformers", "ctransformers"]
|
||||
|
||||
|
||||
|
|
@ -141,7 +140,7 @@ testpaths = ["tests", "integration"]
|
|||
console_output_style = "progress"
|
||||
filterwarnings = ["ignore::DeprecationWarning"]
|
||||
log_cli = true
|
||||
markers = ["async_test", "api_key_required"]
|
||||
markers = ["async_test"]
|
||||
|
||||
|
||||
[tool.ruff]
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
from typing import List, Optional
|
||||
|
||||
from uuid import UUID
|
||||
from fastapi import APIRouter, Depends, HTTPException, Query
|
||||
|
||||
from langflow.services.deps import get_monitor_service
|
||||
from langflow.services.monitor.schema import (
|
||||
MessageModelRequest,
|
||||
MessageModelResponse,
|
||||
TransactionModelResponse,
|
||||
VertexBuildMapModel,
|
||||
|
|
@ -66,6 +67,44 @@ async def get_messages(
|
|||
raise HTTPException(status_code=500, detail=str(e))
|
||||
|
||||
|
||||
@router.delete("/messages", status_code=204)
|
||||
async def delete_messages(
|
||||
message_ids: List[int],
|
||||
monitor_service: MonitorService = Depends(get_monitor_service),
|
||||
):
|
||||
try:
|
||||
monitor_service.delete_messages(message_ids=message_ids)
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=str(e))
|
||||
|
||||
|
||||
@router.post("/messages/{message_id}", response_model=MessageModelResponse)
|
||||
async def update_message(
|
||||
message_id: str,
|
||||
message: MessageModelRequest,
|
||||
monitor_service: MonitorService = Depends(get_monitor_service),
|
||||
):
|
||||
try:
|
||||
message_dict = message.model_dump(exclude_none=True)
|
||||
message_dict.pop("index", None)
|
||||
monitor_service.update_message(message_id=message_id, **message_dict)
|
||||
return MessageModelResponse(index=message_id, **message_dict)
|
||||
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=str(e))
|
||||
|
||||
|
||||
@router.delete("/messages/session/{session_id}", status_code=204)
|
||||
async def delete_messages_session(
|
||||
session_id: str,
|
||||
monitor_service: MonitorService = Depends(get_monitor_service),
|
||||
):
|
||||
try:
|
||||
monitor_service.delete_messages_session(session_id=session_id)
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=str(e))
|
||||
|
||||
|
||||
@router.get("/transactions", response_model=List[TransactionModelResponse])
|
||||
async def get_transactions(
|
||||
source: Optional[str] = Query(None),
|
||||
|
|
|
|||
|
|
@ -122,6 +122,13 @@ class MessageModelResponse(MessageModel):
|
|||
return v
|
||||
|
||||
|
||||
class MessageModelRequest(MessageModel):
|
||||
message: str = Field(default="")
|
||||
sender: str = Field(default="")
|
||||
sender_name: str = Field(default="")
|
||||
session_id: str = Field(default="")
|
||||
|
||||
|
||||
class VertexBuildModel(BaseModel):
|
||||
index: Optional[int] = Field(default=None, alias="index", exclude=True)
|
||||
id: Optional[str] = Field(default=None, alias="id")
|
||||
|
|
|
|||
|
|
@ -32,6 +32,10 @@ class MonitorService(Service):
|
|||
except Exception as e:
|
||||
logger.exception(f"Error initializing monitor service: {e}")
|
||||
|
||||
def exec_query(self, query: str):
|
||||
with duckdb.connect(str(self.db_path)) as conn:
|
||||
return conn.execute(query).df()
|
||||
|
||||
def to_df(self, table_name):
|
||||
return self.load_table_as_dataframe(table_name)
|
||||
|
||||
|
|
@ -69,7 +73,7 @@ class MonitorService(Service):
|
|||
valid: Optional[bool] = None,
|
||||
order_by: Optional[str] = "timestamp",
|
||||
):
|
||||
query = "SELECT index,flow_id, valid, params, data, artifacts, timestamp FROM vertex_builds"
|
||||
query = "SELECT id, index,flow_id, valid, params, data, artifacts, timestamp FROM vertex_builds"
|
||||
conditions = []
|
||||
if flow_id:
|
||||
conditions.append(f"flow_id = '{flow_id}'")
|
||||
|
|
@ -88,6 +92,8 @@ class MonitorService(Service):
|
|||
with duckdb.connect(str(self.db_path)) as conn:
|
||||
df = conn.execute(query).df()
|
||||
|
||||
print(query)
|
||||
|
||||
return df.to_dict(orient="records")
|
||||
|
||||
def delete_vertex_builds(self, flow_id: Optional[str] = None):
|
||||
|
|
@ -98,11 +104,20 @@ class MonitorService(Service):
|
|||
with duckdb.connect(str(self.db_path)) as conn:
|
||||
conn.execute(query)
|
||||
|
||||
def delete_messages(self, session_id: str):
|
||||
def delete_messages_session(self, session_id: str):
|
||||
query = f"DELETE FROM messages WHERE session_id = '{session_id}'"
|
||||
|
||||
with duckdb.connect(str(self.db_path)) as conn:
|
||||
conn.execute(query)
|
||||
return self.exec_query(query)
|
||||
|
||||
def delete_messages(self, message_ids: list[int]):
|
||||
query = f"DELETE FROM messages WHERE index IN ({','.join(map(str, message_ids))})"
|
||||
|
||||
return self.exec_query(query)
|
||||
|
||||
def update_message(self, message_id: int, **kwargs):
|
||||
query = f"""UPDATE messages SET {', '.join(f"{k} = '{v}'" for k, v in kwargs.items())} WHERE index = {message_id}"""
|
||||
|
||||
return self.exec_query(query)
|
||||
|
||||
def add_message(self, message: MessageModel):
|
||||
self.add_row("messages", message)
|
||||
|
|
|
|||
26
src/frontend/package-lock.json
generated
26
src/frontend/package-lock.json
generated
|
|
@ -26,6 +26,7 @@
|
|||
"@radix-ui/react-slot": "^1.0.2",
|
||||
"@radix-ui/react-switch": "^1.0.3",
|
||||
"@radix-ui/react-tabs": "^1.0.4",
|
||||
"@radix-ui/react-toggle": "^1.0.3",
|
||||
"@radix-ui/react-tooltip": "^1.0.6",
|
||||
"@tabler/icons-react": "^2.32.0",
|
||||
"@tailwindcss/forms": "^0.5.6",
|
||||
|
|
@ -2762,6 +2763,31 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-toggle": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-toggle/-/react-toggle-1.0.3.tgz",
|
||||
"integrity": "sha512-Pkqg3+Bc98ftZGsl60CLANXQBBQ4W3mTFS9EJvNxKMZ7magklKV69/id1mlAlOFDDfHvlCms0fx8fA4CMKDJHg==",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.13.10",
|
||||
"@radix-ui/primitive": "1.0.1",
|
||||
"@radix-ui/react-primitive": "1.0.3",
|
||||
"@radix-ui/react-use-controllable-state": "1.0.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"@types/react-dom": "*",
|
||||
"react": "^16.8 || ^17.0 || ^18.0",
|
||||
"react-dom": "^16.8 || ^17.0 || ^18.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
},
|
||||
"@types/react-dom": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-tooltip": {
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.0.7.tgz",
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
"@radix-ui/react-slot": "^1.0.2",
|
||||
"@radix-ui/react-switch": "^1.0.3",
|
||||
"@radix-ui/react-tabs": "^1.0.4",
|
||||
"@radix-ui/react-toggle": "^1.0.3",
|
||||
"@radix-ui/react-tooltip": "^1.0.6",
|
||||
"@tabler/icons-react": "^2.32.0",
|
||||
"@tailwindcss/forms": "^0.5.6",
|
||||
|
|
|
|||
|
|
@ -23,19 +23,19 @@ export default function AddNewVariableButton({ children }): JSX.Element {
|
|||
const setErrorData = useAlertStore((state) => state.setErrorData);
|
||||
const componentFields = useTypesStore((state) => state.ComponentFields);
|
||||
const unavaliableFields = new Set(
|
||||
Object.keys(useGlobalVariablesStore((state) => state.unavaliableFields))
|
||||
Object.keys(useGlobalVariablesStore((state) => state.unavaliableFields)),
|
||||
);
|
||||
|
||||
const availableFields = () => {
|
||||
const fields = Array.from(componentFields).filter(
|
||||
(field) => !unavaliableFields.has(field)
|
||||
(field) => !unavaliableFields.has(field),
|
||||
);
|
||||
|
||||
return sortByName(fields);
|
||||
};
|
||||
|
||||
const addGlobalVariable = useGlobalVariablesStore(
|
||||
(state) => state.addGlobalVariable
|
||||
(state) => state.addGlobalVariable,
|
||||
);
|
||||
|
||||
function handleSaveVariable() {
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ export default function InputListComponent({
|
|||
<div
|
||||
className={classNames(
|
||||
value.length > 1 && editNode ? "my-1" : "",
|
||||
"flex flex-col gap-3"
|
||||
"flex flex-col gap-3",
|
||||
)}
|
||||
>
|
||||
{value.map((singleValue, idx) => {
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ const SideBarFoldersButtonsComponent = ({
|
|||
const [foldersNames, setFoldersNames] = useState({});
|
||||
const takeSnapshot = useFlowsManagerStore((state) => state.takeSnapshot);
|
||||
const [editFolders, setEditFolderName] = useState(
|
||||
folders.map((obj) => ({ name: obj.name, edit: false }))
|
||||
folders.map((obj) => ({ name: obj.name, edit: false })),
|
||||
);
|
||||
const uploadFolder = useFolderStore((state) => state.uploadFolder);
|
||||
const currentFolder = pathname.split("/");
|
||||
|
|
@ -58,7 +58,7 @@ const SideBarFoldersButtonsComponent = ({
|
|||
|
||||
const { dragOver, dragEnter, dragLeave, onDrop } = useFileDrop(
|
||||
folderId,
|
||||
handleFolderChange
|
||||
handleFolderChange,
|
||||
);
|
||||
|
||||
const handleUploadFlowsToFolder = () => {
|
||||
|
|
@ -73,7 +73,7 @@ const SideBarFoldersButtonsComponent = ({
|
|||
addFolder({ name: "New Folder", parent_id: null, description: "" }).then(
|
||||
(res) => {
|
||||
getFoldersApi(true);
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -119,7 +119,7 @@ const SideBarFoldersButtonsComponent = ({
|
|||
<>
|
||||
{folders.map((item, index) => {
|
||||
const editFolderName = editFolders?.filter(
|
||||
(folder) => folder.name === item.name
|
||||
(folder) => folder.name === item.name,
|
||||
)[0];
|
||||
return (
|
||||
<div
|
||||
|
|
@ -135,7 +135,7 @@ const SideBarFoldersButtonsComponent = ({
|
|||
? "border border-border bg-muted hover:bg-muted"
|
||||
: "border hover:bg-transparent lg:border-transparent lg:hover:border-border",
|
||||
"group flex w-full shrink-0 cursor-pointer gap-2 opacity-100 lg:min-w-full",
|
||||
folderIdDragging === item.id! ? "bg-border" : ""
|
||||
folderIdDragging === item.id! ? "bg-border" : "",
|
||||
)}
|
||||
onClick={() => handleChangeFolder!(item.id!)}
|
||||
>
|
||||
|
|
@ -205,7 +205,7 @@ const SideBarFoldersButtonsComponent = ({
|
|||
folders.map((obj) => ({
|
||||
name: obj.name,
|
||||
edit: false,
|
||||
}))
|
||||
})),
|
||||
);
|
||||
}
|
||||
if (e.key === "Enter") {
|
||||
|
|
@ -238,10 +238,10 @@ const SideBarFoldersButtonsComponent = ({
|
|||
};
|
||||
const updatedFolder = await updateFolder(
|
||||
body,
|
||||
item.id!
|
||||
item.id!,
|
||||
);
|
||||
const updateFolders = folders.filter(
|
||||
(f) => f.name !== item.name
|
||||
(f) => f.name !== item.name,
|
||||
);
|
||||
setFolders([...updateFolders, updatedFolder]);
|
||||
setFoldersNames({});
|
||||
|
|
@ -249,7 +249,7 @@ const SideBarFoldersButtonsComponent = ({
|
|||
folders.map((obj) => ({
|
||||
name: obj.name,
|
||||
edit: false,
|
||||
}))
|
||||
})),
|
||||
);
|
||||
} else {
|
||||
setFoldersNames((old) => ({
|
||||
|
|
|
|||
|
|
@ -0,0 +1,31 @@
|
|||
import { cn } from "../../../../utils/utils";
|
||||
import ShadTooltip from "../../../shadTooltipComponent";
|
||||
import { Toggle } from "../../../ui/toggle";
|
||||
|
||||
export default function ResetColumns({
|
||||
resetGrid,
|
||||
}: {
|
||||
resetGrid: () => void;
|
||||
}): JSX.Element {
|
||||
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")}>
|
||||
<span
|
||||
className="cursor-pointer underline"
|
||||
onClick={() => {
|
||||
resetGrid();
|
||||
}}
|
||||
>
|
||||
Reset Columns
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
@ -1,22 +1,27 @@
|
|||
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 { AgGridReact, AgGridReactProps } from "ag-grid-react";
|
||||
import { ElementRef, forwardRef, useCallback } from "react";
|
||||
import { ElementRef, forwardRef, useEffect, useRef } from "react";
|
||||
import {
|
||||
DEFAULT_TABLE_ALERT_MSG,
|
||||
DEFAULT_TABLE_ALERT_TITLE,
|
||||
} from "../../constants/constants";
|
||||
import { useDarkStore } from "../../stores/darkStore";
|
||||
import "../../style/ag-theme-shadcn.css"; // Custom CSS applied to the grid
|
||||
import { cn } from "../../utils/utils";
|
||||
import { cn, toTitleCase } from "../../utils/utils";
|
||||
import ForwardedIconComponent from "../genericIconComponent";
|
||||
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";
|
||||
|
||||
interface TableComponentProps extends AgGridReactProps {
|
||||
columnDefs: NonNullable<AgGridReactProps["columnDefs"]>;
|
||||
rowData: NonNullable<AgGridReactProps["rowData"]>;
|
||||
alertTitle?: string;
|
||||
alertDescription?: string;
|
||||
editable?: boolean | string[];
|
||||
}
|
||||
|
||||
const TableComponent = forwardRef<
|
||||
|
|
@ -31,7 +36,67 @@ const TableComponent = forwardRef<
|
|||
},
|
||||
ref,
|
||||
) => {
|
||||
let colDef = props.columnDefs.map((col, index) => {
|
||||
let newCol = {
|
||||
...col,
|
||||
headerName: toTitleCase(col.headerName),
|
||||
};
|
||||
if (index === props.columnDefs.length - 1) {
|
||||
newCol = {
|
||||
...newCol,
|
||||
resizable: false,
|
||||
};
|
||||
}
|
||||
if (props.onSelectionChanged && index === 0) {
|
||||
newCol = {
|
||||
...newCol,
|
||||
checkboxSelection: true,
|
||||
headerCheckboxSelection: true,
|
||||
headerCheckboxSelectionFilteredOnly: true,
|
||||
};
|
||||
}
|
||||
if (
|
||||
(typeof props.editable === "boolean" && props.editable) ||
|
||||
(Array.isArray(props.editable) &&
|
||||
props.editable.includes(newCol.headerName ?? ""))
|
||||
) {
|
||||
newCol = {
|
||||
...newCol,
|
||||
editable: true,
|
||||
};
|
||||
}
|
||||
return newCol;
|
||||
});
|
||||
const gridRef = useRef(null);
|
||||
// @ts-ignore
|
||||
const realRef = ref?.current ? ref : gridRef;
|
||||
const dark = useDarkStore((state) => state.dark);
|
||||
const initialColumnDefs = useRef(colDef);
|
||||
|
||||
const makeLastColumnNonResizable = (columnDefs) => {
|
||||
columnDefs.forEach((colDef, index) => {
|
||||
colDef.resizable = index !== columnDefs.length - 1;
|
||||
});
|
||||
return columnDefs;
|
||||
};
|
||||
|
||||
const onGridReady = (params) => {
|
||||
// @ts-ignore
|
||||
realRef.current = params;
|
||||
const updatedColumnDefs = makeLastColumnNonResizable([...colDef]);
|
||||
params.api.setColumnDefs(updatedColumnDefs);
|
||||
initialColumnDefs.current = params.api.getColumnDefs();
|
||||
if (props.onGridReady) props.onGridReady(params);
|
||||
};
|
||||
|
||||
const onColumnMoved = (params) => {
|
||||
const updatedColumnDefs = makeLastColumnNonResizable(
|
||||
params.columnApi.getAllGridColumns().map((col) => col.getColDef()),
|
||||
);
|
||||
params.api.setColumnDefs(updatedColumnDefs);
|
||||
if (props.onColumnMoved) props.onColumnMoved(params);
|
||||
};
|
||||
|
||||
if (props.rowData.length === 0) {
|
||||
return (
|
||||
<div className="flex h-full w-full items-center justify-center rounded-md border">
|
||||
|
|
@ -46,12 +111,12 @@ const TableComponent = forwardRef<
|
|||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
className={cn(
|
||||
dark ? "ag-theme-quartz-dark" : "ag-theme-quartz",
|
||||
"ag-theme-shadcn flex h-full flex-col",
|
||||
"relative",
|
||||
)} // applying the grid theme
|
||||
>
|
||||
<AgGridReact
|
||||
|
|
@ -60,8 +125,13 @@ const TableComponent = forwardRef<
|
|||
defaultColDef={{
|
||||
minWidth: 100,
|
||||
}}
|
||||
ref={ref}
|
||||
columnDefs={colDef}
|
||||
ref={realRef}
|
||||
pagination={true}
|
||||
onGridReady={onGridReady}
|
||||
onColumnMoved={onColumnMoved}
|
||||
/>
|
||||
<ResetColumns resetGrid={() => resetGrid(realRef, initialColumnDefs)} />
|
||||
</div>
|
||||
);
|
||||
},
|
||||
|
|
|
|||
|
|
@ -0,0 +1,12 @@
|
|||
export default function resetGrid(ref, initialColumnDefs) {
|
||||
if (ref?.current && ref?.current.api) {
|
||||
ref.current.api.resetColumnState();
|
||||
if (initialColumnDefs.current) {
|
||||
const resetColumns = ref.current.api.applyColumnState({
|
||||
state: initialColumnDefs.current,
|
||||
applyOrder: true,
|
||||
});
|
||||
return resetColumns;
|
||||
}
|
||||
}
|
||||
}
|
||||
45
src/frontend/src/components/ui/toggle.tsx
Normal file
45
src/frontend/src/components/ui/toggle.tsx
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
"use client";
|
||||
|
||||
import * as React from "react";
|
||||
import * as TogglePrimitive from "@radix-ui/react-toggle";
|
||||
import { cva, type VariantProps } from "class-variance-authority";
|
||||
|
||||
import { cn } from "../../utils/utils";
|
||||
|
||||
const toggleVariants = cva(
|
||||
"inline-flex items-center justify-center rounded-md text-sm font-medium ring-offset-background transition-colors hover:bg-muted hover:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
|
||||
{
|
||||
variants: {
|
||||
variant: {
|
||||
default: "bg-transparent",
|
||||
outline:
|
||||
"border border-input bg-transparent hover:bg-accent hover:text-accent-foreground",
|
||||
},
|
||||
size: {
|
||||
default: "h-10 px-3",
|
||||
sm: "h-9 px-2.5",
|
||||
lg: "h-11 px-5",
|
||||
},
|
||||
},
|
||||
defaultVariants: {
|
||||
variant: "default",
|
||||
size: "default",
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
const Toggle = React.forwardRef<
|
||||
React.ElementRef<typeof TogglePrimitive.Root>,
|
||||
React.ComponentPropsWithoutRef<typeof TogglePrimitive.Root> &
|
||||
VariantProps<typeof toggleVariants>
|
||||
>(({ className, variant, size, ...props }, ref) => (
|
||||
<TogglePrimitive.Root
|
||||
ref={ref}
|
||||
className={cn(toggleVariants({ variant, size, className }))}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
|
||||
Toggle.displayName = TogglePrimitive.Root.displayName;
|
||||
|
||||
export { Toggle, toggleVariants };
|
||||
|
|
@ -48,7 +48,7 @@ function ApiInterceptor() {
|
|||
}
|
||||
await clearBuildVerticesState(error);
|
||||
return Promise.reject(error);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
const isAuthorizedURL = (url) => {
|
||||
|
|
@ -65,10 +65,10 @@ function ApiInterceptor() {
|
|||
const parsedURL = new URL(url);
|
||||
|
||||
const isDomainAllowed = authorizedDomains.some(
|
||||
(domain) => parsedURL.origin === new URL(domain).origin
|
||||
(domain) => parsedURL.origin === new URL(domain).origin,
|
||||
);
|
||||
const isEndpointAllowed = authorizedEndpoints.some((endpoint) =>
|
||||
parsedURL.pathname.includes(endpoint)
|
||||
parsedURL.pathname.includes(endpoint),
|
||||
);
|
||||
|
||||
return isDomainAllowed || isEndpointAllowed;
|
||||
|
|
@ -96,7 +96,7 @@ function ApiInterceptor() {
|
|||
},
|
||||
(error) => {
|
||||
return Promise.reject(error);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
return () => {
|
||||
|
|
@ -128,7 +128,7 @@ function ApiInterceptor() {
|
|||
if (error?.config?.headers) {
|
||||
delete error.config.headers["Authorization"];
|
||||
error.config.headers["Authorization"] = `Bearer ${cookies.get(
|
||||
"access_token_lf"
|
||||
"access_token_lf",
|
||||
)}`;
|
||||
const response = await axios.request(error.config);
|
||||
return response;
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ import {
|
|||
UploadFileTypeAPI,
|
||||
errorsTypeAPI,
|
||||
} from "./../../types/api/index";
|
||||
import { Message } from "../../types/messages";
|
||||
|
||||
/**
|
||||
* Fetches all objects from the API endpoint.
|
||||
|
|
@ -61,7 +62,7 @@ export async function sendAll(data: sendAllProps) {
|
|||
}
|
||||
|
||||
export async function postValidateCode(
|
||||
code: string
|
||||
code: string,
|
||||
): Promise<AxiosResponse<errorsTypeAPI>> {
|
||||
return await api.post(`${BASE_URL_API}validate/code`, { code });
|
||||
}
|
||||
|
|
@ -76,7 +77,7 @@ export async function postValidateCode(
|
|||
export async function postValidatePrompt(
|
||||
name: string,
|
||||
template: string,
|
||||
frontend_node: APIClassType
|
||||
frontend_node: APIClassType,
|
||||
): Promise<AxiosResponse<PromptTypeAPI>> {
|
||||
return api.post(`${BASE_URL_API}validate/prompt`, {
|
||||
name,
|
||||
|
|
@ -149,7 +150,7 @@ export async function saveFlowToDatabase(newFlow: {
|
|||
* @throws Will throw an error if the update fails.
|
||||
*/
|
||||
export async function updateFlowInDatabase(
|
||||
updatedFlow: FlowType
|
||||
updatedFlow: FlowType,
|
||||
): Promise<FlowType> {
|
||||
try {
|
||||
const response = await api.patch(`${BASE_URL_API}flows/${updatedFlow.id}`, {
|
||||
|
|
@ -327,7 +328,7 @@ export async function getHealth() {
|
|||
*
|
||||
*/
|
||||
export async function getBuildStatus(
|
||||
flowId: string
|
||||
flowId: string,
|
||||
): Promise<AxiosResponse<BuildStatusTypeAPI>> {
|
||||
return await api.get(`${BASE_URL_API}build/${flowId}/status`);
|
||||
}
|
||||
|
|
@ -340,7 +341,7 @@ export async function getBuildStatus(
|
|||
*
|
||||
*/
|
||||
export async function postBuildInit(
|
||||
flow: FlowType
|
||||
flow: FlowType,
|
||||
): Promise<AxiosResponse<InitTypeAPI>> {
|
||||
return await api.post(`${BASE_URL_API}build/init/${flow.id}`, flow);
|
||||
}
|
||||
|
|
@ -356,7 +357,7 @@ export async function postBuildInit(
|
|||
*/
|
||||
export async function uploadFile(
|
||||
file: File,
|
||||
id: string
|
||||
id: string,
|
||||
): Promise<AxiosResponse<UploadFileTypeAPI>> {
|
||||
const formData = new FormData();
|
||||
formData.append("file", file);
|
||||
|
|
@ -365,7 +366,7 @@ export async function uploadFile(
|
|||
|
||||
export async function postCustomComponent(
|
||||
code: string,
|
||||
apiClass: APIClassType
|
||||
apiClass: APIClassType,
|
||||
): Promise<AxiosResponse<APIClassType>> {
|
||||
// let template = apiClass.template;
|
||||
return await api.post(`${BASE_URL_API}custom_component`, {
|
||||
|
|
@ -378,7 +379,7 @@ export async function postCustomComponentUpdate(
|
|||
code: string,
|
||||
template: APITemplateType,
|
||||
field: string,
|
||||
field_value: any
|
||||
field_value: any,
|
||||
): Promise<AxiosResponse<APIClassType>> {
|
||||
return await api.post(`${BASE_URL_API}custom_component/update`, {
|
||||
code,
|
||||
|
|
@ -400,7 +401,7 @@ export async function onLogin(user: LoginType) {
|
|||
headers: {
|
||||
"Content-Type": "application/x-www-form-urlencoded",
|
||||
},
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
if (response.status === 200) {
|
||||
|
|
@ -462,11 +463,11 @@ export async function addUser(user: UserInputType): Promise<Array<Users>> {
|
|||
|
||||
export async function getUsersPage(
|
||||
skip: number,
|
||||
limit: number
|
||||
limit: number,
|
||||
): Promise<Array<Users>> {
|
||||
try {
|
||||
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) {
|
||||
return res.data;
|
||||
|
|
@ -503,7 +504,7 @@ export async function resetPassword(user_id: string, user: resetPasswordType) {
|
|||
try {
|
||||
const res = await api.patch(
|
||||
`${BASE_URL_API}users/${user_id}/reset-password`,
|
||||
user
|
||||
user,
|
||||
);
|
||||
if (res.status === 200) {
|
||||
return res.data;
|
||||
|
|
@ -577,7 +578,7 @@ export async function saveFlowStore(
|
|||
last_tested_version?: string;
|
||||
},
|
||||
tags: string[],
|
||||
publicFlow = false
|
||||
publicFlow = false,
|
||||
): Promise<FlowType> {
|
||||
try {
|
||||
const response = await api.post(`${BASE_URL_API}store/components/`, {
|
||||
|
|
@ -706,7 +707,7 @@ export async function postStoreComponents(component: Component) {
|
|||
export async function getComponent(component_id: string) {
|
||||
try {
|
||||
const res = await api.get(
|
||||
`${BASE_URL_API}store/components/${component_id}`
|
||||
`${BASE_URL_API}store/components/${component_id}`,
|
||||
);
|
||||
if (res.status === 200) {
|
||||
return res.data;
|
||||
|
|
@ -721,7 +722,7 @@ export async function searchComponent(
|
|||
page?: number | null,
|
||||
limit?: number | null,
|
||||
status?: string | null,
|
||||
tags?: string[]
|
||||
tags?: string[],
|
||||
): Promise<StoreComponentResponse | undefined> {
|
||||
try {
|
||||
let url = `${BASE_URL_API}store/components/`;
|
||||
|
|
@ -833,7 +834,7 @@ export async function updateFlowStore(
|
|||
},
|
||||
tags: string[],
|
||||
publicFlow = false,
|
||||
id: string
|
||||
id: string,
|
||||
): Promise<FlowType> {
|
||||
try {
|
||||
const response = await api.patch(`${BASE_URL_API}store/components/${id}`, {
|
||||
|
|
@ -917,7 +918,7 @@ export async function deleteGlobalVariable(id: string) {
|
|||
export async function updateGlobalVariable(
|
||||
name: string,
|
||||
value: string,
|
||||
id: string
|
||||
id: string,
|
||||
) {
|
||||
try {
|
||||
const response = api.patch(`${BASE_URL_API}variables/${id}`, {
|
||||
|
|
@ -936,7 +937,7 @@ export async function getVerticesOrder(
|
|||
startNodeId?: string | null,
|
||||
stopNodeId?: string | null,
|
||||
nodes?: Node[],
|
||||
Edges?: Edge[]
|
||||
Edges?: Edge[],
|
||||
): Promise<AxiosResponse<VerticesOrderTypeAPI>> {
|
||||
// nodeId is optional and is a query parameter
|
||||
// if nodeId is not provided, the API will return all vertices
|
||||
|
|
@ -956,19 +957,19 @@ export async function getVerticesOrder(
|
|||
return await api.post(
|
||||
`${BASE_URL_API}build/${flowId}/vertices`,
|
||||
data,
|
||||
config
|
||||
config,
|
||||
);
|
||||
}
|
||||
|
||||
export async function postBuildVertex(
|
||||
flowId: string,
|
||||
vertexId: string,
|
||||
input_value: string
|
||||
input_value: string,
|
||||
): Promise<AxiosResponse<VertexBuildTypeAPI>> {
|
||||
// input_value is optional and is a query parameter
|
||||
return await api.post(
|
||||
`${BASE_URL_API}build/${flowId}/vertices/${vertexId}`,
|
||||
input_value ? { inputs: { input_value: input_value } } : undefined
|
||||
input_value ? { inputs: { input_value: input_value } } : undefined,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -992,7 +993,7 @@ export async function getFlowPool({
|
|||
}
|
||||
|
||||
export async function deleteFlowPool(
|
||||
flowId: string
|
||||
flowId: string,
|
||||
): Promise<AxiosResponse<any>> {
|
||||
const config = {};
|
||||
config["params"] = { flow_id: flowId };
|
||||
|
|
@ -1006,7 +1007,7 @@ export async function deleteFlowPool(
|
|||
* @returns A promise that resolves to an array of AxiosResponse objects representing the delete responses.
|
||||
*/
|
||||
export async function multipleDeleteFlowsComponents(
|
||||
flowIds: string[]
|
||||
flowIds: string[],
|
||||
): Promise<AxiosResponse<any>[]> {
|
||||
const batches: string[][] = [];
|
||||
|
||||
|
|
@ -1029,7 +1030,7 @@ export async function multipleDeleteFlowsComponents(
|
|||
|
||||
// Execute all delete requests
|
||||
const responses: Promise<AxiosResponse<any>>[] = batches.map((batch) =>
|
||||
deleteBatch(batch)
|
||||
deleteBatch(batch),
|
||||
);
|
||||
|
||||
// Return the responses after all requests are completed
|
||||
|
|
@ -1039,7 +1040,7 @@ export async function multipleDeleteFlowsComponents(
|
|||
export async function getTransactionTable(
|
||||
id: string,
|
||||
mode: "intersection" | "union",
|
||||
params = {}
|
||||
params = {},
|
||||
): Promise<{ rows: Array<object>; columns: Array<ColDef | ColGroupDef> }> {
|
||||
const config = {};
|
||||
config["params"] = { flow_id: id };
|
||||
|
|
@ -1052,16 +1053,47 @@ export async function getTransactionTable(
|
|||
}
|
||||
|
||||
export async function getMessagesTable(
|
||||
id: string,
|
||||
mode: "intersection" | "union",
|
||||
params = {}
|
||||
): Promise<{ rows: Array<object>; columns: Array<ColDef | ColGroupDef> }> {
|
||||
id?: string,
|
||||
excludedFields?: string[],
|
||||
params = {},
|
||||
): Promise<{ rows: Array<Message>; columns: Array<ColDef | ColGroupDef> }> {
|
||||
const config = {};
|
||||
config["params"] = { flow_id: id };
|
||||
if (id) {
|
||||
config["params"] = { flow_id: id };
|
||||
}
|
||||
if (params) {
|
||||
config["params"] = { ...config["params"], ...params };
|
||||
}
|
||||
const rows = await api.get(`${BASE_URL_API}monitor/messages`, config);
|
||||
const columns = extractColumnsFromRows(rows.data, mode);
|
||||
const columns = extractColumnsFromRows(rows.data, mode, excludedFields);
|
||||
return { rows: rows.data, columns };
|
||||
}
|
||||
|
||||
export async function getSessions(id?: string): Promise<Array<string>> {
|
||||
const config = {};
|
||||
if (id) {
|
||||
config["params"] = { flow_id: id };
|
||||
}
|
||||
const rows = await api.get(`${BASE_URL_API}monitor/messages`, config);
|
||||
const sessions = new Set<string>();
|
||||
rows.data.forEach((row) => {
|
||||
sessions.add(row.session_id);
|
||||
});
|
||||
return Array.from(sessions);
|
||||
}
|
||||
|
||||
export async function deleteMessagesFn(ids: number[]) {
|
||||
try {
|
||||
return await api.delete(`${BASE_URL_API}monitor/messages`, {
|
||||
data: ids,
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("Error deleting flows:", error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
export async function updateMessageApi(data: Message) {
|
||||
return await api.post(`${BASE_URL_API}monitor/messages/${data.index}`, data);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,14 +55,14 @@ export default function GenericNode({
|
|||
const [nodeName, setNodeName] = useState(data.node!.display_name);
|
||||
const [inputDescription, setInputDescription] = useState(false);
|
||||
const [nodeDescription, setNodeDescription] = useState(
|
||||
data.node?.description!
|
||||
data.node?.description!,
|
||||
);
|
||||
const [isOutdated, setIsOutdated] = useState(false);
|
||||
const buildStatus = useFlowStore(
|
||||
(state) => state.flowBuildStatus[data.id]?.status
|
||||
(state) => state.flowBuildStatus[data.id]?.status,
|
||||
);
|
||||
const lastRunTime = useFlowStore(
|
||||
(state) => state.flowBuildStatus[data.id]?.timestamp
|
||||
(state) => state.flowBuildStatus[data.id]?.timestamp,
|
||||
);
|
||||
const [validationStatus, setValidationStatus] =
|
||||
useState<validationStatusType | null>(null);
|
||||
|
|
@ -115,7 +115,7 @@ export default function GenericNode({
|
|||
|
||||
updateNodeInternals(data.id);
|
||||
},
|
||||
[data.id, data.node, setNode, setIsOutdated]
|
||||
[data.id, data.node, setNode, setIsOutdated],
|
||||
);
|
||||
|
||||
if (!data.node!.template) {
|
||||
|
|
@ -255,7 +255,7 @@ export default function GenericNode({
|
|||
const isDark = useDarkStore((state) => state.dark);
|
||||
const renderIconStatus = (
|
||||
buildStatus: BuildStatus | undefined,
|
||||
validationStatus: validationStatusType | null
|
||||
validationStatus: validationStatusType | null,
|
||||
) => {
|
||||
if (buildStatus === BuildStatus.BUILDING) {
|
||||
return <Loading className="text-medium-indigo" />;
|
||||
|
|
@ -296,7 +296,7 @@ export default function GenericNode({
|
|||
};
|
||||
const getSpecificClassFromBuildStatus = (
|
||||
buildStatus: BuildStatus | undefined,
|
||||
validationStatus: validationStatusType | null
|
||||
validationStatus: validationStatusType | null,
|
||||
) => {
|
||||
let isInvalid = validationStatus && !validationStatus.valid;
|
||||
|
||||
|
|
@ -320,11 +320,11 @@ export default function GenericNode({
|
|||
selected: boolean,
|
||||
showNode: boolean,
|
||||
buildStatus: BuildStatus | undefined,
|
||||
validationStatus: validationStatusType | null
|
||||
validationStatus: validationStatusType | null,
|
||||
) => {
|
||||
const specificClassFromBuildStatus = getSpecificClassFromBuildStatus(
|
||||
buildStatus,
|
||||
validationStatus
|
||||
validationStatus,
|
||||
);
|
||||
|
||||
const baseBorderClass = getBaseBorderClass(selected);
|
||||
|
|
@ -333,7 +333,7 @@ export default function GenericNode({
|
|||
baseBorderClass,
|
||||
nodeSizeClass,
|
||||
"generic-node-div",
|
||||
specificClassFromBuildStatus
|
||||
specificClassFromBuildStatus,
|
||||
);
|
||||
return names;
|
||||
};
|
||||
|
|
@ -393,7 +393,7 @@ export default function GenericNode({
|
|||
selected,
|
||||
showNode,
|
||||
buildStatus,
|
||||
validationStatus
|
||||
validationStatus,
|
||||
)}
|
||||
>
|
||||
{data.node?.beta && showNode && (
|
||||
|
|
@ -524,7 +524,7 @@ export default function GenericNode({
|
|||
}
|
||||
title={getFieldTitle(
|
||||
data.node?.template!,
|
||||
templateField
|
||||
templateField,
|
||||
)}
|
||||
info={data.node?.template[templateField].info}
|
||||
name={templateField}
|
||||
|
|
@ -552,7 +552,7 @@ export default function GenericNode({
|
|||
proxy={data.node?.template[templateField].proxy}
|
||||
showNode={showNode}
|
||||
/>
|
||||
)
|
||||
),
|
||||
)}
|
||||
<ParameterComponent
|
||||
key={scapedJSONStringfy({
|
||||
|
|
@ -709,7 +709,7 @@ export default function GenericNode({
|
|||
!data.node?.description) &&
|
||||
nameEditable
|
||||
? "font-light italic"
|
||||
: ""
|
||||
: "",
|
||||
)}
|
||||
onClick={(e) => {
|
||||
setInputDescription(true);
|
||||
|
|
@ -771,13 +771,13 @@ export default function GenericNode({
|
|||
}
|
||||
title={getFieldTitle(
|
||||
data.node?.template!,
|
||||
templateField
|
||||
templateField,
|
||||
)}
|
||||
info={data.node?.template[templateField].info}
|
||||
name={templateField}
|
||||
tooltipTitle={
|
||||
data.node?.template[templateField].input_types?.join(
|
||||
"\n"
|
||||
"\n",
|
||||
) ?? data.node?.template[templateField].type
|
||||
}
|
||||
required={data.node!.template[templateField].required}
|
||||
|
|
@ -804,7 +804,7 @@ export default function GenericNode({
|
|||
<div
|
||||
className={classNames(
|
||||
Object.keys(data.node!.template).length < 1 ? "hidden" : "",
|
||||
"flex-max-width justify-center"
|
||||
"flex-max-width justify-center",
|
||||
)}
|
||||
>
|
||||
{" "}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ const useFetchDataOnMount = (
|
|||
handleUpdateValues,
|
||||
setNode,
|
||||
renderTooltips,
|
||||
setIsLoading
|
||||
setIsLoading,
|
||||
) => {
|
||||
const setErrorData = useAlertStore((state) => state.setErrorData);
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ const useHandleOnNewValue = (
|
|||
debouncedHandleUpdateValues,
|
||||
setNode,
|
||||
renderTooltips,
|
||||
setIsLoading
|
||||
setIsLoading,
|
||||
) => {
|
||||
const setErrorData = useAlertStore((state) => state.setErrorData);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,11 @@
|
|||
import { useEffect, useRef, useState } from "react";
|
||||
import IconComponent from "../../../../components/genericIconComponent";
|
||||
import {
|
||||
Select,
|
||||
SelectContent,
|
||||
SelectItem,
|
||||
SelectTrigger,
|
||||
} from "../../../../components/ui/select";
|
||||
import {
|
||||
CHAT_FIRST_INITIAL_TEXT,
|
||||
CHAT_SECOND_INITIAL_TEXT,
|
||||
|
|
@ -118,10 +124,21 @@ export default function ChatView({
|
|||
if (lockChat) setLockChat(false);
|
||||
}
|
||||
|
||||
function handleSelectChange(event: string): void {
|
||||
switch (event) {
|
||||
case "builds":
|
||||
clearChat();
|
||||
break;
|
||||
case "buildsNSession":
|
||||
console.log("delete build and session");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function updateChat(
|
||||
chat: ChatMessageType,
|
||||
message: string,
|
||||
stream_url?: string
|
||||
stream_url?: string,
|
||||
) {
|
||||
// if (message === "") return;
|
||||
chat.message = message;
|
||||
|
|
@ -149,18 +166,57 @@ export default function ChatView({
|
|||
<div className="eraser-column-arrangement">
|
||||
<div className="eraser-size">
|
||||
<div className="eraser-position">
|
||||
<button disabled={lockChat} onClick={() => clearChat()}>
|
||||
<button
|
||||
className="flex gap-1"
|
||||
onClick={() => handleSelectChange("builds")}
|
||||
>
|
||||
<IconComponent
|
||||
name="Eraser"
|
||||
className={classNames(
|
||||
"h-5 w-5",
|
||||
lockChat
|
||||
? "animate-pulse text-primary"
|
||||
: "text-primary hover:text-gray-600"
|
||||
"h-5 w-5 transition-all duration-100",
|
||||
lockChat ? "animate-pulse text-primary" : "text-primary",
|
||||
)}
|
||||
aria-hidden="true"
|
||||
/>
|
||||
</button>
|
||||
{/* <Select
|
||||
onValueChange={handleSelectChange}
|
||||
value=""
|
||||
disabled={lockChat}
|
||||
>
|
||||
<SelectTrigger className="">
|
||||
<button className="flex gap-1">
|
||||
<IconComponent
|
||||
name="Eraser"
|
||||
className={classNames(
|
||||
"h-5 w-5 transition-all duration-100",
|
||||
lockChat ? "animate-pulse text-primary" : "text-primary",
|
||||
)}
|
||||
aria-hidden="true"
|
||||
/>
|
||||
</button>
|
||||
</SelectTrigger>
|
||||
<SelectContent className="right-[9.5em]">
|
||||
<SelectItem value="builds" className="cursor-pointer">
|
||||
<div className="flex">
|
||||
<IconComponent
|
||||
name={"Trash2"}
|
||||
className={`relative top-0.5 mr-2 h-4 w-4`}
|
||||
/>
|
||||
<span className="">Clear Builds</span>
|
||||
</div>
|
||||
</SelectItem>
|
||||
<SelectItem value="buildsNSession" className="cursor-pointer">
|
||||
<div className="flex">
|
||||
<IconComponent
|
||||
name={"Trash2"}
|
||||
className={`relative top-0.5 mr-2 h-4 w-4`}
|
||||
/>
|
||||
<span className="">Clear Builds & Session</span>
|
||||
</div>
|
||||
</SelectItem>
|
||||
</SelectContent>
|
||||
</Select> */}
|
||||
</div>
|
||||
<div ref={messagesRef} className="chat-message-div">
|
||||
{chatHistory?.length > 0 ? (
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ import { cn } from "../../utils/utils";
|
|||
import BaseModal from "../baseModal";
|
||||
import IOFieldView from "./components/IOFieldView";
|
||||
import ChatView from "./components/chatView";
|
||||
import { getSessions } from "../../controllers/API";
|
||||
|
||||
export default function IOModal({
|
||||
children,
|
||||
|
|
@ -77,6 +78,7 @@ export default function IOModal({
|
|||
const isBuilding = useFlowStore((state) => state.isBuilding);
|
||||
const currentFlow = useFlowsManagerStore((state) => state.currentFlow);
|
||||
const setNode = useFlowStore((state) => state.setNode);
|
||||
const [sessions, setSessions] = useState<string[]>([]);
|
||||
|
||||
async function updateVertices() {
|
||||
return updateVerticesOrder(currentFlow!.id, null);
|
||||
|
|
@ -113,6 +115,11 @@ export default function IOModal({
|
|||
|
||||
useEffect(() => {
|
||||
setSelectedViewField(startView());
|
||||
// if (haveChat) {
|
||||
// getSessions().then((sessions) => {
|
||||
// setSessions(sessions);
|
||||
// });
|
||||
// }
|
||||
}, [open]);
|
||||
|
||||
return (
|
||||
|
|
@ -161,6 +168,9 @@ export default function IOModal({
|
|||
{outputs.length > 0 && (
|
||||
<TabsTrigger value={"2"}>Outputs</TabsTrigger>
|
||||
)}
|
||||
{/* {haveChat && (
|
||||
<TabsTrigger value={"3"}>History</TabsTrigger>
|
||||
)} */}
|
||||
</TabsList>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ export default function getPythonApiCode(
|
|||
flowId: string,
|
||||
isAuth: boolean,
|
||||
tweaksBuildedObject,
|
||||
endpointName?: string
|
||||
endpointName?: string,
|
||||
): string {
|
||||
const tweaksObject = tweaksBuildedObject[0];
|
||||
return `import argparse
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ const ApiModal = forwardRef(
|
|||
flow: FlowType;
|
||||
children: ReactNode;
|
||||
},
|
||||
ref
|
||||
ref,
|
||||
) => {
|
||||
const tweak = useTweaksStore((state) => state.tweak);
|
||||
const addTweaks = useTweaksStore((state) => state.setTweak);
|
||||
|
|
@ -50,18 +50,18 @@ const ApiModal = forwardRef(
|
|||
flow?.id,
|
||||
autoLogin,
|
||||
tweak,
|
||||
flow?.endpoint_name
|
||||
flow?.endpoint_name,
|
||||
);
|
||||
const curl_run_code = getCurlRunCode(
|
||||
flow?.id,
|
||||
autoLogin,
|
||||
tweak,
|
||||
flow?.endpoint_name
|
||||
flow?.endpoint_name,
|
||||
);
|
||||
const curl_webhook_code = getCurlWebhookCode(
|
||||
flow?.id,
|
||||
autoLogin,
|
||||
flow?.endpoint_name
|
||||
flow?.endpoint_name,
|
||||
);
|
||||
const pythonCode = getPythonCode(flow?.name, tweak);
|
||||
const widgetCode = getWidgetCode(flow?.id, flow?.name, autoLogin);
|
||||
|
|
@ -77,7 +77,7 @@ const ApiModal = forwardRef(
|
|||
pythonCode,
|
||||
];
|
||||
const [tabs, setTabs] = useState(
|
||||
createTabsArray(codesArray, includeWebhook)
|
||||
createTabsArray(codesArray, includeWebhook),
|
||||
);
|
||||
|
||||
const canShowTweaks =
|
||||
|
|
@ -126,7 +126,7 @@ const ApiModal = forwardRef(
|
|||
buildTweakObject(
|
||||
nodeId,
|
||||
element.data.node.template[templateField].value,
|
||||
element.data.node.template[templateField]
|
||||
element.data.node.template[templateField],
|
||||
);
|
||||
}
|
||||
});
|
||||
|
|
@ -143,7 +143,7 @@ const ApiModal = forwardRef(
|
|||
async function buildTweakObject(
|
||||
tw: string,
|
||||
changes: string | string[] | boolean | number | Object[] | Object,
|
||||
template: TemplateVariableType
|
||||
template: TemplateVariableType,
|
||||
) {
|
||||
changes = getChangesType(changes, template);
|
||||
|
||||
|
|
@ -185,7 +185,7 @@ const ApiModal = forwardRef(
|
|||
flow?.id,
|
||||
autoLogin,
|
||||
cloneTweak,
|
||||
flow?.endpoint_name
|
||||
flow?.endpoint_name,
|
||||
);
|
||||
const pythonCode = getPythonCode(flow?.name, cloneTweak);
|
||||
const widgetCode = getWidgetCode(flow?.id, flow?.name, autoLogin);
|
||||
|
|
@ -229,7 +229,7 @@ const ApiModal = forwardRef(
|
|||
</BaseModal.Content>
|
||||
</BaseModal>
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
export default ApiModal;
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ const EditNodeModal = forwardRef(
|
|||
setOpen: (open: boolean) => void;
|
||||
data: NodeDataType;
|
||||
},
|
||||
ref
|
||||
ref,
|
||||
) => {
|
||||
const nodes = useFlowStore((state) => state.nodes);
|
||||
|
||||
|
|
@ -134,7 +134,7 @@ const EditNodeModal = forwardRef(
|
|||
"edit-node-modal-box",
|
||||
nodeLength > limitScrollFieldsModal
|
||||
? "overflow-scroll overflow-x-hidden custom-scroll"
|
||||
: ""
|
||||
: "",
|
||||
)}
|
||||
>
|
||||
{nodeLength > 0 && (
|
||||
|
|
@ -157,8 +157,8 @@ const EditNodeModal = forwardRef(
|
|||
templateParam.charAt(0) !== "_" &&
|
||||
myData.node?.template[templateParam].show &&
|
||||
LANGFLOW_SUPPORTED_TYPES.has(
|
||||
myData.node!.template[templateParam].type
|
||||
)
|
||||
myData.node!.template[templateParam].type,
|
||||
),
|
||||
)
|
||||
.map((templateParam, index) => {
|
||||
let id = {
|
||||
|
|
@ -180,8 +180,8 @@ const EditNodeModal = forwardRef(
|
|||
myData.node?.template[templateParam]
|
||||
.proxy,
|
||||
}
|
||||
: id
|
||||
)
|
||||
: id,
|
||||
),
|
||||
) ?? false;
|
||||
return (
|
||||
<TableRow
|
||||
|
|
@ -204,11 +204,11 @@ const EditNodeModal = forwardRef(
|
|||
? myData.node?.template[templateParam]
|
||||
.proxy?.id
|
||||
: myData.node?.template[templateParam]
|
||||
.display_name
|
||||
? myData.node!.template[templateParam]
|
||||
.display_name
|
||||
: myData.node?.template[templateParam]
|
||||
.name
|
||||
.display_name
|
||||
? myData.node!.template[templateParam]
|
||||
.display_name
|
||||
: myData.node?.template[templateParam]
|
||||
.name
|
||||
}
|
||||
>
|
||||
<span>
|
||||
|
|
@ -263,7 +263,7 @@ const EditNodeModal = forwardRef(
|
|||
onChange={(value: string[]) => {
|
||||
handleOnNewValue(
|
||||
value,
|
||||
templateParam
|
||||
templateParam,
|
||||
);
|
||||
}}
|
||||
/>
|
||||
|
|
@ -287,11 +287,11 @@ const EditNodeModal = forwardRef(
|
|||
.value ?? ""
|
||||
}
|
||||
onChange={(
|
||||
value: string | string[]
|
||||
value: string | string[],
|
||||
) => {
|
||||
handleOnNewValue(
|
||||
value,
|
||||
templateParam
|
||||
templateParam,
|
||||
);
|
||||
}}
|
||||
/>
|
||||
|
|
@ -341,7 +341,7 @@ const EditNodeModal = forwardRef(
|
|||
].value = newValue;
|
||||
handleOnNewValue(
|
||||
newValue,
|
||||
templateParam
|
||||
templateParam,
|
||||
);
|
||||
}}
|
||||
id="editnode-div-dict-input"
|
||||
|
|
@ -358,7 +358,7 @@ const EditNodeModal = forwardRef(
|
|||
myData.node!.template[templateParam].value
|
||||
?.length > 1
|
||||
? "my-3"
|
||||
: ""
|
||||
: "",
|
||||
)}
|
||||
>
|
||||
<KeypairListComponent
|
||||
|
|
@ -374,7 +374,7 @@ const EditNodeModal = forwardRef(
|
|||
myData.node!.template[
|
||||
templateParam
|
||||
].value,
|
||||
type(templateParam)!
|
||||
type(templateParam)!,
|
||||
)
|
||||
}
|
||||
duplicateKey={errorDuplicateKey}
|
||||
|
|
@ -385,11 +385,11 @@ const EditNodeModal = forwardRef(
|
|||
templateParam
|
||||
].value = valueToNumbers;
|
||||
setErrorDuplicateKey(
|
||||
hasDuplicateKeys(valueToNumbers)
|
||||
hasDuplicateKeys(valueToNumbers),
|
||||
);
|
||||
handleOnNewValue(
|
||||
valueToNumbers,
|
||||
templateParam
|
||||
templateParam,
|
||||
);
|
||||
}}
|
||||
isList={
|
||||
|
|
@ -419,7 +419,7 @@ const EditNodeModal = forwardRef(
|
|||
setEnabled={(isEnabled) => {
|
||||
handleOnNewValue(
|
||||
isEnabled,
|
||||
templateParam
|
||||
templateParam,
|
||||
);
|
||||
}}
|
||||
size="small"
|
||||
|
|
@ -643,7 +643,7 @@ const EditNodeModal = forwardRef(
|
|||
<BaseModal.Footer submit={{ label: "Save Changes" }} />
|
||||
</BaseModal>
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
export default EditNodeModal;
|
||||
|
|
|
|||
|
|
@ -33,11 +33,13 @@ export default function FlowLogsModal({
|
|||
setRows(rows);
|
||||
});
|
||||
} else if (activeTab === "Messages") {
|
||||
getMessagesTable(currentFlowId, "union").then((data) => {
|
||||
const { columns, rows } = data;
|
||||
setColumns(columns.map((col) => ({ ...col, editable: true })));
|
||||
setRows(rows);
|
||||
});
|
||||
getMessagesTable("union", currentFlowId, ["index", "flow_id"]).then(
|
||||
(data) => {
|
||||
const { columns, rows } = data;
|
||||
setColumns(columns.map((col) => ({ ...col, editable: true })));
|
||||
setRows(rows);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
if (open && activeTab === "Messages" && !noticed.current) {
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ export default function NodeToolbarComponent({
|
|||
data.node.template[templateField].type === "Any" ||
|
||||
data.node.template[templateField].type === "int" ||
|
||||
data.node.template[templateField].type === "dict" ||
|
||||
data.node.template[templateField].type === "NestedDict")
|
||||
data.node.template[templateField].type === "NestedDict"),
|
||||
).length;
|
||||
const templates = useTypesStore((state) => state.templates);
|
||||
const hasStore = useStoreStore((state) => state.hasStore);
|
||||
|
|
@ -85,7 +85,7 @@ export default function NodeToolbarComponent({
|
|||
const [showconfirmShare, setShowconfirmShare] = useState(false);
|
||||
const [showOverrideModal, setShowOverrideModal] = useState(false);
|
||||
const [flowComponent, setFlowComponent] = useState<FlowType>(
|
||||
createFlowComponent(cloneDeep(data), version)
|
||||
createFlowComponent(cloneDeep(data), version),
|
||||
);
|
||||
|
||||
const openInNewTab = (url) => {
|
||||
|
|
@ -100,7 +100,7 @@ export default function NodeToolbarComponent({
|
|||
const updateNodeInternals = useUpdateNodeInternals();
|
||||
|
||||
const setLastCopiedSelection = useFlowStore(
|
||||
(state) => state.setLastCopiedSelection
|
||||
(state) => state.setLastCopiedSelection,
|
||||
);
|
||||
|
||||
const setSuccessData = useAlertStore((state) => state.setSuccessData);
|
||||
|
|
@ -153,7 +153,7 @@ export default function NodeToolbarComponent({
|
|||
nodes,
|
||||
edges,
|
||||
setNodes,
|
||||
setEdges
|
||||
setEdges,
|
||||
);
|
||||
break;
|
||||
case "override":
|
||||
|
|
@ -177,7 +177,7 @@ export default function NodeToolbarComponent({
|
|||
y: 10,
|
||||
paneX: nodes.find((node) => node.id === data.id)?.position.x,
|
||||
paneY: nodes.find((node) => node.id === data.id)?.position.y,
|
||||
}
|
||||
},
|
||||
);
|
||||
break;
|
||||
case "update":
|
||||
|
|
@ -215,13 +215,13 @@ export default function NodeToolbarComponent({
|
|||
};
|
||||
|
||||
const isSaved = flows.some((flow) =>
|
||||
Object.values(flow).includes(data.node?.display_name!)
|
||||
Object.values(flow).includes(data.node?.display_name!),
|
||||
);
|
||||
|
||||
const setNode = useFlowStore((state) => state.setNode);
|
||||
|
||||
const handleOnNewValue = (
|
||||
newValue: string | string[] | boolean | Object[]
|
||||
newValue: string | string[] | boolean | Object[],
|
||||
): void => {
|
||||
if (data.node!.template[name].value !== newValue) {
|
||||
takeSnapshot();
|
||||
|
|
@ -408,7 +408,7 @@ export default function NodeToolbarComponent({
|
|||
data-testid="save-button-modal"
|
||||
className={classNames(
|
||||
"relative -ml-px inline-flex items-center bg-background px-2 py-2 text-foreground shadow-md ring-1 ring-inset ring-ring transition-all duration-500 ease-in-out hover:bg-muted focus:z-10",
|
||||
hasCode ? " " : " rounded-l-md "
|
||||
hasCode ? " " : " rounded-l-md ",
|
||||
)}
|
||||
onClick={(event) => {
|
||||
event.preventDefault();
|
||||
|
|
@ -426,7 +426,7 @@ export default function NodeToolbarComponent({
|
|||
<button
|
||||
data-testid="duplicate-button-modal"
|
||||
className={classNames(
|
||||
"relative -ml-px inline-flex items-center bg-background px-2 py-2 text-foreground shadow-md ring-1 ring-inset ring-ring transition-all duration-500 ease-in-out hover:bg-muted focus:z-10"
|
||||
"relative -ml-px inline-flex items-center bg-background px-2 py-2 text-foreground shadow-md ring-1 ring-inset ring-ring transition-all duration-500 ease-in-out hover:bg-muted focus:z-10",
|
||||
)}
|
||||
onClick={(event) => {
|
||||
event.preventDefault();
|
||||
|
|
@ -440,7 +440,7 @@ export default function NodeToolbarComponent({
|
|||
<ShadTooltip content="Freeze" side="top">
|
||||
<button
|
||||
className={classNames(
|
||||
"relative -ml-px inline-flex items-center bg-background px-2 py-2 text-foreground shadow-md ring-1 ring-inset ring-ring transition-all duration-500 ease-in-out hover:bg-muted focus:z-10"
|
||||
"relative -ml-px inline-flex items-center bg-background px-2 py-2 text-foreground shadow-md ring-1 ring-inset ring-ring transition-all duration-500 ease-in-out hover:bg-muted focus:z-10",
|
||||
)}
|
||||
onClick={(event) => {
|
||||
event.preventDefault();
|
||||
|
|
@ -461,7 +461,7 @@ export default function NodeToolbarComponent({
|
|||
className={cn(
|
||||
"h-4 w-4 transition-all",
|
||||
// TODO UPDATE THIS COLOR TO BE A VARIABLE
|
||||
frozen ? "animate-wiggle text-ice" : ""
|
||||
frozen ? "animate-wiggle text-ice" : "",
|
||||
)}
|
||||
/>
|
||||
</button>
|
||||
|
|
@ -474,7 +474,7 @@ export default function NodeToolbarComponent({
|
|||
<div
|
||||
data-testid="more-options-modal"
|
||||
className={classNames(
|
||||
"relative -ml-px inline-flex h-8 w-[31px] items-center rounded-r-md bg-background text-foreground shadow-md ring-1 ring-inset ring-ring transition-all duration-500 ease-in-out hover:bg-muted focus:z-10"
|
||||
"relative -ml-px inline-flex h-8 w-[31px] items-center rounded-r-md bg-background text-foreground shadow-md ring-1 ring-inset ring-ring transition-all duration-500 ease-in-out hover:bg-muted focus:z-10",
|
||||
)}
|
||||
>
|
||||
<IconComponent
|
||||
|
|
|
|||
|
|
@ -46,6 +46,13 @@ export default function SettingsPage(): JSX.Element {
|
|||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: "Messages",
|
||||
href: "/settings/messages",
|
||||
icon: (
|
||||
<ForwardedIconComponent name="Keyboard" className="w-5 stroke-[1.5]" />
|
||||
),
|
||||
},
|
||||
];
|
||||
return (
|
||||
<PageLayout
|
||||
|
|
|
|||
|
|
@ -78,9 +78,6 @@ export default function GlobalVariablesPage() {
|
|||
// Column Definitions: Defines the columns to be displayed.
|
||||
const [colDefs, setColDefs] = useState<(ColDef<any> | ColGroupDef<any>)[]>([
|
||||
{
|
||||
headerCheckboxSelection: true,
|
||||
checkboxSelection: true,
|
||||
showDisabledCheckboxes: true,
|
||||
headerName: "Variable Name",
|
||||
field: "name",
|
||||
flex: 2,
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ const usePatchGradient = (
|
|||
setSuccessData,
|
||||
setErrorData,
|
||||
currentUserData,
|
||||
setUserData
|
||||
setUserData,
|
||||
) => {
|
||||
const handlePatchGradient = async (gradient) => {
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ const useSaveKey = (
|
|||
setErrorData,
|
||||
setHasApiKey,
|
||||
setValidApiKey,
|
||||
setLoadingApiKey
|
||||
setLoadingApiKey,
|
||||
) => {
|
||||
const { storeApiKey } = useContext(AuthContext);
|
||||
|
||||
|
|
@ -35,7 +35,7 @@ const useSaveKey = (
|
|||
setHasApiKey(false);
|
||||
setValidApiKey(false);
|
||||
setLoadingApiKey(false);
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -0,0 +1,49 @@
|
|||
import ForwardedIconComponent from "../../../../../../components/genericIconComponent";
|
||||
import { Button } from "../../../../../../components/ui/button";
|
||||
import { cn } from "../../../../../../utils/utils";
|
||||
|
||||
type HeaderMessagesComponentProps = {
|
||||
selectedRows: number[];
|
||||
handleRemoveMessages: () => void;
|
||||
};
|
||||
const HeaderMessagesComponent = ({
|
||||
selectedRows,
|
||||
handleRemoveMessages,
|
||||
}: HeaderMessagesComponentProps) => {
|
||||
return (
|
||||
<>
|
||||
<div className="flex w-full items-center justify-between gap-4 space-y-0.5">
|
||||
<div className="flex w-full flex-col">
|
||||
<h2 className="flex items-center text-lg font-semibold tracking-tight">
|
||||
Messages
|
||||
<ForwardedIconComponent
|
||||
name="MessagesSquare"
|
||||
className="ml-2 h-5 w-5 text-primary"
|
||||
/>
|
||||
</h2>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Inspect, edit and remove messages to explore and refine model
|
||||
behaviors.
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex flex-shrink-0 items-center gap-2">
|
||||
<Button
|
||||
data-testid="api-key-button-store"
|
||||
variant="primary"
|
||||
className="group px-2"
|
||||
disabled={selectedRows.length === 0}
|
||||
onClick={handleRemoveMessages}
|
||||
>
|
||||
<ForwardedIconComponent
|
||||
name="Trash2"
|
||||
className={cn(
|
||||
"h-5 w-5 text-destructive group-disabled:text-primary",
|
||||
)}
|
||||
/>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
export default HeaderMessagesComponent;
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
import { useEffect } from "react";
|
||||
import { getMessagesTable } from "../../../../../controllers/API";
|
||||
import { useMessagesStore } from "../../../../../stores/messagesStore";
|
||||
|
||||
const useMessagesTable = (setColumns) => {
|
||||
const setMessages = useMessagesStore((state) => state.setMessages);
|
||||
useEffect(() => {
|
||||
const fetchData = async () => {
|
||||
try {
|
||||
const data = await getMessagesTable("union", undefined, ["index"]);
|
||||
const { columns, rows } = data;
|
||||
setColumns(columns);
|
||||
setMessages(rows);
|
||||
} catch (error) {
|
||||
console.error("Error fetching messages:", error);
|
||||
}
|
||||
};
|
||||
fetchData();
|
||||
}, []);
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
export default useMessagesTable;
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
import { deleteMessagesFn } from "../../../../../controllers/API";
|
||||
import { useMessagesStore } from "../../../../../stores/messagesStore";
|
||||
|
||||
const useRemoveMessages = (
|
||||
setSelectedRows,
|
||||
setSuccessData,
|
||||
setErrorData,
|
||||
selectedRows,
|
||||
) => {
|
||||
const deleteMessages = useMessagesStore((state) => state.removeMessages);
|
||||
|
||||
const handleRemoveMessages = async () => {
|
||||
try {
|
||||
await deleteMessagesFn(selectedRows);
|
||||
deleteMessages(selectedRows);
|
||||
setSelectedRows([]);
|
||||
setSuccessData({
|
||||
title: "Messages deleted successfully.",
|
||||
});
|
||||
} catch (error) {
|
||||
setErrorData({
|
||||
title: "Error deleting messages.",
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
return { handleRemoveMessages };
|
||||
};
|
||||
|
||||
export default useRemoveMessages;
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
import { useMessagesStore } from "../../../../../stores/messagesStore";
|
||||
import { Message } from "../../../../../types/messages";
|
||||
import { updateMessageApi } from "../../../../../controllers/API";
|
||||
|
||||
const useUpdateMessage = (setSuccessData, setErrorData) => {
|
||||
const updateMessage = useMessagesStore((state) => state.updateMessage);
|
||||
|
||||
const handleUpdate = async (data: Message) => {
|
||||
try {
|
||||
await updateMessageApi(data);
|
||||
|
||||
updateMessage(data);
|
||||
|
||||
// Set success message
|
||||
setSuccessData({
|
||||
title: "Messages updated successfully.",
|
||||
});
|
||||
} catch (error) {
|
||||
// Set error message
|
||||
setErrorData({
|
||||
title: "Error updating messages.",
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
return { handleUpdate };
|
||||
};
|
||||
|
||||
export default useUpdateMessage;
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
import {
|
||||
CellEditRequestEvent,
|
||||
ColDef,
|
||||
ColGroupDef,
|
||||
SelectionChangedEvent,
|
||||
} from "ag-grid-community";
|
||||
import { useState } from "react";
|
||||
import TableComponent from "../../../../components/tableComponent";
|
||||
import { Card, CardContent } from "../../../../components/ui/card";
|
||||
import useAlertStore from "../../../../stores/alertStore";
|
||||
import { useMessagesStore } from "../../../../stores/messagesStore";
|
||||
import HeaderMessagesComponent from "./components/headerMessages";
|
||||
import useMessagesTable from "./hooks/use-messages-table";
|
||||
import useRemoveMessages from "./hooks/use-remove-messages";
|
||||
import useUpdateMessage from "./hooks/use-updateMessage";
|
||||
|
||||
export default function MessagesPage() {
|
||||
const [columns, setColumns] = useState<Array<ColDef | ColGroupDef>>([]);
|
||||
const messages = useMessagesStore((state) => state.messages);
|
||||
|
||||
const setErrorData = useAlertStore((state) => state.setErrorData);
|
||||
const setSuccessData = useAlertStore((state) => state.setSuccessData);
|
||||
|
||||
const [selectedRows, setSelectedRows] = useState<number[]>([]);
|
||||
|
||||
const { handleRemoveMessages } = useRemoveMessages(
|
||||
setSelectedRows,
|
||||
setSuccessData,
|
||||
setErrorData,
|
||||
selectedRows,
|
||||
);
|
||||
|
||||
const { handleUpdate } = useUpdateMessage(setSuccessData, setErrorData);
|
||||
|
||||
useMessagesTable(setColumns);
|
||||
|
||||
function handleUpdateMessage(event: CellEditRequestEvent<any, string>) {
|
||||
const newValue = event.newValue;
|
||||
const field = event.column.getColId();
|
||||
const row = event.data;
|
||||
const data = {
|
||||
...row,
|
||||
[field]: newValue,
|
||||
};
|
||||
handleUpdate(data);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="flex h-full w-full flex-col justify-between gap-6">
|
||||
<HeaderMessagesComponent
|
||||
selectedRows={selectedRows}
|
||||
handleRemoveMessages={handleRemoveMessages}
|
||||
/>
|
||||
|
||||
<div className="flex h-full w-full flex-col justify-between pb-8">
|
||||
<Card x-chunk="dashboard-04-chunk-2" className="h-full pt-4">
|
||||
<CardContent className="h-full">
|
||||
<TableComponent
|
||||
readOnlyEdit
|
||||
onCellEditRequest={(event) => {
|
||||
handleUpdateMessage(event);
|
||||
}}
|
||||
editable={["Sender Name", "Message"]}
|
||||
overlayNoRowsTemplate="No data available"
|
||||
onSelectionChanged={(event: SelectionChangedEvent) => {
|
||||
setSelectedRows(
|
||||
event.api.getSelectedRows().map((row) => row.index),
|
||||
);
|
||||
}}
|
||||
rowSelection="multiple"
|
||||
suppressRowClickSelection={true}
|
||||
pagination={true}
|
||||
columnDefs={columns}
|
||||
rowData={messages}
|
||||
/>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
@ -6,6 +6,7 @@ import { ProtectedLoginRoute } from "./components/authLoginGuard";
|
|||
import { CatchAllRoute } from "./components/catchAllRoutes";
|
||||
import LoadingComponent from "./components/loadingComponent";
|
||||
import { StoreGuard } from "./components/storeGuard";
|
||||
import MessagesPage from "./pages/SettingsPage/pages/messagesPage";
|
||||
|
||||
const AdminPage = lazy(() => import("./pages/AdminPage"));
|
||||
const LoginAdminPage = lazy(() => import("./pages/AdminPage/LoginPage"));
|
||||
|
|
@ -78,6 +79,7 @@ const Router = () => {
|
|||
<Route path="global-variables" element={<GlobalVariablesPage />} />
|
||||
<Route path="general/:scrollId?" element={<GeneralPage />} />
|
||||
<Route path="shortcuts" element={<ShortcutsPage />} />
|
||||
<Route path="messages" element={<MessagesPage />} />
|
||||
</Route>
|
||||
<Route
|
||||
path="/store"
|
||||
|
|
|
|||
43
src/frontend/src/stores/messagesStore.ts
Normal file
43
src/frontend/src/stores/messagesStore.ts
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
import { create } from "zustand";
|
||||
import { MessagesStoreType } from "../types/zustand/messages";
|
||||
|
||||
export const useMessagesStore = create<MessagesStoreType>((set, get) => ({
|
||||
messages: [],
|
||||
setMessages: (messages) => {
|
||||
set(() => ({ messages: messages }));
|
||||
},
|
||||
addMessage: (message) => {
|
||||
set(() => ({ messages: [...get().messages, message] }));
|
||||
},
|
||||
removeMessage: (message) => {
|
||||
set(() => ({
|
||||
messages: get().messages.filter((msg) => msg.id !== message.id),
|
||||
}));
|
||||
},
|
||||
updateMessage: (message) => {
|
||||
set(() => ({
|
||||
messages: get().messages.map((msg) =>
|
||||
msg.index === message.index ? message : msg,
|
||||
),
|
||||
}));
|
||||
},
|
||||
clearMessages: () => {
|
||||
set(() => ({ messages: [] }));
|
||||
},
|
||||
removeMessages: (ids) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
try {
|
||||
set((state) => {
|
||||
const updatedMessages = state.messages.filter(
|
||||
(msg) => !ids.includes(msg.index),
|
||||
);
|
||||
get().setMessages(updatedMessages);
|
||||
resolve(updatedMessages);
|
||||
return { messages: updatedMessages };
|
||||
});
|
||||
} catch (error) {
|
||||
reject(error);
|
||||
}
|
||||
});
|
||||
},
|
||||
}));
|
||||
|
|
@ -15,6 +15,10 @@ pre {
|
|||
font-family: inherit;
|
||||
}
|
||||
|
||||
.ag-paging-page-size {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.react-flow__pane {
|
||||
cursor: default;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -756,3 +756,17 @@ export type toolbarSelectItemProps = {
|
|||
dataTestId: string;
|
||||
ping?: boolean;
|
||||
};
|
||||
|
||||
export type clearChatPropsType = {
|
||||
lockChat: boolean;
|
||||
setLockChat: (lock: boolean) => void;
|
||||
setChatHistory: (chatHistory: ChatMessageType) => void;
|
||||
method: string;
|
||||
};
|
||||
|
||||
export type handleSelectPropsType = {
|
||||
event: string;
|
||||
lockChat: boolean;
|
||||
setLockChat: (lock: boolean) => void;
|
||||
setChatHistory: (chatHistory: ChatMessageType) => void;
|
||||
};
|
||||
|
|
|
|||
13
src/frontend/src/types/messages/index.ts
Normal file
13
src/frontend/src/types/messages/index.ts
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
type Message = {
|
||||
artifacts: Record<string, any>;
|
||||
flow_id: string;
|
||||
index: number;
|
||||
message: string;
|
||||
sender: string;
|
||||
sender_name: string;
|
||||
session_id: string;
|
||||
timestamp: string;
|
||||
id: string;
|
||||
};
|
||||
|
||||
export type { Message };
|
||||
|
|
@ -48,8 +48,16 @@ export type FlowStoreType = {
|
|||
onFlowPage: boolean;
|
||||
setOnFlowPage: (onFlowPage: boolean) => void;
|
||||
flowPool: FlowPoolType;
|
||||
inputs: Array<{ type: string; id: string; displayName: string }>;
|
||||
outputs: Array<{ type: string; id: string; displayName: string }>;
|
||||
inputs: Array<{
|
||||
type: string;
|
||||
id: string;
|
||||
displayName: string;
|
||||
}>;
|
||||
outputs: Array<{
|
||||
type: string;
|
||||
id: string;
|
||||
displayName: string;
|
||||
}>;
|
||||
hasIO: boolean;
|
||||
setFlowPool: (flowPool: FlowPoolType) => void;
|
||||
addDataToFlowPool: (data: FlowPoolObjectType, nodeId: string) => void;
|
||||
|
|
|
|||
11
src/frontend/src/types/zustand/messages/index.ts
Normal file
11
src/frontend/src/types/zustand/messages/index.ts
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
import { Message } from "../../messages";
|
||||
|
||||
export type MessagesStoreType = {
|
||||
messages: Message[];
|
||||
setMessages: (messages: Message[]) => void;
|
||||
addMessage: (message: Message) => void;
|
||||
removeMessage: (message: Message) => void;
|
||||
updateMessage: (message: Message) => void;
|
||||
clearMessages: () => void;
|
||||
removeMessages: (ids: number[]) => void;
|
||||
};
|
||||
|
|
@ -99,18 +99,18 @@ export function unselectAllNodes({ updateNodes, data }: unselectAllNodesType) {
|
|||
export function isValidConnection(
|
||||
{ source, target, sourceHandle, targetHandle }: Connection,
|
||||
nodes: Node[],
|
||||
edges: Edge[]
|
||||
edges: Edge[],
|
||||
) {
|
||||
const targetHandleObject: targetHandleType = scapeJSONParse(targetHandle!);
|
||||
const sourceHandleObject: sourceHandleType = scapeJSONParse(sourceHandle!);
|
||||
if (
|
||||
targetHandleObject.inputTypes?.some(
|
||||
(n) => n === sourceHandleObject.dataType
|
||||
(n) => n === sourceHandleObject.dataType,
|
||||
) ||
|
||||
sourceHandleObject.baseClasses.some(
|
||||
(t) =>
|
||||
targetHandleObject.inputTypes?.some((n) => n === t) ||
|
||||
t === targetHandleObject.type
|
||||
t === targetHandleObject.type,
|
||||
)
|
||||
) {
|
||||
let targetNode = nodes.find((node) => node.id === target!)?.data?.node;
|
||||
|
|
@ -143,7 +143,7 @@ export function removeApiKeys(flow: FlowType): FlowType {
|
|||
|
||||
export function updateTemplate(
|
||||
reference: APITemplateType,
|
||||
objectToUpdate: APITemplateType
|
||||
objectToUpdate: APITemplateType,
|
||||
): APITemplateType {
|
||||
let clonedObject: APITemplateType = cloneDeep(reference);
|
||||
|
||||
|
|
@ -203,7 +203,7 @@ export const processDataFromFlow = (flow: FlowType, refreshIds = true) => {
|
|||
|
||||
export function updateIds(
|
||||
{ edges, nodes }: { edges: Edge[]; nodes: Node[] },
|
||||
selection?: { edges: Edge[]; nodes: Node[] }
|
||||
selection?: { edges: Edge[]; nodes: Node[] },
|
||||
) {
|
||||
let idsMap = {};
|
||||
const selectionIds = selection?.nodes.map((n) => n.id);
|
||||
|
|
@ -231,7 +231,7 @@ export function updateIds(
|
|||
edge.source = idsMap[edge.source];
|
||||
edge.target = idsMap[edge.target];
|
||||
const sourceHandleObject: sourceHandleType = scapeJSONParse(
|
||||
edge.sourceHandle!
|
||||
edge.sourceHandle!,
|
||||
);
|
||||
edge.sourceHandle = scapedJSONStringfy({
|
||||
...sourceHandleObject,
|
||||
|
|
@ -241,7 +241,7 @@ export function updateIds(
|
|||
edge.data.sourceHandle.id = edge.source;
|
||||
}
|
||||
const targetHandleObject: targetHandleType = scapeJSONParse(
|
||||
edge.targetHandle!
|
||||
edge.targetHandle!,
|
||||
);
|
||||
edge.targetHandle = scapedJSONStringfy({
|
||||
...targetHandleObject,
|
||||
|
|
@ -287,11 +287,11 @@ export function validateNode(node: NodeType, edges: Edge[]): Array<string> {
|
|||
(scapeJSONParse(edge.targetHandle!) as targetHandleType).fieldName ===
|
||||
t &&
|
||||
(scapeJSONParse(edge.targetHandle!) as targetHandleType).id ===
|
||||
node.id
|
||||
node.id,
|
||||
)
|
||||
) {
|
||||
errors.push(
|
||||
`${displayName || type} is missing ${getFieldTitle(template, t)}.`
|
||||
`${displayName || type} is missing ${getFieldTitle(template, t)}.`,
|
||||
);
|
||||
} else if (
|
||||
template[t].type === "dict" &&
|
||||
|
|
@ -305,15 +305,15 @@ export function validateNode(node: NodeType, edges: Edge[]): Array<string> {
|
|||
errors.push(
|
||||
`${displayName || type} (${getFieldTitle(
|
||||
template,
|
||||
t
|
||||
)}) contains duplicate keys with the same values.`
|
||||
t,
|
||||
)}) contains duplicate keys with the same values.`,
|
||||
);
|
||||
if (hasEmptyKey(template[t].value))
|
||||
errors.push(
|
||||
`${displayName || type} (${getFieldTitle(
|
||||
template,
|
||||
t
|
||||
)}) field must not be empty.`
|
||||
t,
|
||||
)}) field must not be empty.`,
|
||||
);
|
||||
}
|
||||
return errors;
|
||||
|
|
@ -322,7 +322,7 @@ export function validateNode(node: NodeType, edges: Edge[]): Array<string> {
|
|||
|
||||
export function validateNodes(
|
||||
nodes: Node[],
|
||||
edges: Edge[]
|
||||
edges: Edge[],
|
||||
): // this returns an array of tuples with the node id and the errors
|
||||
Array<{ id: string; errors: Array<string> }> {
|
||||
if (nodes.length === 0) {
|
||||
|
|
@ -343,7 +343,7 @@ export function updateEdges(edges: Edge[]) {
|
|||
if (edges)
|
||||
edges.forEach((edge) => {
|
||||
const targetHandleObject: targetHandleType = scapeJSONParse(
|
||||
edge.targetHandle!
|
||||
edge.targetHandle!,
|
||||
);
|
||||
edge.className = "stroke-gray-900 stroke-connection";
|
||||
});
|
||||
|
|
@ -410,7 +410,7 @@ export function handleKeyDown(
|
|||
| React.KeyboardEvent<HTMLInputElement>
|
||||
| React.KeyboardEvent<HTMLTextAreaElement>,
|
||||
inputValue: string | string[] | null,
|
||||
block: string
|
||||
block: string,
|
||||
) {
|
||||
//condition to fix bug control+backspace on Windows/Linux
|
||||
if (
|
||||
|
|
@ -435,7 +435,7 @@ export function handleKeyDown(
|
|||
}
|
||||
|
||||
export function handleOnlyIntegerInput(
|
||||
event: React.KeyboardEvent<HTMLInputElement>
|
||||
event: React.KeyboardEvent<HTMLInputElement>,
|
||||
) {
|
||||
if (
|
||||
event.key === "." ||
|
||||
|
|
@ -451,7 +451,7 @@ export function handleOnlyIntegerInput(
|
|||
|
||||
export function getConnectedNodes(
|
||||
edge: Edge,
|
||||
nodes: Array<NodeType>
|
||||
nodes: Array<NodeType>,
|
||||
): Array<NodeType> {
|
||||
const sourceId = edge.source;
|
||||
const targetId = edge.target;
|
||||
|
|
@ -552,7 +552,7 @@ export function checkOldEdgesHandles(edges: Edge[]): boolean {
|
|||
!edge.sourceHandle ||
|
||||
!edge.targetHandle ||
|
||||
!edge.sourceHandle.includes("{") ||
|
||||
!edge.targetHandle.includes("{")
|
||||
!edge.targetHandle.includes("{"),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -575,7 +575,7 @@ export function customStringify(obj: any): string {
|
|||
|
||||
const keys = Object.keys(obj).sort();
|
||||
const keyValuePairs = keys.map(
|
||||
(key) => `"${key}":${customStringify(obj[key])}`
|
||||
(key) => `"${key}":${customStringify(obj[key])}`,
|
||||
);
|
||||
return `{${keyValuePairs.join(",")}}`;
|
||||
}
|
||||
|
|
@ -604,7 +604,7 @@ export function getHandleId(
|
|||
source: string,
|
||||
sourceHandle: string,
|
||||
target: string,
|
||||
targetHandle: string
|
||||
targetHandle: string,
|
||||
) {
|
||||
return (
|
||||
"reactflow__edge-" + source + sourceHandle + "-" + target + targetHandle
|
||||
|
|
@ -615,7 +615,7 @@ export function generateFlow(
|
|||
selection: OnSelectionChangeParams,
|
||||
nodes: Node[],
|
||||
edges: Edge[],
|
||||
name: string
|
||||
name: string,
|
||||
): generateFlowType {
|
||||
const newFlowData = { nodes, edges, viewport: { zoom: 1, x: 0, y: 0 } };
|
||||
const uid = new ShortUniqueId({ length: 5 });
|
||||
|
|
@ -624,7 +624,7 @@ export function generateFlow(
|
|||
newFlowData.edges = selection.edges.filter(
|
||||
(edge) =>
|
||||
selection.nodes.some((node) => node.id === edge.target) &&
|
||||
selection.nodes.some((node) => node.id === edge.source)
|
||||
selection.nodes.some((node) => node.id === edge.source),
|
||||
);
|
||||
newFlowData.nodes = selection.nodes;
|
||||
|
||||
|
|
@ -645,7 +645,7 @@ export function generateFlow(
|
|||
(edge) =>
|
||||
(selection.nodes.some((node) => node.id === edge.target) ||
|
||||
selection.nodes.some((node) => node.id === edge.source)) &&
|
||||
newFlowData.edges.every((e) => e.id !== edge.id)
|
||||
newFlowData.edges.every((e) => e.id !== edge.id),
|
||||
),
|
||||
};
|
||||
}
|
||||
|
|
@ -656,13 +656,13 @@ export function reconnectEdges(groupNode: NodeType, excludedEdges: Edge[]) {
|
|||
const { nodes, edges } = groupNode.data.node!.flow!.data!;
|
||||
const lastNode = findLastNode(groupNode.data.node!.flow!.data!);
|
||||
newEdges = newEdges.filter(
|
||||
(e) => !(nodes.some((n) => n.id === e.source) && e.source !== lastNode?.id)
|
||||
(e) => !(nodes.some((n) => n.id === e.source) && e.source !== lastNode?.id),
|
||||
);
|
||||
newEdges.forEach((edge) => {
|
||||
if (lastNode && edge.source === lastNode.id) {
|
||||
edge.source = groupNode.id;
|
||||
let newSourceHandle: sourceHandleType = scapeJSONParse(
|
||||
edge.sourceHandle!
|
||||
edge.sourceHandle!,
|
||||
);
|
||||
newSourceHandle.id = groupNode.id;
|
||||
edge.sourceHandle = scapedJSONStringfy(newSourceHandle);
|
||||
|
|
@ -689,7 +689,7 @@ export function reconnectEdges(groupNode: NodeType, excludedEdges: Edge[]) {
|
|||
export function filterFlow(
|
||||
selection: OnSelectionChangeParams,
|
||||
setNodes: (update: Node[] | ((oldState: Node[]) => Node[])) => void,
|
||||
setEdges: (update: Edge[] | ((oldState: Edge[]) => Edge[])) => void
|
||||
setEdges: (update: Edge[] | ((oldState: Edge[]) => Edge[])) => void,
|
||||
) {
|
||||
setNodes((nodes) => nodes.filter((node) => !selection.nodes.includes(node)));
|
||||
setEdges((edges) => edges.filter((edge) => !selection.edges.includes(edge)));
|
||||
|
|
@ -727,7 +727,7 @@ export function updateFlowPosition(NewPosition: XYPosition, flow: FlowType) {
|
|||
export function concatFlows(
|
||||
flow: FlowType,
|
||||
setNodes: (update: Node[] | ((oldState: Node[]) => Node[])) => void,
|
||||
setEdges: (update: Edge[] | ((oldState: Edge[]) => Edge[])) => void
|
||||
setEdges: (update: Edge[] | ((oldState: Edge[]) => Edge[])) => void,
|
||||
) {
|
||||
const { nodes, edges } = flow.data!;
|
||||
setNodes((old) => [...old, ...nodes]);
|
||||
|
|
@ -736,7 +736,7 @@ export function concatFlows(
|
|||
|
||||
export function validateSelection(
|
||||
selection: OnSelectionChangeParams,
|
||||
edges: Edge[]
|
||||
edges: Edge[],
|
||||
): Array<string> {
|
||||
const clonedSelection = cloneDeep(selection);
|
||||
const clonedEdges = cloneDeep(edges);
|
||||
|
|
@ -750,7 +750,7 @@ export function validateSelection(
|
|||
let nodesSet = new Set(clonedSelection.nodes.map((n) => n.id));
|
||||
// then filter the edges that are connected to the nodes in the set
|
||||
let connectedEdges = clonedSelection.edges.filter(
|
||||
(e) => nodesSet.has(e.source) && nodesSet.has(e.target)
|
||||
(e) => nodesSet.has(e.source) && nodesSet.has(e.target),
|
||||
);
|
||||
// add the edges to the selection
|
||||
clonedSelection.edges = connectedEdges;
|
||||
|
|
@ -764,17 +764,17 @@ export function validateSelection(
|
|||
clonedSelection.nodes.some(
|
||||
(node) =>
|
||||
isInputNode(node.data as NodeDataType) ||
|
||||
isOutputNode(node.data as NodeDataType)
|
||||
isOutputNode(node.data as NodeDataType),
|
||||
)
|
||||
) {
|
||||
errorsArray.push(
|
||||
"Please select only nodes that are not input or output nodes"
|
||||
"Please select only nodes that are not input or output nodes",
|
||||
);
|
||||
}
|
||||
//check if there are two or more nodes with free outputs
|
||||
if (
|
||||
clonedSelection.nodes.filter(
|
||||
(n) => !clonedSelection.edges.some((e) => e.source === n.id)
|
||||
(n) => !clonedSelection.edges.some((e) => e.source === n.id),
|
||||
).length > 1
|
||||
) {
|
||||
errorsArray.push("Please select only one node with free outputs");
|
||||
|
|
@ -785,7 +785,7 @@ export function validateSelection(
|
|||
clonedSelection.nodes.some(
|
||||
(node) =>
|
||||
!clonedSelection.edges.some((edge) => edge.target === node.id) &&
|
||||
!clonedSelection.edges.some((edge) => edge.source === node.id)
|
||||
!clonedSelection.edges.some((edge) => edge.source === node.id),
|
||||
)
|
||||
) {
|
||||
errorsArray.push("Please select only nodes that are connected");
|
||||
|
|
@ -842,8 +842,8 @@ export function mergeNodeTemplates({
|
|||
nodeTemplate[key].display_name
|
||||
? nodeTemplate[key].display_name
|
||||
: nodeTemplate[key].name
|
||||
? toTitleCase(nodeTemplate[key].name)
|
||||
: toTitleCase(key);
|
||||
? toTitleCase(nodeTemplate[key].name)
|
||||
: toTitleCase(key);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
@ -854,7 +854,7 @@ function isHandleConnected(
|
|||
edges: Edge[],
|
||||
key: string,
|
||||
field: TemplateVariableType,
|
||||
nodeId: string
|
||||
nodeId: string,
|
||||
) {
|
||||
/*
|
||||
this function receives a flow and a handleId and check if there is a connection with this handle
|
||||
|
|
@ -870,7 +870,7 @@ function isHandleConnected(
|
|||
id: nodeId,
|
||||
proxy: { id: field.proxy!.id, field: field.proxy!.field },
|
||||
inputTypes: field.input_types,
|
||||
} as targetHandleType)
|
||||
} as targetHandleType),
|
||||
)
|
||||
) {
|
||||
return true;
|
||||
|
|
@ -885,7 +885,7 @@ function isHandleConnected(
|
|||
fieldName: key,
|
||||
id: nodeId,
|
||||
inputTypes: field.input_types,
|
||||
} as targetHandleType)
|
||||
} as targetHandleType),
|
||||
)
|
||||
) {
|
||||
return true;
|
||||
|
|
@ -908,7 +908,7 @@ export function generateNodeTemplate(Flow: FlowType) {
|
|||
|
||||
export function generateNodeFromFlow(
|
||||
flow: FlowType,
|
||||
getNodeId: (type: string) => string
|
||||
getNodeId: (type: string) => string,
|
||||
): NodeType {
|
||||
const { nodes } = flow.data!;
|
||||
const outputNode = cloneDeep(findLastNode(flow.data!));
|
||||
|
|
@ -939,7 +939,7 @@ export function generateNodeFromFlow(
|
|||
export function connectedInputNodesOnHandle(
|
||||
nodeId: string,
|
||||
handleId: string,
|
||||
{ nodes, edges }: { nodes: NodeType[]; edges: Edge[] }
|
||||
{ nodes, edges }: { nodes: NodeType[]; edges: Edge[] },
|
||||
) {
|
||||
const connectedNodes: Array<{ name: string; id: string; isGroup: boolean }> =
|
||||
[];
|
||||
|
|
@ -976,7 +976,7 @@ export function connectedInputNodesOnHandle(
|
|||
|
||||
export function updateProxyIdsOnTemplate(
|
||||
template: APITemplateType,
|
||||
idsMap: { [key: string]: string }
|
||||
idsMap: { [key: string]: string },
|
||||
) {
|
||||
Object.keys(template).forEach((key) => {
|
||||
if (template[key].proxy && idsMap[template[key].proxy!.id]) {
|
||||
|
|
@ -987,7 +987,7 @@ export function updateProxyIdsOnTemplate(
|
|||
|
||||
export function updateEdgesIds(
|
||||
edges: Edge[],
|
||||
idsMap: { [key: string]: string }
|
||||
idsMap: { [key: string]: string },
|
||||
) {
|
||||
edges.forEach((edge) => {
|
||||
let targetHandle: targetHandleType = edge.data.targetHandle;
|
||||
|
|
@ -1019,7 +1019,7 @@ export function expandGroupNode(
|
|||
nodes: Node[],
|
||||
edges: Edge[],
|
||||
setNodes: (update: Node[] | ((oldState: Node[]) => Node[])) => void,
|
||||
setEdges: (update: Edge[] | ((oldState: Edge[]) => Edge[])) => void
|
||||
setEdges: (update: Edge[] | ((oldState: Edge[]) => Edge[])) => void,
|
||||
) {
|
||||
const idsMap = updateIds(flow!.data!);
|
||||
updateProxyIdsOnTemplate(template, idsMap);
|
||||
|
|
@ -1062,7 +1062,7 @@ export function expandGroupNode(
|
|||
const lastNode = cloneDeep(findLastNode(flow!.data!));
|
||||
newEdge.source = lastNode!.id;
|
||||
let newSourceHandle: sourceHandleType = scapeJSONParse(
|
||||
newEdge.sourceHandle!
|
||||
newEdge.sourceHandle!,
|
||||
);
|
||||
newSourceHandle.id = lastNode!.id;
|
||||
newEdge.data.sourceHandle = newSourceHandle;
|
||||
|
|
@ -1119,7 +1119,7 @@ export function expandGroupNode(
|
|||
|
||||
export function getGroupStatus(
|
||||
flow: FlowType,
|
||||
ssData: { [key: string]: { valid: boolean; params: string } }
|
||||
ssData: { [key: string]: { valid: boolean; params: string } },
|
||||
) {
|
||||
let status = { valid: true, params: SUCCESS_BUILD };
|
||||
const { nodes } = flow.data!;
|
||||
|
|
@ -1138,7 +1138,7 @@ export function getGroupStatus(
|
|||
|
||||
export function createFlowComponent(
|
||||
nodeData: NodeDataType,
|
||||
version: string
|
||||
version: string,
|
||||
): FlowType {
|
||||
const flowNode: FlowType = {
|
||||
data: {
|
||||
|
|
@ -1174,7 +1174,7 @@ export function downloadNode(NodeFLow: FlowType) {
|
|||
|
||||
export function updateComponentNameAndType(
|
||||
data: any,
|
||||
component: NodeDataType
|
||||
component: NodeDataType,
|
||||
) {}
|
||||
|
||||
export function removeFileNameFromComponents(flow: FlowType) {
|
||||
|
|
@ -1248,7 +1248,7 @@ export function extractFieldsFromComponenents(data: APIObjectType) {
|
|||
export function downloadFlow(
|
||||
flow: FlowType,
|
||||
flowName: string,
|
||||
flowDescription?: string
|
||||
flowDescription?: string,
|
||||
) {
|
||||
let clonedFlow = cloneDeep(flow);
|
||||
removeFileNameFromComponents(clonedFlow);
|
||||
|
|
@ -1258,7 +1258,7 @@ export function downloadFlow(
|
|||
...clonedFlow,
|
||||
name: flowName,
|
||||
description: flowDescription,
|
||||
})
|
||||
}),
|
||||
)}`;
|
||||
|
||||
// create a link element and set its properties
|
||||
|
|
@ -1273,7 +1273,7 @@ export function downloadFlow(
|
|||
export function downloadFlows() {
|
||||
downloadFlowsFromDatabase().then((flows) => {
|
||||
const jsonString = `data:text/json;chatset=utf-8,${encodeURIComponent(
|
||||
JSON.stringify(flows)
|
||||
JSON.stringify(flows),
|
||||
)}`;
|
||||
|
||||
// create a link element and set its properties
|
||||
|
|
@ -1297,7 +1297,7 @@ export function getRandomDescription(): string {
|
|||
export const createNewFlow = (
|
||||
flowData: ReactFlowJsonObject,
|
||||
flow: FlowType,
|
||||
folderId: string
|
||||
folderId: string,
|
||||
) => {
|
||||
return {
|
||||
description: flow?.description ?? getRandomDescription(),
|
||||
|
|
|
|||
|
|
@ -21,8 +21,16 @@ export default function cloneFLowWithParent(
|
|||
}
|
||||
|
||||
export function getInputsAndOutputs(nodes: Node[]) {
|
||||
let inputs: { type: string; id: string; displayName: string }[] = [];
|
||||
let outputs: { type: string; id: string; displayName: string }[] = [];
|
||||
let inputs: {
|
||||
type: string;
|
||||
id: string;
|
||||
displayName: string;
|
||||
}[] = [];
|
||||
let outputs: {
|
||||
type: string;
|
||||
id: string;
|
||||
displayName: string;
|
||||
}[] = [];
|
||||
nodes.forEach((node) => {
|
||||
const nodeData: NodeDataType = node.data as NodeDataType;
|
||||
if (isOutputNode(nodeData)) {
|
||||
|
|
|
|||
|
|
@ -143,6 +143,8 @@ import {
|
|||
X,
|
||||
XCircle,
|
||||
Zap,
|
||||
RotateCcw,
|
||||
Settings,
|
||||
} from "lucide-react";
|
||||
import { FaApple, FaDiscord, FaGithub } from "react-icons/fa";
|
||||
import { AWSIcon } from "../icons/AWS";
|
||||
|
|
@ -526,4 +528,6 @@ export const nodeIconsLucide: iconsType = {
|
|||
FolderPlusIcon,
|
||||
FolderIcon,
|
||||
Discord: FaDiscord,
|
||||
RotateCcw,
|
||||
Settings,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -352,8 +352,9 @@ export function isTimeStampString(str: string): boolean {
|
|||
export function extractColumnsFromRows(
|
||||
rows: object[],
|
||||
mode: "intersection" | "union",
|
||||
excludeColumns?: Array<string>,
|
||||
): (ColDef<any> | ColGroupDef<any>)[] {
|
||||
const columnsKeys: { [key: string]: ColDef<any> | ColGroupDef<any> } = {};
|
||||
let columnsKeys: { [key: string]: ColDef<any> | ColGroupDef<any> } = {};
|
||||
if (rows.length === 0) {
|
||||
return [];
|
||||
}
|
||||
|
|
@ -393,5 +394,11 @@ export function extractColumnsFromRows(
|
|||
union();
|
||||
}
|
||||
|
||||
if (excludeColumns) {
|
||||
for (const key of excludeColumns) {
|
||||
delete columnsKeys[key];
|
||||
}
|
||||
}
|
||||
|
||||
return Object.values(columnsKeys);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ test("chat_io_teste", async ({ page }) => {
|
|||
|
||||
const jsonContent = readFileSync(
|
||||
"src/frontend/tests/end-to-end/assets/ChatTest.json",
|
||||
"utf-8"
|
||||
"utf-8",
|
||||
);
|
||||
|
||||
await page.getByTestId("blank-flow").click();
|
||||
|
|
@ -47,7 +47,7 @@ test("chat_io_teste", async ({ page }) => {
|
|||
"drop",
|
||||
{
|
||||
dataTransfer,
|
||||
}
|
||||
},
|
||||
);
|
||||
await page.getByLabel("fit view").click();
|
||||
await page.getByText("Playground", { exact: true }).click();
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ test("user must interact with chat with Input/Output", async ({ page }) => {
|
|||
.getByTestId("textarea-input_value")
|
||||
.nth(1)
|
||||
.fill(
|
||||
"testtesttesttesttesttestte;.;.,;,.;,.;.,;,..,;;;;;;;;;;;;;;;;;;;;;,;.;,.;,.,;.,;.;.,~~çççççççççççççççççççççççççççççççççççççççisdajfdasiopjfaodisjhvoicxjiovjcxizopjviopasjioasfhjaiohf23432432432423423sttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttestççççççççççççççççççççççççççççççççç,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,!"
|
||||
"testtesttesttesttesttestte;.;.,;,.;,.;.,;,..,;;;;;;;;;;;;;;;;;;;;;,;.;,.;,.,;.,;.;.,~~çççççççççççççççççççççççççççççççççççççççisdajfdasiopjfaodisjhvoicxjiovjcxizopjviopasjioasfhjaiohf23432432432423423sttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttestççççççççççççççççççççççççççççççççç,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,!",
|
||||
);
|
||||
await page.getByTestId("icon-LucideSend").click();
|
||||
await page.getByText("Close", { exact: true }).click();
|
||||
|
|
@ -88,8 +88,8 @@ test("user must interact with chat with Input/Output", async ({ page }) => {
|
|||
await page
|
||||
.getByText(
|
||||
"testtesttesttesttesttestte;.;.,;,.;,.;.,;,..,;;;;;;;;;;;;;;;;;;;;;,;.;,.;,.,;.,;.;.,~~çççççççççççççççççççççççççççççççççççççççisdajfdasiopjfaodisjhvoicxjiovjcxizopjviopasjioasfhjaiohf23432432432423423sttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttestççççççççççççççççççççççççççççççççç,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,!",
|
||||
{ exact: true }
|
||||
{ exact: true },
|
||||
)
|
||||
.isVisible()
|
||||
.isVisible(),
|
||||
);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ test.describe("drag and drop test", () => {
|
|||
// Read your file into a buffer.
|
||||
const jsonContent = readFileSync(
|
||||
"src/frontend/tests/end-to-end/assets/collection.json",
|
||||
"utf-8"
|
||||
"utf-8",
|
||||
);
|
||||
|
||||
// Create the DataTransfer and File
|
||||
|
|
@ -47,7 +47,7 @@ test.describe("drag and drop test", () => {
|
|||
"drop",
|
||||
{
|
||||
dataTransfer,
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
const genericNoda = page.getByTestId("div-generic-node");
|
||||
|
|
|
|||
|
|
@ -78,32 +78,32 @@ test("dropDownComponent", async ({ page }) => {
|
|||
|
||||
await page.locator('//*[@id="showcredentials_profile_name"]').click();
|
||||
expect(
|
||||
await page.locator('//*[@id="showcredentials_profile_name"]').isChecked()
|
||||
await page.locator('//*[@id="showcredentials_profile_name"]').isChecked(),
|
||||
).toBeFalsy();
|
||||
|
||||
await page.locator('//*[@id="showcredentials_profile_name"]').click();
|
||||
expect(
|
||||
await page.locator('//*[@id="showcredentials_profile_name"]').isChecked()
|
||||
await page.locator('//*[@id="showcredentials_profile_name"]').isChecked(),
|
||||
).toBeTruthy();
|
||||
|
||||
await page.locator('//*[@id="showendpoint_url"]').click();
|
||||
expect(
|
||||
await page.locator('//*[@id="showendpoint_url"]').isChecked()
|
||||
await page.locator('//*[@id="showendpoint_url"]').isChecked(),
|
||||
).toBeFalsy();
|
||||
|
||||
await page.locator('//*[@id="showendpoint_url"]').click();
|
||||
expect(
|
||||
await page.locator('//*[@id="showendpoint_url"]').isChecked()
|
||||
await page.locator('//*[@id="showendpoint_url"]').isChecked(),
|
||||
).toBeTruthy();
|
||||
|
||||
await page.locator('//*[@id="showregion_name"]').click();
|
||||
expect(
|
||||
await page.locator('//*[@id="showregion_name"]').isChecked()
|
||||
await page.locator('//*[@id="showregion_name"]').isChecked(),
|
||||
).toBeFalsy();
|
||||
|
||||
await page.locator('//*[@id="showregion_name"]').click();
|
||||
expect(
|
||||
await page.locator('//*[@id="showregion_name"]').isChecked()
|
||||
await page.locator('//*[@id="showregion_name"]').isChecked(),
|
||||
).toBeTruthy();
|
||||
|
||||
// showmodel_id
|
||||
|
|
@ -113,7 +113,7 @@ test("dropDownComponent", async ({ page }) => {
|
|||
// showmodel_id
|
||||
await page.locator('//*[@id="showmodel_id"]').click();
|
||||
expect(
|
||||
await page.locator('//*[@id="showmodel_id"]').isChecked()
|
||||
await page.locator('//*[@id="showmodel_id"]').isChecked(),
|
||||
).toBeTruthy();
|
||||
|
||||
await page.locator('//*[@id="showcache"]').click();
|
||||
|
|
@ -124,32 +124,32 @@ test("dropDownComponent", async ({ page }) => {
|
|||
|
||||
await page.locator('//*[@id="showcredentials_profile_name"]').click();
|
||||
expect(
|
||||
await page.locator('//*[@id="showcredentials_profile_name"]').isChecked()
|
||||
await page.locator('//*[@id="showcredentials_profile_name"]').isChecked(),
|
||||
).toBeFalsy();
|
||||
|
||||
await page.locator('//*[@id="showcredentials_profile_name"]').click();
|
||||
expect(
|
||||
await page.locator('//*[@id="showcredentials_profile_name"]').isChecked()
|
||||
await page.locator('//*[@id="showcredentials_profile_name"]').isChecked(),
|
||||
).toBeTruthy();
|
||||
|
||||
await page.locator('//*[@id="showendpoint_url"]').click();
|
||||
expect(
|
||||
await page.locator('//*[@id="showendpoint_url"]').isChecked()
|
||||
await page.locator('//*[@id="showendpoint_url"]').isChecked(),
|
||||
).toBeFalsy();
|
||||
|
||||
await page.locator('//*[@id="showendpoint_url"]').click();
|
||||
expect(
|
||||
await page.locator('//*[@id="showendpoint_url"]').isChecked()
|
||||
await page.locator('//*[@id="showendpoint_url"]').isChecked(),
|
||||
).toBeTruthy();
|
||||
|
||||
await page.locator('//*[@id="showregion_name"]').click();
|
||||
expect(
|
||||
await page.locator('//*[@id="showregion_name"]').isChecked()
|
||||
await page.locator('//*[@id="showregion_name"]').isChecked(),
|
||||
).toBeFalsy();
|
||||
|
||||
await page.locator('//*[@id="showregion_name"]').click();
|
||||
expect(
|
||||
await page.locator('//*[@id="showregion_name"]').isChecked()
|
||||
await page.locator('//*[@id="showregion_name"]').isChecked(),
|
||||
).toBeTruthy();
|
||||
|
||||
// showmodel_id
|
||||
|
|
@ -159,7 +159,7 @@ test("dropDownComponent", async ({ page }) => {
|
|||
// showmodel_id
|
||||
await page.locator('//*[@id="showmodel_id"]').click();
|
||||
expect(
|
||||
await page.locator('//*[@id="showmodel_id"]').isChecked()
|
||||
await page.locator('//*[@id="showmodel_id"]').isChecked(),
|
||||
).toBeTruthy();
|
||||
|
||||
await page.getByTestId("dropdown-edit-model_id").click();
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ test("LLMChain - Tooltip", async ({ page }) => {
|
|||
|
||||
await page
|
||||
.locator(
|
||||
'//*[@id="react-flow-id"]/div[1]/div[1]/div/div/div[2]/div/div/div[2]/div[3]/div/button/div/div'
|
||||
'//*[@id="react-flow-id"]/div[1]/div[1]/div/div/div[2]/div/div/div[2]/div[3]/div/button/div/div',
|
||||
)
|
||||
.hover()
|
||||
.then(async () => {
|
||||
|
|
@ -60,17 +60,17 @@ test("LLMChain - Tooltip", async ({ page }) => {
|
|||
await page.getByTitle("zoom out").click();
|
||||
await page
|
||||
.locator(
|
||||
'//*[@id="react-flow-id"]/div[1]/div[1]/div/div/div[2]/div/div/div[2]/div[4]/div/button/div/div'
|
||||
'//*[@id="react-flow-id"]/div[1]/div[1]/div/div/div[2]/div/div/div[2]/div[4]/div/button/div/div',
|
||||
)
|
||||
.hover()
|
||||
.then(async () => {
|
||||
await expect(
|
||||
page.getByTestId("tooltip-Model Specs").first()
|
||||
page.getByTestId("tooltip-Model Specs").first(),
|
||||
).toBeVisible();
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
await expect(
|
||||
page.getByTestId("tooltip-Model Specs").first()
|
||||
page.getByTestId("tooltip-Model Specs").first(),
|
||||
).toBeVisible();
|
||||
|
||||
await page.getByTestId("icon-Search").click();
|
||||
|
|
@ -81,12 +81,12 @@ test("LLMChain - Tooltip", async ({ page }) => {
|
|||
|
||||
await page
|
||||
.locator(
|
||||
'//*[@id="react-flow-id"]/div[1]/div[1]/div/div/div[2]/div/div/div[2]/div[5]/div/button/div/div'
|
||||
'//*[@id="react-flow-id"]/div[1]/div[1]/div/div/div[2]/div/div/div[2]/div[5]/div/button/div/div',
|
||||
)
|
||||
.hover()
|
||||
.then(async () => {
|
||||
await expect(
|
||||
page.getByTestId("empty-tooltip-filter").first()
|
||||
page.getByTestId("empty-tooltip-filter").first(),
|
||||
).toBeVisible();
|
||||
});
|
||||
});
|
||||
|
|
@ -113,7 +113,7 @@ test("LLMChain - Filter", async ({ page }) => {
|
|||
await page.waitForTimeout(1000);
|
||||
|
||||
await page.getByTestId(
|
||||
"input-list-plus-btn-edit_metadata_indexing_include-2"
|
||||
"input-list-plus-btn-edit_metadata_indexing_include-2",
|
||||
);
|
||||
|
||||
await page.getByTestId("blank-flow").click();
|
||||
|
|
@ -136,7 +136,7 @@ test("LLMChain - Filter", async ({ page }) => {
|
|||
|
||||
await page
|
||||
.locator(
|
||||
'//*[@id="react-flow-id"]/div/div[1]/div[1]/div/div[2]/div/div/div[2]/div[4]/div/button/div/div'
|
||||
'//*[@id="react-flow-id"]/div/div[1]/div[1]/div/div[2]/div/div/div[2]/div[4]/div/button/div/div',
|
||||
)
|
||||
.click();
|
||||
|
||||
|
|
@ -149,14 +149,14 @@ test("LLMChain - Filter", async ({ page }) => {
|
|||
await expect(page.getByTestId("model_specsChatOpenAI")).toBeVisible();
|
||||
await expect(page.getByTestId("model_specsChatVertexAI")).toBeVisible();
|
||||
await expect(
|
||||
page.getByTestId("model_specsGoogle Generative AI")
|
||||
page.getByTestId("model_specsGoogle Generative AI"),
|
||||
).toBeVisible();
|
||||
await expect(
|
||||
page.getByTestId("model_specsHugging Face Inference API")
|
||||
page.getByTestId("model_specsHugging Face Inference API"),
|
||||
).toBeVisible();
|
||||
await expect(page.getByTestId("model_specsOllama")).toBeVisible();
|
||||
await expect(
|
||||
page.getByTestId("model_specsQianfanChatEndpoint")
|
||||
page.getByTestId("model_specsQianfanChatEndpoint"),
|
||||
).toBeVisible();
|
||||
await expect(page.getByTestId("model_specsQianfanLLMEndpoint")).toBeVisible();
|
||||
await expect(page.getByTestId("model_specsVertexAI")).toBeVisible();
|
||||
|
|
@ -168,7 +168,7 @@ test("LLMChain - Filter", async ({ page }) => {
|
|||
await expect(page.getByTestId("model_specsAmazon Bedrock")).not.toBeVisible();
|
||||
await expect(page.getByTestId("modelsAzure OpenAI")).not.toBeVisible();
|
||||
await expect(
|
||||
page.getByTestId("model_specsAzureChatOpenAI")
|
||||
page.getByTestId("model_specsAzureChatOpenAI"),
|
||||
).not.toBeVisible();
|
||||
await expect(page.getByTestId("model_specsChatAnthropic")).not.toBeVisible();
|
||||
await expect(page.getByTestId("model_specsChatLiteLLM")).not.toBeVisible();
|
||||
|
|
@ -178,13 +178,13 @@ test("LLMChain - Filter", async ({ page }) => {
|
|||
|
||||
await page
|
||||
.locator(
|
||||
'//*[@id="react-flow-id"]/div/div[1]/div[1]/div/div[2]/div/div/div[2]/div[7]/button/div/div'
|
||||
'//*[@id="react-flow-id"]/div/div[1]/div[1]/div/div[2]/div/div/div[2]/div[7]/button/div/div',
|
||||
)
|
||||
.click();
|
||||
|
||||
await page
|
||||
.locator(
|
||||
'//*[@id="react-flow-id"]/div/div[1]/div[1]/div/div[2]/div/div/div[2]/div[7]/button/div/div'
|
||||
'//*[@id="react-flow-id"]/div/div[1]/div[1]/div/div[2]/div/div/div[2]/div[7]/button/div/div',
|
||||
)
|
||||
.click();
|
||||
|
||||
|
|
|
|||
|
|
@ -71,27 +71,27 @@ test("FloatComponent", async ({ page }) => {
|
|||
|
||||
await page.getByTestId("showmirostat").click();
|
||||
expect(
|
||||
await page.locator('//*[@id="showmirostat"]').isChecked()
|
||||
await page.locator('//*[@id="showmirostat"]').isChecked(),
|
||||
).toBeTruthy();
|
||||
|
||||
await page.getByTestId("showmirostat_eta").click();
|
||||
expect(
|
||||
await page.locator('//*[@id="showmirostat_eta"]').isChecked()
|
||||
await page.locator('//*[@id="showmirostat_eta"]').isChecked(),
|
||||
).toBeTruthy();
|
||||
|
||||
await page.getByTestId("showmirostat_eta").click();
|
||||
expect(
|
||||
await page.locator('//*[@id="showmirostat_eta"]').isChecked()
|
||||
await page.locator('//*[@id="showmirostat_eta"]').isChecked(),
|
||||
).toBeFalsy();
|
||||
|
||||
await page.getByTestId("showmirostat_tau").click();
|
||||
expect(
|
||||
await page.locator('//*[@id="showmirostat_tau"]').isChecked()
|
||||
await page.locator('//*[@id="showmirostat_tau"]').isChecked(),
|
||||
).toBeTruthy();
|
||||
|
||||
await page.getByTestId("showmirostat_tau").click();
|
||||
expect(
|
||||
await page.locator('//*[@id="showmirostat_tau"]').isChecked()
|
||||
await page.locator('//*[@id="showmirostat_tau"]').isChecked(),
|
||||
).toBeFalsy();
|
||||
|
||||
await page.getByTestId("showmodel").click();
|
||||
|
|
@ -114,22 +114,22 @@ test("FloatComponent", async ({ page }) => {
|
|||
|
||||
await page.getByTestId("shownum_thread").click();
|
||||
expect(
|
||||
await page.locator('//*[@id="shownum_thread"]').isChecked()
|
||||
await page.locator('//*[@id="shownum_thread"]').isChecked(),
|
||||
).toBeTruthy();
|
||||
|
||||
await page.getByTestId("shownum_thread").click();
|
||||
expect(
|
||||
await page.locator('//*[@id="shownum_thread"]').isChecked()
|
||||
await page.locator('//*[@id="shownum_thread"]').isChecked(),
|
||||
).toBeFalsy();
|
||||
|
||||
await page.getByTestId("showrepeat_last_n").click();
|
||||
expect(
|
||||
await page.locator('//*[@id="showrepeat_last_n"]').isChecked()
|
||||
await page.locator('//*[@id="showrepeat_last_n"]').isChecked(),
|
||||
).toBeTruthy();
|
||||
|
||||
await page.getByTestId("showrepeat_last_n").click();
|
||||
expect(
|
||||
await page.locator('//*[@id="showrepeat_last_n"]').isChecked()
|
||||
await page.locator('//*[@id="showrepeat_last_n"]').isChecked(),
|
||||
).toBeFalsy();
|
||||
|
||||
await page.getByText("Save Changes", { exact: true }).click();
|
||||
|
|
@ -145,7 +145,7 @@ test("FloatComponent", async ({ page }) => {
|
|||
// showtemperature
|
||||
await page.locator('//*[@id="showtemperature"]').click();
|
||||
expect(
|
||||
await page.locator('//*[@id="showtemperature"]').isChecked()
|
||||
await page.locator('//*[@id="showtemperature"]').isChecked(),
|
||||
).toBeTruthy();
|
||||
|
||||
await page.getByText("Save Changes", { exact: true }).click();
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ test("flowSettings", async ({ page }) => {
|
|||
await page
|
||||
.getByPlaceholder("Flow name")
|
||||
.fill(
|
||||
"Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test"
|
||||
"Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test",
|
||||
);
|
||||
|
||||
await page.getByText("Character limit reached").isVisible();
|
||||
|
|
@ -41,7 +41,7 @@ test("flowSettings", async ({ page }) => {
|
|||
await page
|
||||
.getByPlaceholder("Flow description")
|
||||
.fill(
|
||||
"Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test"
|
||||
"Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test",
|
||||
);
|
||||
|
||||
await page.getByTestId("save-flow-settings").click();
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ test("add folder by drag and drop", async ({ page }) => {
|
|||
|
||||
const jsonContent = readFileSync(
|
||||
"src/frontend/tests/end-to-end/assets/collection.json",
|
||||
"utf-8"
|
||||
"utf-8",
|
||||
);
|
||||
|
||||
// Create the DataTransfer and File
|
||||
|
|
@ -78,7 +78,7 @@ test("add folder by drag and drop", async ({ page }) => {
|
|||
"drop",
|
||||
{
|
||||
dataTransfer,
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
await page.getByText("Getting Started").first().isVisible();
|
||||
|
|
|
|||
|
|
@ -60,69 +60,69 @@ test("InputComponent", async ({ page }) => {
|
|||
expect(
|
||||
await page
|
||||
.locator('//*[@id="showchroma_server_cors_allow_origins"]')
|
||||
.isChecked()
|
||||
.isChecked(),
|
||||
).toBeTruthy();
|
||||
|
||||
await page.locator('//*[@id="showchroma_server_grpc_port"]').click();
|
||||
expect(
|
||||
await page.locator('//*[@id="showchroma_server_grpc_port"]').isChecked()
|
||||
await page.locator('//*[@id="showchroma_server_grpc_port"]').isChecked(),
|
||||
).toBeTruthy();
|
||||
|
||||
await page.locator('//*[@id="showchroma_server_host"]').click();
|
||||
expect(
|
||||
await page.locator('//*[@id="showchroma_server_host"]').isChecked()
|
||||
await page.locator('//*[@id="showchroma_server_host"]').isChecked(),
|
||||
).toBeTruthy();
|
||||
|
||||
await page.locator('//*[@id="showchroma_server_http_port"]').click();
|
||||
expect(
|
||||
await page.locator('//*[@id="showchroma_server_http_port"]').isChecked()
|
||||
await page.locator('//*[@id="showchroma_server_http_port"]').isChecked(),
|
||||
).toBeTruthy();
|
||||
|
||||
await page.locator('//*[@id="showchroma_server_ssl_enabled"]').click();
|
||||
expect(
|
||||
await page.locator('//*[@id="showchroma_server_ssl_enabled"]').isChecked()
|
||||
await page.locator('//*[@id="showchroma_server_ssl_enabled"]').isChecked(),
|
||||
).toBeTruthy();
|
||||
|
||||
await page.locator('//*[@id="showcollection_name"]').click();
|
||||
expect(
|
||||
await page.locator('//*[@id="showcollection_name"]').isChecked()
|
||||
await page.locator('//*[@id="showcollection_name"]').isChecked(),
|
||||
).toBeFalsy();
|
||||
|
||||
await page.locator('//*[@id="showindex_directory"]').click();
|
||||
expect(
|
||||
await page.locator('//*[@id="showindex_directory"]').isChecked()
|
||||
await page.locator('//*[@id="showindex_directory"]').isChecked(),
|
||||
).toBeFalsy();
|
||||
|
||||
await page.locator('//*[@id="showchroma_server_cors_allow_origins"]').click();
|
||||
expect(
|
||||
await page
|
||||
.locator('//*[@id="showchroma_server_cors_allow_origins"]')
|
||||
.isChecked()
|
||||
.isChecked(),
|
||||
).toBeFalsy();
|
||||
|
||||
await page.locator('//*[@id="showchroma_server_grpc_port"]').click();
|
||||
expect(
|
||||
await page.locator('//*[@id="showchroma_server_grpc_port"]').isChecked()
|
||||
await page.locator('//*[@id="showchroma_server_grpc_port"]').isChecked(),
|
||||
).toBeFalsy();
|
||||
|
||||
await page.locator('//*[@id="showchroma_server_host"]').click();
|
||||
expect(
|
||||
await page.locator('//*[@id="showchroma_server_host"]').isChecked()
|
||||
await page.locator('//*[@id="showchroma_server_host"]').isChecked(),
|
||||
).toBeFalsy();
|
||||
|
||||
await page.locator('//*[@id="showchroma_server_http_port"]').click();
|
||||
expect(
|
||||
await page.locator('//*[@id="showchroma_server_http_port"]').isChecked()
|
||||
await page.locator('//*[@id="showchroma_server_http_port"]').isChecked(),
|
||||
).toBeFalsy();
|
||||
|
||||
await page.locator('//*[@id="showchroma_server_ssl_enabled"]').click();
|
||||
expect(
|
||||
await page.locator('//*[@id="showchroma_server_ssl_enabled"]').isChecked()
|
||||
await page.locator('//*[@id="showchroma_server_ssl_enabled"]').isChecked(),
|
||||
).toBeFalsy();
|
||||
|
||||
await page.locator('//*[@id="showindex_directory"]').click();
|
||||
expect(
|
||||
await page.locator('//*[@id="showindex_directory"]').isChecked()
|
||||
await page.locator('//*[@id="showindex_directory"]').isChecked(),
|
||||
).toBeTruthy();
|
||||
|
||||
let valueEditNode = await page
|
||||
|
|
@ -152,7 +152,7 @@ test("InputComponent", async ({ page }) => {
|
|||
|
||||
await page.locator('//*[@id="showcollection_name"]').click();
|
||||
expect(
|
||||
await page.locator('//*[@id="showcollection_name"]').isChecked()
|
||||
await page.locator('//*[@id="showcollection_name"]').isChecked(),
|
||||
).toBeTruthy();
|
||||
|
||||
await page.getByText("Save Changes", { exact: true }).click();
|
||||
|
|
|
|||
|
|
@ -41,19 +41,19 @@ test("InputListComponent", async ({ page }) => {
|
|||
await page.getByTestId("edit-button-modal").click();
|
||||
|
||||
expect(
|
||||
await page.getByTestId("showmetadata_indexing_exclude").isChecked()
|
||||
await page.getByTestId("showmetadata_indexing_exclude").isChecked(),
|
||||
).toBeFalsy();
|
||||
await page.getByTestId("showmetadata_indexing_exclude").click();
|
||||
expect(
|
||||
await page.getByTestId("showmetadata_indexing_exclude").isChecked()
|
||||
await page.getByTestId("showmetadata_indexing_exclude").isChecked(),
|
||||
).toBeTruthy();
|
||||
|
||||
expect(
|
||||
await page.getByTestId("showmetadata_indexing_include").isChecked()
|
||||
await page.getByTestId("showmetadata_indexing_include").isChecked(),
|
||||
).toBeFalsy();
|
||||
await page.getByTestId("showmetadata_indexing_include").click();
|
||||
expect(
|
||||
await page.getByTestId("showmetadata_indexing_include").isChecked()
|
||||
await page.getByTestId("showmetadata_indexing_include").isChecked(),
|
||||
).toBeTruthy();
|
||||
|
||||
await page
|
||||
|
|
@ -93,7 +93,7 @@ test("InputListComponent", async ({ page }) => {
|
|||
.click();
|
||||
|
||||
const plusButtonLocator = page.getByTestId(
|
||||
"input-list-plus-btn_metadata_indexing_include-1"
|
||||
"input-list-plus-btn_metadata_indexing_include-1",
|
||||
);
|
||||
const elementCount = await plusButtonLocator?.count();
|
||||
|
||||
|
|
@ -164,12 +164,12 @@ test("InputListComponent", async ({ page }) => {
|
|||
.click();
|
||||
|
||||
const plusButtonLocatorEdit0 = await page.getByTestId(
|
||||
"input-list-plus-btn-edit_metadata_indexing_include-0"
|
||||
"input-list-plus-btn-edit_metadata_indexing_include-0",
|
||||
);
|
||||
const elementCountEdit0 = await plusButtonLocatorEdit0?.count();
|
||||
|
||||
const plusButtonLocatorEdit2 = await page.getByTestId(
|
||||
"input-list-plus-btn-edit_metadata_indexing_include-2"
|
||||
"input-list-plus-btn-edit_metadata_indexing_include-2",
|
||||
);
|
||||
const elementCountEdit2 = await plusButtonLocatorEdit2?.count();
|
||||
|
||||
|
|
@ -178,13 +178,13 @@ test("InputListComponent", async ({ page }) => {
|
|||
}
|
||||
|
||||
const minusButtonLocatorEdit1 = await page.getByTestId(
|
||||
"input-list-minus-btn-edit_metadata_indexing_include-1"
|
||||
"input-list-minus-btn-edit_metadata_indexing_include-1",
|
||||
);
|
||||
|
||||
const elementCountMinusEdit1 = await minusButtonLocatorEdit1?.count();
|
||||
|
||||
const minusButtonLocatorEdit2 = await page.getByTestId(
|
||||
"input-list-minus-btn-edit_metadata_indexing_include-2"
|
||||
"input-list-minus-btn-edit_metadata_indexing_include-2",
|
||||
);
|
||||
|
||||
const elementCountMinusEdit2 = await minusButtonLocatorEdit2?.count();
|
||||
|
|
|
|||
|
|
@ -87,77 +87,77 @@ test("IntComponent", async ({ page }) => {
|
|||
|
||||
await page.locator('//*[@id="showmodel_kwargs"]').click();
|
||||
expect(
|
||||
await page.locator('//*[@id="showmodel_kwargs"]').isChecked()
|
||||
await page.locator('//*[@id="showmodel_kwargs"]').isChecked(),
|
||||
).toBeTruthy();
|
||||
|
||||
await page.locator('//*[@id="showmodel_name"]').click();
|
||||
expect(
|
||||
await page.locator('//*[@id="showmodel_name"]').isChecked()
|
||||
await page.locator('//*[@id="showmodel_name"]').isChecked(),
|
||||
).toBeFalsy();
|
||||
|
||||
await page.locator('//*[@id="showopenai_api_base"]').click();
|
||||
expect(
|
||||
await page.locator('//*[@id="showopenai_api_base"]').isChecked()
|
||||
await page.locator('//*[@id="showopenai_api_base"]').isChecked(),
|
||||
).toBeFalsy();
|
||||
|
||||
await page.locator('//*[@id="showopenai_api_key"]').click();
|
||||
expect(
|
||||
await page.locator('//*[@id="showopenai_api_key"]').isChecked()
|
||||
await page.locator('//*[@id="showopenai_api_key"]').isChecked(),
|
||||
).toBeFalsy();
|
||||
|
||||
await page.locator('//*[@id="showtemperature"]').click();
|
||||
expect(
|
||||
await page.locator('//*[@id="showtemperature"]').isChecked()
|
||||
await page.locator('//*[@id="showtemperature"]').isChecked(),
|
||||
).toBeFalsy();
|
||||
|
||||
await page.locator('//*[@id="showmodel_kwargs"]').click();
|
||||
expect(
|
||||
await page.locator('//*[@id="showmodel_kwargs"]').isChecked()
|
||||
await page.locator('//*[@id="showmodel_kwargs"]').isChecked(),
|
||||
).toBeFalsy();
|
||||
|
||||
await page.locator('//*[@id="showmodel_name"]').click();
|
||||
expect(
|
||||
await page.locator('//*[@id="showmodel_name"]').isChecked()
|
||||
await page.locator('//*[@id="showmodel_name"]').isChecked(),
|
||||
).toBeTruthy();
|
||||
|
||||
await page.locator('//*[@id="showopenai_api_base"]').click();
|
||||
expect(
|
||||
await page.locator('//*[@id="showopenai_api_base"]').isChecked()
|
||||
await page.locator('//*[@id="showopenai_api_base"]').isChecked(),
|
||||
).toBeTruthy();
|
||||
|
||||
await page.locator('//*[@id="showopenai_api_key"]').click();
|
||||
expect(
|
||||
await page.locator('//*[@id="showopenai_api_key"]').isChecked()
|
||||
await page.locator('//*[@id="showopenai_api_key"]').isChecked(),
|
||||
).toBeTruthy();
|
||||
|
||||
await page.locator('//*[@id="showtemperature"]').click();
|
||||
expect(
|
||||
await page.locator('//*[@id="showtemperature"]').isChecked()
|
||||
await page.locator('//*[@id="showtemperature"]').isChecked(),
|
||||
).toBeTruthy();
|
||||
|
||||
await page.locator('//*[@id="showmodel_kwargs"]').click();
|
||||
expect(
|
||||
await page.locator('//*[@id="showmodel_kwargs"]').isChecked()
|
||||
await page.locator('//*[@id="showmodel_kwargs"]').isChecked(),
|
||||
).toBeTruthy();
|
||||
|
||||
await page.locator('//*[@id="showmodel_name"]').click();
|
||||
expect(
|
||||
await page.locator('//*[@id="showmodel_name"]').isChecked()
|
||||
await page.locator('//*[@id="showmodel_name"]').isChecked(),
|
||||
).toBeFalsy();
|
||||
|
||||
await page.locator('//*[@id="showopenai_api_base"]').click();
|
||||
expect(
|
||||
await page.locator('//*[@id="showopenai_api_base"]').isChecked()
|
||||
await page.locator('//*[@id="showopenai_api_base"]').isChecked(),
|
||||
).toBeFalsy();
|
||||
|
||||
await page.locator('//*[@id="showopenai_api_key"]').click();
|
||||
expect(
|
||||
await page.locator('//*[@id="showopenai_api_key"]').isChecked()
|
||||
await page.locator('//*[@id="showopenai_api_key"]').isChecked(),
|
||||
).toBeFalsy();
|
||||
|
||||
await page.locator('//*[@id="showtemperature"]').click();
|
||||
expect(
|
||||
await page.locator('//*[@id="showtemperature"]').isChecked()
|
||||
await page.locator('//*[@id="showtemperature"]').isChecked(),
|
||||
).toBeFalsy();
|
||||
|
||||
await page.getByText("Save Changes", { exact: true }).click();
|
||||
|
|
@ -172,7 +172,7 @@ test("IntComponent", async ({ page }) => {
|
|||
|
||||
await page.locator('//*[@id="showtimeout"]').click();
|
||||
expect(
|
||||
await page.locator('//*[@id="showtimeout"]').isChecked()
|
||||
await page.locator('//*[@id="showtimeout"]').isChecked(),
|
||||
).toBeTruthy();
|
||||
|
||||
const valueEditNode = await page
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ test("KeypairListComponent", async ({ page }) => {
|
|||
expect(await page.locator('//*[@id="showcache"]').isChecked()).toBeFalsy();
|
||||
await page.locator('//*[@id="showcredentials_profile_name"]').click();
|
||||
expect(
|
||||
await page.locator('//*[@id="showcredentials_profile_name"]').isChecked()
|
||||
await page.locator('//*[@id="showcredentials_profile_name"]').isChecked(),
|
||||
).toBeFalsy();
|
||||
await page.getByText("Save Changes", { exact: true }).click();
|
||||
|
||||
|
|
@ -96,7 +96,7 @@ test("KeypairListComponent", async ({ page }) => {
|
|||
|
||||
await page.locator('//*[@id="showcredentials_profile_name"]').click();
|
||||
expect(
|
||||
await page.locator('//*[@id="showcredentials_profile_name"]').isChecked()
|
||||
await page.locator('//*[@id="showcredentials_profile_name"]').isChecked(),
|
||||
).toBeTruthy();
|
||||
await page.locator('//*[@id="showcache"]').click();
|
||||
expect(await page.locator('//*[@id="showcache"]').isChecked()).toBeTruthy();
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ test("LangflowShortcuts", async ({ page }) => {
|
|||
|
||||
await page
|
||||
.locator(
|
||||
'//*[@id="react-flow-id"]/div[1]/div[1]/div[1]/div/div[2]/div[2]/div/div[1]/div/div[1]/div/div/div[1]'
|
||||
'//*[@id="react-flow-id"]/div[1]/div[1]/div[1]/div/div[2]/div[2]/div/div[1]/div/div[1]/div/div/div[1]',
|
||||
)
|
||||
.click();
|
||||
await page.keyboard.press("Backspace");
|
||||
|
|
@ -84,7 +84,7 @@ test("LangflowShortcuts", async ({ page }) => {
|
|||
|
||||
await page
|
||||
.locator(
|
||||
'//*[@id="react-flow-id"]/div[1]/div[1]/div[1]/div/div[2]/div[2]/div/div[1]/div/div[1]/div/div/div[1]'
|
||||
'//*[@id="react-flow-id"]/div[1]/div[1]/div[1]/div/div[2]/div[2]/div/div[1]/div/div[1]/div/div/div[1]',
|
||||
)
|
||||
.click();
|
||||
await page.keyboard.press("Backspace");
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ test("NestedComponent", async ({ page }) => {
|
|||
await page.locator('//*[@id="showpool_threads"]').click();
|
||||
|
||||
expect(
|
||||
await page.locator('//*[@id="showpool_threads"]').isChecked()
|
||||
await page.locator('//*[@id="showpool_threads"]').isChecked(),
|
||||
).toBeTruthy();
|
||||
|
||||
//showtext_key
|
||||
|
|
@ -53,140 +53,140 @@ test("NestedComponent", async ({ page }) => {
|
|||
await page.locator('//*[@id="showindex_name"]').click();
|
||||
|
||||
expect(
|
||||
await page.locator('//*[@id="showindex_name"]').isChecked()
|
||||
await page.locator('//*[@id="showindex_name"]').isChecked(),
|
||||
).toBeFalsy();
|
||||
|
||||
// shownamespace
|
||||
await page.locator('//*[@id="shownamespace"]').click();
|
||||
|
||||
expect(
|
||||
await page.locator('//*[@id="shownamespace"]').isChecked()
|
||||
await page.locator('//*[@id="shownamespace"]').isChecked(),
|
||||
).toBeFalsy();
|
||||
|
||||
// showpinecone_api_key
|
||||
await page.locator('//*[@id="showpinecone_api_key"]').click();
|
||||
|
||||
expect(
|
||||
await page.locator('//*[@id="showpinecone_api_key"]').isChecked()
|
||||
await page.locator('//*[@id="showpinecone_api_key"]').isChecked(),
|
||||
).toBeFalsy();
|
||||
|
||||
// showindex_name
|
||||
await page.locator('//*[@id="showindex_name"]').click();
|
||||
|
||||
expect(
|
||||
await page.locator('//*[@id="showindex_name"]').isChecked()
|
||||
await page.locator('//*[@id="showindex_name"]').isChecked(),
|
||||
).toBeTruthy();
|
||||
|
||||
// shownamespace
|
||||
await page.locator('//*[@id="shownamespace"]').click();
|
||||
|
||||
expect(
|
||||
await page.locator('//*[@id="shownamespace"]').isChecked()
|
||||
await page.locator('//*[@id="shownamespace"]').isChecked(),
|
||||
).toBeTruthy();
|
||||
|
||||
// showpinecone_api_key
|
||||
await page.locator('//*[@id="showpinecone_api_key"]').click();
|
||||
|
||||
expect(
|
||||
await page.locator('//*[@id="showpinecone_api_key"]').isChecked()
|
||||
await page.locator('//*[@id="showpinecone_api_key"]').isChecked(),
|
||||
).toBeTruthy();
|
||||
|
||||
// showindex_name
|
||||
await page.locator('//*[@id="showindex_name"]').click();
|
||||
|
||||
expect(
|
||||
await page.locator('//*[@id="showindex_name"]').isChecked()
|
||||
await page.locator('//*[@id="showindex_name"]').isChecked(),
|
||||
).toBeFalsy();
|
||||
|
||||
// shownamespace
|
||||
await page.locator('//*[@id="shownamespace"]').click();
|
||||
|
||||
expect(
|
||||
await page.locator('//*[@id="shownamespace"]').isChecked()
|
||||
await page.locator('//*[@id="shownamespace"]').isChecked(),
|
||||
).toBeFalsy();
|
||||
|
||||
// showpinecone_api_key
|
||||
await page.locator('//*[@id="showpinecone_api_key"]').click();
|
||||
|
||||
expect(
|
||||
await page.locator('//*[@id="showpinecone_api_key"]').isChecked()
|
||||
await page.locator('//*[@id="showpinecone_api_key"]').isChecked(),
|
||||
).toBeFalsy();
|
||||
|
||||
// showindex_name
|
||||
await page.locator('//*[@id="showindex_name"]').click();
|
||||
|
||||
expect(
|
||||
await page.locator('//*[@id="showindex_name"]').isChecked()
|
||||
await page.locator('//*[@id="showindex_name"]').isChecked(),
|
||||
).toBeTruthy();
|
||||
|
||||
// shownamespace
|
||||
await page.locator('//*[@id="shownamespace"]').click();
|
||||
|
||||
expect(
|
||||
await page.locator('//*[@id="shownamespace"]').isChecked()
|
||||
await page.locator('//*[@id="shownamespace"]').isChecked(),
|
||||
).toBeTruthy();
|
||||
|
||||
// showpinecone_api_key
|
||||
await page.locator('//*[@id="showpinecone_api_key"]').click();
|
||||
|
||||
expect(
|
||||
await page.locator('//*[@id="showpinecone_api_key"]').isChecked()
|
||||
await page.locator('//*[@id="showpinecone_api_key"]').isChecked(),
|
||||
).toBeTruthy();
|
||||
|
||||
// showindex_name
|
||||
await page.locator('//*[@id="showindex_name"]').click();
|
||||
|
||||
expect(
|
||||
await page.locator('//*[@id="showindex_name"]').isChecked()
|
||||
await page.locator('//*[@id="showindex_name"]').isChecked(),
|
||||
).toBeFalsy();
|
||||
|
||||
// shownamespace
|
||||
await page.locator('//*[@id="shownamespace"]').click();
|
||||
|
||||
expect(
|
||||
await page.locator('//*[@id="shownamespace"]').isChecked()
|
||||
await page.locator('//*[@id="shownamespace"]').isChecked(),
|
||||
).toBeFalsy();
|
||||
|
||||
// showpinecone_api_key
|
||||
await page.locator('//*[@id="showpinecone_api_key"]').click();
|
||||
|
||||
expect(
|
||||
await page.locator('//*[@id="showpinecone_api_key"]').isChecked()
|
||||
await page.locator('//*[@id="showpinecone_api_key"]').isChecked(),
|
||||
).toBeFalsy();
|
||||
|
||||
// showindex_name
|
||||
await page.locator('//*[@id="showindex_name"]').click();
|
||||
|
||||
expect(
|
||||
await page.locator('//*[@id="showindex_name"]').isChecked()
|
||||
await page.locator('//*[@id="showindex_name"]').isChecked(),
|
||||
).toBeTruthy();
|
||||
|
||||
// shownamespace
|
||||
await page.locator('//*[@id="shownamespace"]').click();
|
||||
|
||||
expect(
|
||||
await page.locator('//*[@id="shownamespace"]').isChecked()
|
||||
await page.locator('//*[@id="shownamespace"]').isChecked(),
|
||||
).toBeTruthy();
|
||||
|
||||
// showpinecone_api_key
|
||||
await page.locator('//*[@id="showpinecone_api_key"]').click();
|
||||
|
||||
expect(
|
||||
await page.locator('//*[@id="showpinecone_api_key"]').isChecked()
|
||||
await page.locator('//*[@id="showpinecone_api_key"]').isChecked(),
|
||||
).toBeTruthy();
|
||||
|
||||
//showpool_threads
|
||||
await page.locator('//*[@id="showpool_threads"]').click();
|
||||
|
||||
expect(
|
||||
await page.locator('//*[@id="showpool_threads"]').isChecked()
|
||||
await page.locator('//*[@id="showpool_threads"]').isChecked(),
|
||||
).toBeFalsy();
|
||||
|
||||
//showtext_key
|
||||
await page.locator('//*[@id="showtext_key"]').click();
|
||||
|
||||
expect(
|
||||
await page.locator('//*[@id="showtext_key"]').isChecked()
|
||||
await page.locator('//*[@id="showtext_key"]').isChecked(),
|
||||
).toBeTruthy();
|
||||
|
||||
await page.getByText("Save Changes", { exact: true }).click();
|
||||
|
|
|
|||
|
|
@ -138,7 +138,7 @@ test("PromptTemplateComponent", async ({ page }) => {
|
|||
|
||||
await page.locator('//*[@id="showtemplate"]').click();
|
||||
expect(
|
||||
await page.locator('//*[@id="showtemplate"]').isChecked()
|
||||
await page.locator('//*[@id="showtemplate"]').isChecked(),
|
||||
).toBeTruthy();
|
||||
|
||||
await page.locator('//*[@id="showprompt"]').click();
|
||||
|
|
@ -158,7 +158,7 @@ test("PromptTemplateComponent", async ({ page }) => {
|
|||
|
||||
await page.locator('//*[@id="showtemplate"]').click();
|
||||
expect(
|
||||
await page.locator('//*[@id="showtemplate"]').isChecked()
|
||||
await page.locator('//*[@id="showtemplate"]').isChecked(),
|
||||
).toBeTruthy();
|
||||
|
||||
await page.locator('//*[@id="showprompt"]').click();
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ test.describe("save component tests", () => {
|
|||
// Read your file into a buffer.
|
||||
const jsonContent = readFileSync(
|
||||
"src/frontend/tests/end-to-end/assets/flow_group_test.json",
|
||||
"utf-8"
|
||||
"utf-8",
|
||||
);
|
||||
|
||||
// Create the DataTransfer and File
|
||||
|
|
@ -49,7 +49,7 @@ test.describe("save component tests", () => {
|
|||
"drop",
|
||||
{
|
||||
dataTransfer,
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
const genericNoda = page.getByTestId("div-generic-node");
|
||||
|
|
|
|||
|
|
@ -262,7 +262,7 @@ test("should share component with share button", async ({ page }) => {
|
|||
await page.getByText("Set workflow status to public").isVisible();
|
||||
await page
|
||||
.getByText(
|
||||
"Attention: API keys in specified fields are automatically removed upon sharing."
|
||||
"Attention: API keys in specified fields are automatically removed upon sharing.",
|
||||
)
|
||||
.isVisible();
|
||||
await page.getByText("Export").first().isVisible();
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ test("TextInputOutputComponent", async ({ page }) => {
|
|||
// Click and hold on the first element
|
||||
await page
|
||||
.locator(
|
||||
'//*[@id="react-flow-id"]/div/div[1]/div[1]/div/div[2]/div[1]/div/div[2]/div[6]/button/div/div'
|
||||
'//*[@id="react-flow-id"]/div/div[1]/div[1]/div/div[2]/div[1]/div/div[2]/div[6]/button/div/div',
|
||||
)
|
||||
.hover();
|
||||
await page.mouse.down();
|
||||
|
|
@ -68,7 +68,7 @@ test("TextInputOutputComponent", async ({ page }) => {
|
|||
// Move to the second element
|
||||
await page
|
||||
.locator(
|
||||
'//*[@id="react-flow-id"]/div/div[1]/div[1]/div/div[2]/div[2]/div/div[2]/div[9]/div/button/div/div'
|
||||
'//*[@id="react-flow-id"]/div/div[1]/div[1]/div/div[2]/div[2]/div/div[2]/div[9]/div/button/div/div',
|
||||
)
|
||||
.hover();
|
||||
|
||||
|
|
@ -92,7 +92,7 @@ test("TextInputOutputComponent", async ({ page }) => {
|
|||
// Click and hold on the first element
|
||||
await page
|
||||
.locator(
|
||||
'//*[@id="react-flow-id"]/div/div[1]/div[1]/div/div[2]/div[2]/div/div[2]/div[13]/button/div/div'
|
||||
'//*[@id="react-flow-id"]/div/div[1]/div[1]/div/div[2]/div[2]/div/div[2]/div[13]/button/div/div',
|
||||
)
|
||||
.hover();
|
||||
await page.mouse.down();
|
||||
|
|
@ -100,7 +100,7 @@ test("TextInputOutputComponent", async ({ page }) => {
|
|||
// Move to the second element
|
||||
await page
|
||||
.locator(
|
||||
'//*[@id="react-flow-id"]/div/div[1]/div[1]/div/div[2]/div[3]/div/div[2]/div[3]/div/button/div/div'
|
||||
'//*[@id="react-flow-id"]/div/div[1]/div[1]/div/div[2]/div[3]/div/div[2]/div[3]/div/button/div/div',
|
||||
)
|
||||
.hover();
|
||||
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ test("ToggleComponent", async ({ page }) => {
|
|||
|
||||
await page.locator('//*[@id="showload_hidden"]').click();
|
||||
expect(
|
||||
await page.locator('//*[@id="showload_hidden"]').isChecked()
|
||||
await page.locator('//*[@id="showload_hidden"]').isChecked(),
|
||||
).toBeTruthy();
|
||||
|
||||
await page.getByText("Save Changes", { exact: true }).click();
|
||||
|
|
@ -81,12 +81,12 @@ test("ToggleComponent", async ({ page }) => {
|
|||
|
||||
await page.locator('//*[@id="showload_hidden"]').click();
|
||||
expect(
|
||||
await page.locator('//*[@id="showload_hidden"]').isChecked()
|
||||
await page.locator('//*[@id="showload_hidden"]').isChecked(),
|
||||
).toBeFalsy();
|
||||
|
||||
await page.locator('//*[@id="showmax_concurrency"]').click();
|
||||
expect(
|
||||
await page.locator('//*[@id="showmax_concurrency"]').isChecked()
|
||||
await page.locator('//*[@id="showmax_concurrency"]').isChecked(),
|
||||
).toBeTruthy();
|
||||
|
||||
await page.locator('//*[@id="showpath"]').click();
|
||||
|
|
@ -94,22 +94,22 @@ test("ToggleComponent", async ({ page }) => {
|
|||
|
||||
await page.locator('//*[@id="showrecursive"]').click();
|
||||
expect(
|
||||
await page.locator('//*[@id="showrecursive"]').isChecked()
|
||||
await page.locator('//*[@id="showrecursive"]').isChecked(),
|
||||
).toBeTruthy();
|
||||
|
||||
await page.locator('//*[@id="showsilent_errors"]').click();
|
||||
expect(
|
||||
await page.locator('//*[@id="showsilent_errors"]').isChecked()
|
||||
await page.locator('//*[@id="showsilent_errors"]').isChecked(),
|
||||
).toBeTruthy();
|
||||
|
||||
await page.locator('//*[@id="showuse_multithreading"]').click();
|
||||
expect(
|
||||
await page.locator('//*[@id="showuse_multithreading"]').isChecked()
|
||||
await page.locator('//*[@id="showuse_multithreading"]').isChecked(),
|
||||
).toBeTruthy();
|
||||
|
||||
await page.locator('//*[@id="showmax_concurrency"]').click();
|
||||
expect(
|
||||
await page.locator('//*[@id="showmax_concurrency"]').isChecked()
|
||||
await page.locator('//*[@id="showmax_concurrency"]').isChecked(),
|
||||
).toBeFalsy();
|
||||
|
||||
await page.locator('//*[@id="showpath"]').click();
|
||||
|
|
@ -117,17 +117,17 @@ test("ToggleComponent", async ({ page }) => {
|
|||
|
||||
await page.locator('//*[@id="showrecursive"]').click();
|
||||
expect(
|
||||
await page.locator('//*[@id="showrecursive"]').isChecked()
|
||||
await page.locator('//*[@id="showrecursive"]').isChecked(),
|
||||
).toBeFalsy();
|
||||
|
||||
await page.locator('//*[@id="showsilent_errors"]').click();
|
||||
expect(
|
||||
await page.locator('//*[@id="showsilent_errors"]').isChecked()
|
||||
await page.locator('//*[@id="showsilent_errors"]').isChecked(),
|
||||
).toBeFalsy();
|
||||
|
||||
await page.locator('//*[@id="showuse_multithreading"]').click();
|
||||
expect(
|
||||
await page.locator('//*[@id="showuse_multithreading"]').isChecked()
|
||||
await page.locator('//*[@id="showuse_multithreading"]').isChecked(),
|
||||
).toBeFalsy();
|
||||
|
||||
await page.getByText("Save Changes", { exact: true }).click();
|
||||
|
|
@ -144,38 +144,38 @@ test("ToggleComponent", async ({ page }) => {
|
|||
|
||||
await page.locator('//*[@id="showload_hidden"]').click();
|
||||
expect(
|
||||
await page.locator('//*[@id="showload_hidden"]').isChecked()
|
||||
await page.locator('//*[@id="showload_hidden"]').isChecked(),
|
||||
).toBeTruthy();
|
||||
|
||||
expect(
|
||||
await page.getByTestId("toggle-edit-load_hidden").isChecked()
|
||||
await page.getByTestId("toggle-edit-load_hidden").isChecked(),
|
||||
).toBeTruthy();
|
||||
|
||||
await page.getByText("Save Changes", { exact: true }).click();
|
||||
|
||||
await page.getByTestId("toggle-load_hidden").click();
|
||||
expect(
|
||||
await page.getByTestId("toggle-load_hidden").isChecked()
|
||||
await page.getByTestId("toggle-load_hidden").isChecked(),
|
||||
).toBeFalsy();
|
||||
|
||||
await page.getByTestId("toggle-load_hidden").click();
|
||||
expect(
|
||||
await page.getByTestId("toggle-load_hidden").isChecked()
|
||||
await page.getByTestId("toggle-load_hidden").isChecked(),
|
||||
).toBeTruthy();
|
||||
|
||||
await page.getByTestId("toggle-load_hidden").click();
|
||||
expect(
|
||||
await page.getByTestId("toggle-load_hidden").isChecked()
|
||||
await page.getByTestId("toggle-load_hidden").isChecked(),
|
||||
).toBeFalsy();
|
||||
|
||||
await page.getByTestId("toggle-load_hidden").click();
|
||||
expect(
|
||||
await page.getByTestId("toggle-load_hidden").isChecked()
|
||||
await page.getByTestId("toggle-load_hidden").isChecked(),
|
||||
).toBeTruthy();
|
||||
|
||||
await page.getByTestId("toggle-load_hidden").click();
|
||||
expect(
|
||||
await page.getByTestId("toggle-load_hidden").isChecked()
|
||||
await page.getByTestId("toggle-load_hidden").isChecked(),
|
||||
).toBeFalsy();
|
||||
}
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue