Merge dev into shortcuts_settings
This commit is contained in:
commit
b698ca3fd2
19 changed files with 108 additions and 86 deletions
|
|
@ -205,17 +205,12 @@ async def build_and_cache_graph_from_db(
|
||||||
flow_id: str,
|
flow_id: str,
|
||||||
session: Session,
|
session: Session,
|
||||||
chat_service: "ChatService",
|
chat_service: "ChatService",
|
||||||
graph: Optional[Graph] = None,
|
|
||||||
):
|
):
|
||||||
"""Build and cache the graph."""
|
"""Build and cache the graph."""
|
||||||
flow: Optional[Flow] = session.get(Flow, flow_id)
|
flow: Optional[Flow] = session.get(Flow, flow_id)
|
||||||
if not flow or not flow.data:
|
if not flow or not flow.data:
|
||||||
raise ValueError("Invalid flow ID")
|
raise ValueError("Invalid flow ID")
|
||||||
other_graph = Graph.from_payload(flow.data, flow_id)
|
graph = Graph.from_payload(flow.data, flow_id)
|
||||||
if graph is None:
|
|
||||||
graph = other_graph
|
|
||||||
else:
|
|
||||||
graph = graph.update(other_graph)
|
|
||||||
await chat_service.set_cache(flow_id, graph)
|
await chat_service.set_cache(flow_id, graph)
|
||||||
return graph
|
return graph
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -79,13 +79,8 @@ async def retrieve_vertices_order(
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
# First, we need to check if the flow_id is in the cache
|
# First, we need to check if the flow_id is in the cache
|
||||||
graph = None
|
|
||||||
if not data:
|
if not data:
|
||||||
if cache := await chat_service.get_cache(flow_id):
|
graph = await build_and_cache_graph_from_db(flow_id=flow_id, session=session, chat_service=chat_service)
|
||||||
graph = cache.get("result")
|
|
||||||
graph = await build_and_cache_graph_from_db(
|
|
||||||
flow_id=flow_id, session=session, chat_service=chat_service, graph=graph
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
graph = await build_and_cache_graph_from_data(
|
graph = await build_and_cache_graph_from_data(
|
||||||
flow_id=flow_id, graph_data=data.model_dump(), chat_service=chat_service
|
flow_id=flow_id, graph_data=data.model_dump(), chat_service=chat_service
|
||||||
|
|
|
||||||
|
|
@ -93,14 +93,14 @@ class APIRequest(CustomComponent):
|
||||||
self,
|
self,
|
||||||
method: str,
|
method: str,
|
||||||
urls: List[str],
|
urls: List[str],
|
||||||
_headers: Optional[Record] = None,
|
headers: Optional[Record] = None,
|
||||||
body: Optional[Record] = None,
|
body: Optional[Record] = None,
|
||||||
timeout: int = 5,
|
timeout: int = 5,
|
||||||
) -> List[Record]:
|
) -> List[Record]:
|
||||||
if _headers is None:
|
if headers is None:
|
||||||
headers = {}
|
headers_dict = {}
|
||||||
else:
|
else:
|
||||||
headers = _headers.data
|
headers_dict = headers.data
|
||||||
|
|
||||||
bodies = []
|
bodies = []
|
||||||
if body:
|
if body:
|
||||||
|
|
@ -114,7 +114,7 @@ class APIRequest(CustomComponent):
|
||||||
bodies += [None] * (len(urls) - len(bodies)) # type: ignore
|
bodies += [None] * (len(urls) - len(bodies)) # type: ignore
|
||||||
async with httpx.AsyncClient() as client:
|
async with httpx.AsyncClient() as client:
|
||||||
results = await asyncio.gather(
|
results = await asyncio.gather(
|
||||||
*[self.make_request(client, method, u, headers, rec, timeout) for u, rec in zip(urls, bodies)]
|
*[self.make_request(client, method, u, headers_dict, rec, timeout) for u, rec in zip(urls, bodies)]
|
||||||
)
|
)
|
||||||
self.status = results
|
self.status = results
|
||||||
return results
|
return results
|
||||||
|
|
|
||||||
|
|
@ -445,9 +445,16 @@ class Graph:
|
||||||
vertex = self.get_vertex(vertex_id)
|
vertex = self.get_vertex(vertex_id)
|
||||||
vertex.set_state(state)
|
vertex.set_state(state)
|
||||||
|
|
||||||
def mark_branch(self, vertex_id: str, state: str):
|
def mark_branch(self, vertex_id: str, state: str, visited: Optional[set] = None):
|
||||||
"""Marks a branch of the graph."""
|
"""Marks a branch of the graph."""
|
||||||
|
if visited is None:
|
||||||
|
visited = set()
|
||||||
|
visited.add(vertex_id)
|
||||||
|
if vertex_id in visited:
|
||||||
|
return
|
||||||
|
|
||||||
self.mark_vertex(vertex_id, state)
|
self.mark_vertex(vertex_id, state)
|
||||||
|
|
||||||
for child_id in self.parent_child_map[vertex_id]:
|
for child_id in self.parent_child_map[vertex_id]:
|
||||||
self.mark_branch(child_id, state)
|
self.mark_branch(child_id, state)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,7 @@ def get_id_from_search_string(search_string: str) -> Optional[str]:
|
||||||
Returns:
|
Returns:
|
||||||
Optional[str]: The extracted ID, or None if no ID is found.
|
Optional[str]: The extracted ID, or None if no ID is found.
|
||||||
"""
|
"""
|
||||||
possible_id = search_string
|
possible_id: Optional[str] = search_string
|
||||||
if "www.langflow.store/store/" in search_string:
|
if "www.langflow.store/store/" in search_string:
|
||||||
possible_id = search_string.split("/")[-1]
|
possible_id = search_string.split("/")[-1]
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import useAlertStore from "../../stores/alertStore";
|
||||||
import { useGlobalVariablesStore } from "../../stores/globalVariables";
|
import { useGlobalVariablesStore } from "../../stores/globalVariables";
|
||||||
import { useTypesStore } from "../../stores/typesStore";
|
import { useTypesStore } from "../../stores/typesStore";
|
||||||
import { ResponseErrorDetailAPI } from "../../types/api";
|
import { ResponseErrorDetailAPI } from "../../types/api";
|
||||||
|
import { sortByName } from "../../utils/utils";
|
||||||
import ForwardedIconComponent from "../genericIconComponent";
|
import ForwardedIconComponent from "../genericIconComponent";
|
||||||
import InputComponent from "../inputComponent";
|
import InputComponent from "../inputComponent";
|
||||||
import { Button } from "../ui/button";
|
import { Button } from "../ui/button";
|
||||||
|
|
@ -23,14 +24,19 @@ export default function AddNewVariableButton({ children }): JSX.Element {
|
||||||
const setErrorData = useAlertStore((state) => state.setErrorData);
|
const setErrorData = useAlertStore((state) => state.setErrorData);
|
||||||
const componentFields = useTypesStore((state) => state.ComponentFields);
|
const componentFields = useTypesStore((state) => state.ComponentFields);
|
||||||
const unavaliableFields = new Set(
|
const unavaliableFields = new Set(
|
||||||
Object.keys(useGlobalVariablesStore((state) => state.unavaliableFields))
|
Object.keys(useGlobalVariablesStore((state) => state.unavaliableFields)),
|
||||||
);
|
);
|
||||||
|
|
||||||
const availableFields = Array.from(componentFields).filter(
|
const availableFields = () => {
|
||||||
(field) => !unavaliableFields.has(field)
|
const fields = Array.from(componentFields).filter(
|
||||||
);
|
(field) => !unavaliableFields.has(field),
|
||||||
|
);
|
||||||
|
|
||||||
|
return sortByName(fields);
|
||||||
|
};
|
||||||
|
|
||||||
const addGlobalVariable = useGlobalVariablesStore(
|
const addGlobalVariable = useGlobalVariablesStore(
|
||||||
(state) => state.addGlobalVariable
|
(state) => state.addGlobalVariable,
|
||||||
);
|
);
|
||||||
|
|
||||||
function handleSaveVariable() {
|
function handleSaveVariable() {
|
||||||
|
|
@ -113,7 +119,7 @@ export default function AddNewVariableButton({ children }): JSX.Element {
|
||||||
setSelectedOptions={(value) => setFields(value)}
|
setSelectedOptions={(value) => setFields(value)}
|
||||||
selectedOptions={fields}
|
selectedOptions={fields}
|
||||||
password={false}
|
password={false}
|
||||||
options={availableFields}
|
options={availableFields()}
|
||||||
placeholder="Choose a field for the variable..."
|
placeholder="Choose a field for the variable..."
|
||||||
id={"apply-to-fields"}
|
id={"apply-to-fields"}
|
||||||
></InputComponent>
|
></InputComponent>
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,6 @@ import cloneFLowWithParent from "../../utils/storeUtils";
|
||||||
import { cn, convertTestName } from "../../utils/utils";
|
import { cn, convertTestName } from "../../utils/utils";
|
||||||
import IconComponent from "../genericIconComponent";
|
import IconComponent from "../genericIconComponent";
|
||||||
import ShadTooltip from "../shadTooltipComponent";
|
import ShadTooltip from "../shadTooltipComponent";
|
||||||
import { Badge } from "../ui/badge";
|
|
||||||
import { Button } from "../ui/button";
|
import { Button } from "../ui/button";
|
||||||
import {
|
import {
|
||||||
Card,
|
Card,
|
||||||
|
|
@ -170,8 +169,9 @@ export default function CollectionCardComponent({
|
||||||
<>
|
<>
|
||||||
<Card
|
<Card
|
||||||
data-testid={`card-${convertTestName(data.name)}`}
|
data-testid={`card-${convertTestName(data.name)}`}
|
||||||
|
//TODO check color schema
|
||||||
className={cn(
|
className={cn(
|
||||||
"group relative flex min-h-[11rem] flex-col justify-between overflow-hidden transition-all hover:shadow-md",
|
"group relative flex min-h-[11rem] flex-col justify-between overflow-hidden transition-all hover:bg-muted/50 hover:shadow-md hover:dark:bg-[#ffffff10]",
|
||||||
disabled ? "pointer-events-none opacity-50" : "",
|
disabled ? "pointer-events-none opacity-50" : "",
|
||||||
onClick ? "cursor-pointer" : "",
|
onClick ? "cursor-pointer" : "",
|
||||||
)}
|
)}
|
||||||
|
|
@ -239,6 +239,7 @@ export default function CollectionCardComponent({
|
||||||
|
|
||||||
{onDelete && data?.metadata === undefined && (
|
{onDelete && data?.metadata === undefined && (
|
||||||
<button
|
<button
|
||||||
|
className="z-50"
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
setOpenDelete(true);
|
setOpenDelete(true);
|
||||||
|
|
@ -269,7 +270,7 @@ export default function CollectionCardComponent({
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
<div className="flex w-full flex-1 flex-wrap gap-2">
|
<div className="flex w-full flex-1 flex-wrap gap-2">
|
||||||
{data.tags &&
|
{/* {data.tags &&
|
||||||
data.tags.length > 0 &&
|
data.tags.length > 0 &&
|
||||||
data.tags.map((tag, index) => (
|
data.tags.map((tag, index) => (
|
||||||
<Badge
|
<Badge
|
||||||
|
|
@ -280,7 +281,7 @@ export default function CollectionCardComponent({
|
||||||
>
|
>
|
||||||
{tag.name}
|
{tag.name}
|
||||||
</Badge>
|
</Badge>
|
||||||
))}
|
))} */}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -291,8 +292,8 @@ export default function CollectionCardComponent({
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<CardFooter>
|
<CardFooter>
|
||||||
<div className="flex w-full items-center justify-between gap-2">
|
<div className="z-50 flex w-full items-center justify-between gap-2">
|
||||||
<div className="flex w-full flex-wrap items-end justify-between gap-2">
|
<div className="flex w-full flex-wrap items-end justify-end gap-2">
|
||||||
{playground && data?.metadata !== undefined ? (
|
{playground && data?.metadata !== undefined ? (
|
||||||
<Button
|
<Button
|
||||||
disabled={loadingPlayground}
|
disabled={loadingPlayground}
|
||||||
|
|
@ -300,7 +301,7 @@ export default function CollectionCardComponent({
|
||||||
tabIndex={-1}
|
tabIndex={-1}
|
||||||
variant="outline"
|
variant="outline"
|
||||||
size="sm"
|
size="sm"
|
||||||
className="gap-2 whitespace-nowrap"
|
className="z-50 gap-2 whitespace-nowrap"
|
||||||
data-testid={"playground-flow-button-" + data.id}
|
data-testid={"playground-flow-button-" + data.id}
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
@ -436,15 +437,14 @@ export default function CollectionCardComponent({
|
||||||
</ShadTooltip>
|
</ShadTooltip>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{button && button}
|
|
||||||
{playground && data?.metadata === undefined && (
|
{playground && data?.metadata === undefined && (
|
||||||
<Button
|
<Button
|
||||||
disabled={loadingPlayground}
|
disabled={loadingPlayground}
|
||||||
key={data.id}
|
key={data.id}
|
||||||
tabIndex={-1}
|
tabIndex={-1}
|
||||||
variant="outline"
|
variant="primary"
|
||||||
size="sm"
|
size="sm"
|
||||||
className="gap-2 whitespace-nowrap"
|
className="gap-2 whitespace-nowrap bg-muted"
|
||||||
data-testid={"playground-flow-button-" + data.id}
|
data-testid={"playground-flow-button-" + data.id}
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,7 @@ export default function FlowToolbar(): JSX.Element {
|
||||||
"relative inline-flex h-full w-full items-center justify-center gap-[4px] bg-muted px-5 py-3 text-sm font-semibold text-foreground transition-all duration-150 ease-in-out hover:bg-background hover:bg-hover ",
|
"relative inline-flex h-full w-full items-center justify-center gap-[4px] bg-muted px-5 py-3 text-sm font-semibold text-foreground transition-all duration-150 ease-in-out hover:bg-background hover:bg-hover ",
|
||||||
!hasApiKey || !validApiKey || !hasStore
|
!hasApiKey || !validApiKey || !hasStore
|
||||||
? " button-disable text-muted-foreground "
|
? " button-disable text-muted-foreground "
|
||||||
: ""
|
: "",
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<ForwardedIconComponent
|
<ForwardedIconComponent
|
||||||
|
|
@ -63,14 +63,14 @@ export default function FlowToolbar(): JSX.Element {
|
||||||
"-m-0.5 -ml-1 h-6 w-6",
|
"-m-0.5 -ml-1 h-6 w-6",
|
||||||
!hasApiKey || !validApiKey || !hasStore
|
!hasApiKey || !validApiKey || !hasStore
|
||||||
? "extra-side-bar-save-disable"
|
? "extra-side-bar-save-disable"
|
||||||
: ""
|
: "",
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
Share
|
Share
|
||||||
</button>
|
</button>
|
||||||
</ShareModal>
|
</ShareModal>
|
||||||
),
|
),
|
||||||
[hasApiKey, validApiKey, currentFlow, hasStore]
|
[hasApiKey, validApiKey, currentFlow, hasStore],
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
@ -112,7 +112,7 @@ export default function FlowToolbar(): JSX.Element {
|
||||||
"message-button-icon h-5 w-5 fill-muted-foreground stroke-muted-foreground transition-all"
|
"message-button-icon h-5 w-5 fill-muted-foreground stroke-muted-foreground transition-all"
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
Run
|
Playground
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -128,7 +128,7 @@ export default function FlowToolbar(): JSX.Element {
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className={classNames(
|
className={classNames(
|
||||||
"relative inline-flex w-full items-center justify-center gap-1 px-5 py-3 text-sm font-semibold text-foreground transition-all duration-150 ease-in-out hover:bg-hover"
|
"relative inline-flex w-full items-center justify-center gap-1 px-5 py-3 text-sm font-semibold text-foreground transition-all duration-150 ease-in-out hover:bg-hover",
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<ForwardedIconComponent
|
<ForwardedIconComponent
|
||||||
|
|
|
||||||
|
|
@ -69,7 +69,7 @@ function CsvOutputComponent({
|
||||||
if (file) {
|
if (file) {
|
||||||
const { rowData: data, colDefs: columns } = convertCSVToData(
|
const { rowData: data, colDefs: columns } = convertCSVToData(
|
||||||
file,
|
file,
|
||||||
separator
|
separator,
|
||||||
);
|
);
|
||||||
setRowData(data);
|
setRowData(data);
|
||||||
setColDefs(columns);
|
setColDefs(columns);
|
||||||
|
|
@ -114,14 +114,14 @@ function CsvOutputComponent({
|
||||||
(params: any) => {
|
(params: any) => {
|
||||||
updateRowHeight(params);
|
updateRowHeight(params);
|
||||||
},
|
},
|
||||||
[updateRowHeight]
|
[updateRowHeight],
|
||||||
);
|
);
|
||||||
|
|
||||||
const onGridSizeChanged = useCallback(
|
const onGridSizeChanged = useCallback(
|
||||||
(params: any) => {
|
(params: any) => {
|
||||||
updateRowHeight(params);
|
updateRowHeight(params);
|
||||||
},
|
},
|
||||||
[updateRowHeight]
|
[updateRowHeight],
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
@ -167,6 +167,7 @@ function CsvOutputComponent({
|
||||||
onFirstDataRendered={onFirstDataRendered}
|
onFirstDataRendered={onFirstDataRendered}
|
||||||
onGridSizeChanged={onGridSizeChanged}
|
onGridSizeChanged={onGridSizeChanged}
|
||||||
scrollbarWidth={8}
|
scrollbarWidth={8}
|
||||||
|
overlayNoRowsTemplate="No data available"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import { ComponentPropsWithoutRef, ElementRef, forwardRef } from "react";
|
||||||
import { useDarkStore } from "../../stores/darkStore";
|
import { useDarkStore } from "../../stores/darkStore";
|
||||||
import "../../style/ag-theme-shadcn.css"; // Custom CSS applied to the grid
|
import "../../style/ag-theme-shadcn.css"; // Custom CSS applied to the grid
|
||||||
import { cn } from "../../utils/utils";
|
import { cn } from "../../utils/utils";
|
||||||
|
import { Card, CardContent } from "../ui/card";
|
||||||
|
|
||||||
const TableComponent = forwardRef<
|
const TableComponent = forwardRef<
|
||||||
ElementRef<typeof AgGridReact>,
|
ElementRef<typeof AgGridReact>,
|
||||||
|
|
@ -17,10 +18,18 @@ const TableComponent = forwardRef<
|
||||||
<div
|
<div
|
||||||
className={cn(
|
className={cn(
|
||||||
dark ? "ag-theme-quartz-dark" : "ag-theme-quartz",
|
dark ? "ag-theme-quartz-dark" : "ag-theme-quartz",
|
||||||
"ag-theme-shadcn flex h-full flex-col"
|
"ag-theme-shadcn flex h-full flex-col",
|
||||||
)} // applying the grid theme
|
)} // applying the grid theme
|
||||||
>
|
>
|
||||||
<AgGridReact ref={ref} {...props} />
|
<Card x-chunk="dashboard-04-chunk-2" className="pt-4">
|
||||||
|
<CardContent>
|
||||||
|
<AgGridReact
|
||||||
|
overlayNoRowsTemplate="No data available"
|
||||||
|
ref={ref}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -117,7 +117,7 @@ export default function IOModal({
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<BaseModal
|
<BaseModal
|
||||||
size={selectedTab === 0 ? "large-thin" : "md-thin"}
|
size={selectedTab === 0 ? "sm-thin" : "md-thin"}
|
||||||
open={open}
|
open={open}
|
||||||
setOpen={setOpen}
|
setOpen={setOpen}
|
||||||
disable={disable}
|
disable={disable}
|
||||||
|
|
|
||||||
|
|
@ -79,6 +79,7 @@ interface BaseModalProps {
|
||||||
| "small-h-full"
|
| "small-h-full"
|
||||||
| "medium-h-full"
|
| "medium-h-full"
|
||||||
| "md-thin"
|
| "md-thin"
|
||||||
|
| "sm-thin"
|
||||||
| "smaller-h-full";
|
| "smaller-h-full";
|
||||||
|
|
||||||
disable?: boolean;
|
disable?: boolean;
|
||||||
|
|
@ -154,6 +155,11 @@ function BaseModal({
|
||||||
height = "h-[70vh]";
|
height = "h-[70vh]";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case "sm-thin":
|
||||||
|
minWidth = "min-w-[65vw]";
|
||||||
|
height = "h-[70vh]";
|
||||||
|
break;
|
||||||
|
|
||||||
case "large-h-full":
|
case "large-h-full":
|
||||||
minWidth = "min-w-[80vw]";
|
minWidth = "min-w-[80vw]";
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -15,13 +15,13 @@ import { cn } from "../../../../utils/utils";
|
||||||
|
|
||||||
export default function GlobalVariablesPage() {
|
export default function GlobalVariablesPage() {
|
||||||
const globalVariablesEntries = useGlobalVariablesStore(
|
const globalVariablesEntries = useGlobalVariablesStore(
|
||||||
(state) => state.globalVariablesEntries
|
(state) => state.globalVariablesEntries,
|
||||||
);
|
);
|
||||||
const removeGlobalVariable = useGlobalVariablesStore(
|
const removeGlobalVariable = useGlobalVariablesStore(
|
||||||
(state) => state.removeGlobalVariable
|
(state) => state.removeGlobalVariable,
|
||||||
);
|
);
|
||||||
const globalVariables = useGlobalVariablesStore(
|
const globalVariables = useGlobalVariablesStore(
|
||||||
(state) => state.globalVariables
|
(state) => state.globalVariables,
|
||||||
);
|
);
|
||||||
const setErrorData = useAlertStore((state) => state.setErrorData);
|
const setErrorData = useAlertStore((state) => state.setErrorData);
|
||||||
const getVariableId = useGlobalVariablesStore((state) => state.getVariableId);
|
const getVariableId = useGlobalVariablesStore((state) => state.getVariableId);
|
||||||
|
|
@ -154,7 +154,7 @@ export default function GlobalVariablesPage() {
|
||||||
<IconComponent
|
<IconComponent
|
||||||
name="Trash2"
|
name="Trash2"
|
||||||
className={cn(
|
className={cn(
|
||||||
"h-5 w-5 text-destructive group-disabled:text-primary"
|
"h-5 w-5 text-destructive group-disabled:text-primary",
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
</Button>
|
</Button>
|
||||||
|
|
@ -174,6 +174,8 @@ export default function GlobalVariablesPage() {
|
||||||
}}
|
}}
|
||||||
rowSelection="multiple"
|
rowSelection="multiple"
|
||||||
suppressRowClickSelection={true}
|
suppressRowClickSelection={true}
|
||||||
|
domLayout="autoHeight"
|
||||||
|
pagination={false}
|
||||||
columnDefs={colDefs}
|
columnDefs={colDefs}
|
||||||
rowData={rowData}
|
rowData={rowData}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -43,10 +43,6 @@ export default function ShortcutsPage() {
|
||||||
|
|
||||||
const combinationToEdit = shortcuts.filter((s) => s.name === selectedRows[0]);
|
const combinationToEdit = shortcuts.filter((s) => s.name === selectedRows[0]);
|
||||||
const [open, setOpen] = useState(false);
|
const [open, setOpen] = useState(false);
|
||||||
|
|
||||||
const unavaliableShortcuts = useShortcutsStore(
|
|
||||||
(state) => state.unavailableShortcuts
|
|
||||||
);
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (localStorage.getItem("langflow-shortcuts")) {
|
if (localStorage.getItem("langflow-shortcuts")) {
|
||||||
const savedShortcuts = localStorage.getItem("langflow-shortcuts");
|
const savedShortcuts = localStorage.getItem("langflow-shortcuts");
|
||||||
|
|
@ -109,7 +105,7 @@ export default function ShortcutsPage() {
|
||||||
<TableComponent
|
<TableComponent
|
||||||
onSelectionChanged={(event: SelectionChangedEvent) => {
|
onSelectionChanged={(event: SelectionChangedEvent) => {
|
||||||
setSelectedRows(
|
setSelectedRows(
|
||||||
event.api.getSelectedRows().map((row) => row.name)
|
event.api.getSelectedRows().map((row) => row.name),
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
suppressRowClickSelection={true}
|
suppressRowClickSelection={true}
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,9 @@
|
||||||
|
|
||||||
body {
|
body {
|
||||||
@apply bg-background text-foreground;
|
@apply bg-background text-foreground;
|
||||||
font-feature-settings: "rlig" 1, "calt" 1;
|
font-feature-settings:
|
||||||
|
"rlig" 1,
|
||||||
|
"calt" 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1018,6 +1020,9 @@
|
||||||
.langflow-chat-span {
|
.langflow-chat-span {
|
||||||
@apply text-lg text-foreground;
|
@apply text-lg text-foreground;
|
||||||
}
|
}
|
||||||
|
.card-filter {
|
||||||
|
@apply bg-background bg-fixed opacity-20;
|
||||||
|
}
|
||||||
.langflow-chat-desc {
|
.langflow-chat-desc {
|
||||||
@apply w-2/4 rounded-md border border-border bg-muted px-6 py-8;
|
@apply w-2/4 rounded-md border border-border bg-muted px-6 py-8;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ type BuildVerticesParams = {
|
||||||
onBuildUpdate?: (
|
onBuildUpdate?: (
|
||||||
data: VertexBuildTypeAPI,
|
data: VertexBuildTypeAPI,
|
||||||
status: BuildStatus,
|
status: BuildStatus,
|
||||||
buildId: string
|
buildId: string,
|
||||||
) => void; // Replace any with the actual type if it's not any
|
) => void; // Replace any with the actual type if it's not any
|
||||||
onBuildComplete?: (allNodesValid: boolean) => void;
|
onBuildComplete?: (allNodesValid: boolean) => void;
|
||||||
onBuildError?: (title, list, idList: VertexLayerElementType[]) => void;
|
onBuildError?: (title, list, idList: VertexLayerElementType[]) => void;
|
||||||
|
|
@ -53,7 +53,7 @@ export async function updateVerticesOrder(
|
||||||
startNodeId?: string | null,
|
startNodeId?: string | null,
|
||||||
stopNodeId?: string | null,
|
stopNodeId?: string | null,
|
||||||
nodes?: Node[],
|
nodes?: Node[],
|
||||||
edges?: Edge[]
|
edges?: Edge[],
|
||||||
): Promise<{
|
): Promise<{
|
||||||
verticesLayers: VertexLayerElementType[][];
|
verticesLayers: VertexLayerElementType[][];
|
||||||
verticesIds: string[];
|
verticesIds: string[];
|
||||||
|
|
@ -69,7 +69,7 @@ export async function updateVerticesOrder(
|
||||||
startNodeId,
|
startNodeId,
|
||||||
stopNodeId,
|
stopNodeId,
|
||||||
nodes,
|
nodes,
|
||||||
edges
|
edges,
|
||||||
);
|
);
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
setErrorData({
|
setErrorData({
|
||||||
|
|
@ -116,33 +116,29 @@ export async function buildVertices({
|
||||||
nodes,
|
nodes,
|
||||||
edges,
|
edges,
|
||||||
}: BuildVerticesParams) {
|
}: BuildVerticesParams) {
|
||||||
let verticesBuild = useFlowStore.getState().verticesBuild;
|
|
||||||
// if startNodeId and stopNodeId are provided
|
// if startNodeId and stopNodeId are provided
|
||||||
// something is wrong
|
// something is wrong
|
||||||
if (startNodeId && stopNodeId) {
|
if (startNodeId && stopNodeId) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
let verticesOrderResponse = await updateVerticesOrder(
|
||||||
|
flowId,
|
||||||
|
startNodeId,
|
||||||
|
stopNodeId,
|
||||||
|
nodes,
|
||||||
|
edges,
|
||||||
|
);
|
||||||
|
if (onValidateNodes) {
|
||||||
|
try {
|
||||||
|
onValidateNodes(verticesOrderResponse.verticesToRun);
|
||||||
|
} catch (e) {
|
||||||
|
useFlowStore.getState().setIsBuilding(false);
|
||||||
|
|
||||||
if (!verticesBuild || startNodeId || stopNodeId) {
|
return;
|
||||||
let verticesOrderResponse = await updateVerticesOrder(
|
|
||||||
flowId,
|
|
||||||
startNodeId,
|
|
||||||
stopNodeId,
|
|
||||||
nodes,
|
|
||||||
edges
|
|
||||||
);
|
|
||||||
if (onValidateNodes) {
|
|
||||||
try {
|
|
||||||
onValidateNodes(verticesOrderResponse.verticesToRun);
|
|
||||||
} catch (e) {
|
|
||||||
useFlowStore.getState().setIsBuilding(false);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (onGetOrderSuccess) onGetOrderSuccess();
|
|
||||||
verticesBuild = useFlowStore.getState().verticesBuild;
|
|
||||||
}
|
}
|
||||||
|
if (onGetOrderSuccess) onGetOrderSuccess();
|
||||||
|
let verticesBuild = useFlowStore.getState().verticesBuild;
|
||||||
|
|
||||||
const verticesIds = verticesBuild?.verticesIds!;
|
const verticesIds = verticesBuild?.verticesIds!;
|
||||||
const verticesLayers = verticesBuild?.verticesLayers!;
|
const verticesLayers = verticesBuild?.verticesLayers!;
|
||||||
|
|
@ -192,14 +188,14 @@ export async function buildVertices({
|
||||||
onBuildUpdate(
|
onBuildUpdate(
|
||||||
getInactiveVertexData(element.id),
|
getInactiveVertexData(element.id),
|
||||||
BuildStatus.INACTIVE,
|
BuildStatus.INACTIVE,
|
||||||
runId
|
runId,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (element.reference) {
|
if (element.reference) {
|
||||||
onBuildUpdate(
|
onBuildUpdate(
|
||||||
getInactiveVertexData(element.reference),
|
getInactiveVertexData(element.reference),
|
||||||
BuildStatus.INACTIVE,
|
BuildStatus.INACTIVE,
|
||||||
runId
|
runId,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
buildResults.push(false);
|
buildResults.push(false);
|
||||||
|
|
@ -224,7 +220,7 @@ export async function buildVertices({
|
||||||
if (stop) {
|
if (stop) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
})
|
}),
|
||||||
);
|
);
|
||||||
// Once the current layer is built, move to the next layer
|
// Once the current layer is built, move to the next layer
|
||||||
currentLayerIndex += 1;
|
currentLayerIndex += 1;
|
||||||
|
|
@ -267,7 +263,7 @@ async function buildVertex({
|
||||||
onBuildError!(
|
onBuildError!(
|
||||||
"Error Building Component",
|
"Error Building Component",
|
||||||
[buildData.params],
|
[buildData.params],
|
||||||
verticesIds.map((id) => ({ id }))
|
verticesIds.map((id) => ({ id })),
|
||||||
);
|
);
|
||||||
stopBuild();
|
stopBuild();
|
||||||
}
|
}
|
||||||
|
|
@ -278,7 +274,7 @@ async function buildVertex({
|
||||||
onBuildError!(
|
onBuildError!(
|
||||||
"Error Building Component",
|
"Error Building Component",
|
||||||
[(error as AxiosError<any>).response?.data?.detail ?? "Unknown Error"],
|
[(error as AxiosError<any>).response?.data?.detail ?? "Unknown Error"],
|
||||||
verticesIds.map((id) => ({ id }))
|
verticesIds.map((id) => ({ id })),
|
||||||
);
|
);
|
||||||
stopBuild();
|
stopBuild();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -719,3 +719,7 @@ export function freezeObject(obj: any) {
|
||||||
export function convertTestName(name: string): string {
|
export function convertTestName(name: string): string {
|
||||||
return name.replace(/ /g, "-").toLowerCase();
|
return name.replace(/ /g, "-").toLowerCase();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function sortByName(stringList: string[]): string[] {
|
||||||
|
return stringList.sort((a, b) => a.localeCompare(b));
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,7 @@ test("should interact with global variables", async ({ page }) => {
|
||||||
.nth(0)
|
.nth(0)
|
||||||
.click();
|
.click();
|
||||||
await page.getByTestId("icon-Trash2").click();
|
await page.getByTestId("icon-Trash2").click();
|
||||||
await page.getByText("No Rows To Show").isVisible();
|
await page.getByText("No data available").isVisible();
|
||||||
});
|
});
|
||||||
|
|
||||||
test("should see shortcuts", async ({ page }) => {
|
test("should see shortcuts", async ({ page }) => {
|
||||||
|
|
|
||||||
|
|
@ -393,13 +393,13 @@ def test_various_prompts(client, prompt, expected_input_variables):
|
||||||
|
|
||||||
|
|
||||||
def test_get_vertices_flow_not_found(client, logged_in_headers):
|
def test_get_vertices_flow_not_found(client, logged_in_headers):
|
||||||
response = client.get("/api/v1/build/nonexistent_id/vertices", headers=logged_in_headers)
|
response = client.post("/api/v1/build/nonexistent_id/vertices", headers=logged_in_headers)
|
||||||
assert response.status_code == 500 # Or whatever status code you've set for invalid ID
|
assert response.status_code == 500 # Or whatever status code you've set for invalid ID
|
||||||
|
|
||||||
|
|
||||||
def test_get_vertices(client, added_flow_with_prompt_and_history, logged_in_headers):
|
def test_get_vertices(client, added_flow_with_prompt_and_history, logged_in_headers):
|
||||||
flow_id = added_flow_with_prompt_and_history["id"]
|
flow_id = added_flow_with_prompt_and_history["id"]
|
||||||
response = client.get(f"/api/v1/build/{flow_id}/vertices", headers=logged_in_headers)
|
response = client.post(f"/api/v1/build/{flow_id}/vertices", headers=logged_in_headers)
|
||||||
assert response.status_code == 200
|
assert response.status_code == 200
|
||||||
assert "ids" in response.json()
|
assert "ids" in response.json()
|
||||||
# The response should contain the list in this order
|
# The response should contain the list in this order
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue