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