Merge remote-tracking branch 'origin/feature/store' into bug/undo-copy
This commit is contained in:
commit
7ee1ad03f4
101 changed files with 1925 additions and 919 deletions
|
|
@ -21,11 +21,17 @@ import PromptAreaComponent from "../../../../components/promptComponent";
|
|||
import TextAreaComponent from "../../../../components/textAreaComponent";
|
||||
import ToggleShadComponent from "../../../../components/toggleShadComponent";
|
||||
import { Button } from "../../../../components/ui/button";
|
||||
import { TOOLTIP_EMPTY } from "../../../../constants/constants";
|
||||
import {
|
||||
LANGFLOW_SUPPORTED_TYPES,
|
||||
TOOLTIP_EMPTY,
|
||||
} from "../../../../constants/constants";
|
||||
import { alertContext } from "../../../../contexts/alertContext";
|
||||
import { FlowsContext } from "../../../../contexts/flowsContext";
|
||||
import { typesContext } from "../../../../contexts/typesContext";
|
||||
import { undoRedoContext } from "../../../../contexts/undoRedoContext";
|
||||
import { postCustomComponentUpdate } from "../../../../controllers/API";
|
||||
import { ParameterComponentType } from "../../../../types/components";
|
||||
import { NodeDataType } from "../../../../types/flow";
|
||||
import {
|
||||
convertObjToArray,
|
||||
convertValuesToNumbers,
|
||||
|
|
@ -59,6 +65,7 @@ export default function ParameterComponent({
|
|||
const ref = useRef<HTMLDivElement>(null);
|
||||
const refHtml = useRef<HTMLDivElement & ReactNode>(null);
|
||||
const infoHtml = useRef<HTMLDivElement & ReactNode>(null);
|
||||
const { setErrorData } = useContext(alertContext);
|
||||
const updateNodeInternals = useUpdateNodeInternals();
|
||||
const [position, setPosition] = useState(0);
|
||||
const { setTabsState, tabId, flows } = useContext(FlowsContext);
|
||||
|
|
@ -93,6 +100,25 @@ export default function ParameterComponent({
|
|||
|
||||
const { takeSnapshot } = useContext(undoRedoContext);
|
||||
|
||||
const handleUpdateValues = async (name: string, data: NodeDataType) => {
|
||||
const code = data.node?.template["code"]?.value;
|
||||
if (!code) {
|
||||
console.error("Code not found in the template");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const res = await postCustomComponentUpdate(code, name);
|
||||
if (res.status === 200 && data.node?.template) {
|
||||
let clone = cloneDeep(data);
|
||||
clone.node!.template[name] = res.data.template[name];
|
||||
setData(clone);
|
||||
}
|
||||
} catch (err) {
|
||||
setErrorData(err as { title: string; list?: Array<string> });
|
||||
}
|
||||
};
|
||||
|
||||
const handleOnNewValue = (
|
||||
newValue: string | string[] | boolean | Object[]
|
||||
): void => {
|
||||
|
|
@ -222,17 +248,7 @@ export default function ParameterComponent({
|
|||
}, [tooltipTitle, flow]);
|
||||
|
||||
return !showNode ? (
|
||||
left &&
|
||||
(type === "str" ||
|
||||
type === "bool" ||
|
||||
type === "float" ||
|
||||
type === "code" ||
|
||||
type === "prompt" ||
|
||||
type === "file" ||
|
||||
type === "int" ||
|
||||
type === "dict" ||
|
||||
type === "NestedDict") &&
|
||||
!optionalHandle ? (
|
||||
left && LANGFLOW_SUPPORTED_TYPES.has(type ?? "") && !optionalHandle ? (
|
||||
<></>
|
||||
) : (
|
||||
<Button className="h-7 truncate bg-muted p-0 text-sm font-normal text-black hover:bg-muted">
|
||||
|
|
@ -305,17 +321,7 @@ export default function ParameterComponent({
|
|||
)}
|
||||
</div>
|
||||
</div>
|
||||
{left &&
|
||||
(type === "str" ||
|
||||
type === "bool" ||
|
||||
type === "float" ||
|
||||
type === "code" ||
|
||||
type === "prompt" ||
|
||||
type === "file" ||
|
||||
type === "int" ||
|
||||
type === "dict" ||
|
||||
type === "NestedDict") &&
|
||||
!optionalHandle ? (
|
||||
{left && LANGFLOW_SUPPORTED_TYPES.has(type ?? "") && !optionalHandle ? (
|
||||
<></>
|
||||
) : (
|
||||
<Button className="h-7 truncate bg-muted p-0 text-sm font-normal text-black hover:bg-muted">
|
||||
|
|
@ -409,12 +415,26 @@ export default function ParameterComponent({
|
|||
) : left === true &&
|
||||
type === "str" &&
|
||||
data.node?.template[name].options ? (
|
||||
<div className="mt-2 w-full">
|
||||
<Dropdown
|
||||
options={data.node.template[name].options}
|
||||
onSelect={handleOnNewValue}
|
||||
value={data.node.template[name].value ?? "Choose an option"}
|
||||
></Dropdown>
|
||||
// TODO: Improve CSS
|
||||
<div className="mt-2 flex w-full items-center">
|
||||
<div className="w-5/6 flex-grow">
|
||||
<Dropdown
|
||||
options={data.node.template[name].options}
|
||||
onSelect={handleOnNewValue}
|
||||
value={data.node.template[name].value ?? "Choose an option"}
|
||||
id={"dropdown-" + index}
|
||||
/>
|
||||
</div>
|
||||
{data.node?.template[name].refresh && (
|
||||
<button
|
||||
className="extra-side-bar-buttons ml-2 mt-1 w-1/6"
|
||||
onClick={() => {
|
||||
handleUpdateValues(name, data);
|
||||
}}
|
||||
>
|
||||
<IconComponent name="RefreshCcw" />
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
) : left === true && type === "code" ? (
|
||||
<div className="mt-2 w-full">
|
||||
|
|
@ -491,6 +511,7 @@ export default function ParameterComponent({
|
|||
data.node!.template[name].value = newValue;
|
||||
handleOnNewValue(newValue);
|
||||
}}
|
||||
id="div-dict-input"
|
||||
/>
|
||||
</div>
|
||||
) : left === true && type === "dict" ? (
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ export default function GenericNode({
|
|||
const { types, deleteNode, reactFlowInstance, setFilterEdge, getFilterEdge } =
|
||||
useContext(typesContext);
|
||||
const name = nodeIconsLucide[data.type] ? data.type : types[data.type];
|
||||
const [inputName, setInputName] = useState(true);
|
||||
const [inputName, setInputName] = useState(false);
|
||||
const [nodeName, setNodeName] = useState(data.node!.display_name);
|
||||
const [inputDescription, setInputDescription] = useState(false);
|
||||
const [nodeDescription, setNodeDescription] = useState(
|
||||
|
|
@ -206,13 +206,21 @@ export default function GenericNode({
|
|||
) : (
|
||||
<ShadTooltip content={data.node?.display_name}>
|
||||
<div
|
||||
className="generic-node-tooltip-div text-primary"
|
||||
className="flex"
|
||||
onDoubleClick={() => {
|
||||
setInputName(true);
|
||||
takeSnapshot();
|
||||
}}
|
||||
>
|
||||
{data.node?.display_name}
|
||||
<div className="generic-node-tooltip-div pr-3 text-primary">
|
||||
{data.node?.display_name}
|
||||
</div>
|
||||
{data.node?.flow && (
|
||||
<IconComponent
|
||||
name="Pencil"
|
||||
className="h-5 w-5 text-primary-content"
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</ShadTooltip>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ const SanitizedHTMLWrapper = ({
|
|||
|
||||
return (
|
||||
<div
|
||||
data-testid="edit-prompt-sanitized"
|
||||
className={className}
|
||||
dangerouslySetInnerHTML={{ __html: sanitizedHTML }}
|
||||
suppressContentEditableWarning={suppressWarning}
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ export default function CodeAreaComponent({
|
|||
<div className="flex w-full items-center">
|
||||
<span
|
||||
id={id}
|
||||
data-testid={id}
|
||||
className={
|
||||
editNode
|
||||
? "input-edit-node input-dialog"
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ import {
|
|||
TabsList,
|
||||
TabsTrigger,
|
||||
} from "../../components/ui/tabs";
|
||||
import { LANGFLOW_SUPPORTED_TYPES } from "../../constants/constants";
|
||||
import { darkContext } from "../../contexts/darkContext";
|
||||
import { typesContext } from "../../contexts/typesContext";
|
||||
import { codeTabsPropsType } from "../../types/components";
|
||||
|
|
@ -242,24 +243,10 @@ export default function CodeTabsComponent({
|
|||
templateField.charAt(0) !== "_" &&
|
||||
node.data.node.template[templateField]
|
||||
.show &&
|
||||
(node.data.node.template[templateField]
|
||||
.type === "str" ||
|
||||
LANGFLOW_SUPPORTED_TYPES.has(
|
||||
node.data.node.template[templateField]
|
||||
.type === "bool" ||
|
||||
node.data.node.template[templateField]
|
||||
.type === "float" ||
|
||||
node.data.node.template[templateField]
|
||||
.type === "code" ||
|
||||
node.data.node.template[templateField]
|
||||
.type === "prompt" ||
|
||||
node.data.node.template[templateField]
|
||||
.type === "file" ||
|
||||
node.data.node.template[templateField]
|
||||
.type === "int" ||
|
||||
node.data.node.template[templateField]
|
||||
.type === "dict" ||
|
||||
node.data.node.template[templateField]
|
||||
.type === "NestedDict")
|
||||
.type
|
||||
)
|
||||
)
|
||||
.map((templateField, indx) => {
|
||||
return (
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ export default function DictComponent({
|
|||
onChange,
|
||||
disabled,
|
||||
editNode = false,
|
||||
id = "",
|
||||
}: DictComponentType): JSX.Element {
|
||||
useEffect(() => {
|
||||
if (disabled) {
|
||||
|
|
@ -30,7 +31,7 @@ export default function DictComponent({
|
|||
)}
|
||||
>
|
||||
{
|
||||
<div className="flex w-full gap-3">
|
||||
<div className="flex w-full gap-3" data-testid={id}>
|
||||
<DictAreaModal
|
||||
value={ref.current}
|
||||
onChange={(obj) => {
|
||||
|
|
@ -45,6 +46,7 @@ export default function DictComponent({
|
|||
: "input-disable pointer-events-none cursor-pointer"
|
||||
}
|
||||
placeholder="Click to edit your dictionary..."
|
||||
data-testid="dict-input"
|
||||
/>
|
||||
</DictAreaModal>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ export default function Dropdown({
|
|||
editNode = false,
|
||||
numberOfOptions = 0,
|
||||
apiModal = false,
|
||||
id = "",
|
||||
}: DropDownComponentType): JSX.Element {
|
||||
let [internalValue, setInternalValue] = useState(
|
||||
value === "" || !value ? "Choose an option" : value
|
||||
|
|
@ -31,15 +32,19 @@ export default function Dropdown({
|
|||
>
|
||||
{({ open }) => (
|
||||
<>
|
||||
<div className={editNode ? "mt-1" : "relative mt-1"}>
|
||||
<div className={"relative mt-1"}>
|
||||
<Listbox.Button
|
||||
data-test={`${id ?? ""}`}
|
||||
className={
|
||||
editNode
|
||||
? "dropdown-component-outline"
|
||||
: "dropdown-component-false-outline"
|
||||
}
|
||||
>
|
||||
<span className="dropdown-component-display">
|
||||
<span
|
||||
className="dropdown-component-display"
|
||||
data-testid={`${id ?? ""}-display`}
|
||||
>
|
||||
{internalValue}
|
||||
</span>
|
||||
<span className={"dropdown-component-arrow"}>
|
||||
|
|
@ -63,7 +68,7 @@ export default function Dropdown({
|
|||
editNode
|
||||
? "dropdown-component-true-options nowheel custom-scroll"
|
||||
: "dropdown-component-false-options nowheel custom-scroll",
|
||||
apiModal ? "mb-2 w-[250px]" : "absolute"
|
||||
apiModal ? "mb-2 w-[250px]" : "absolute w-full"
|
||||
)}
|
||||
>
|
||||
{options.map((option, id) => (
|
||||
|
|
@ -86,6 +91,7 @@ export default function Dropdown({
|
|||
selected ? "font-semibold" : "font-normal",
|
||||
"block truncate "
|
||||
)}
|
||||
data-testid={`${option}-${id ?? ""}-option`}
|
||||
>
|
||||
{option}
|
||||
</span>
|
||||
|
|
|
|||
|
|
@ -3,7 +3,10 @@ import { IconComponentProps } from "../../types/components";
|
|||
import { nodeIconsLucide } from "../../utils/styleUtils";
|
||||
|
||||
const ForwardedIconComponent = forwardRef(
|
||||
({ name, className, iconColor, stroke }: IconComponentProps, ref) => {
|
||||
(
|
||||
{ name, className, iconColor, stroke, id = "" }: IconComponentProps,
|
||||
ref
|
||||
) => {
|
||||
const TargetIcon = nodeIconsLucide[name] ?? nodeIconsLucide["unknown"];
|
||||
return (
|
||||
<TargetIcon
|
||||
|
|
@ -12,6 +15,7 @@ const ForwardedIconComponent = forwardRef(
|
|||
style={iconColor ? { color: iconColor } : {}}
|
||||
ref={ref}
|
||||
stroke={stroke ? stroke : "currentColor"}
|
||||
data-testid={id ? `${id}-${name}` : "icon-" + name}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ export default function KeypairListComponent({
|
|||
return (
|
||||
<div key={idx} className="flex w-full gap-2">
|
||||
<Input
|
||||
id={"keypair" + index}
|
||||
id={editNode ? "editNodekeypair" + index : "keypair" + index}
|
||||
type="text"
|
||||
value={key.trim()}
|
||||
className={classNames(
|
||||
|
|
@ -71,7 +71,11 @@ export default function KeypairListComponent({
|
|||
/>
|
||||
|
||||
<Input
|
||||
id={"keypair" + (index + 100).toString()}
|
||||
id={
|
||||
editNode
|
||||
? "editNodekeypair" + (index + 100).toString()
|
||||
: "keypair" + (index + 100).toString()
|
||||
}
|
||||
type="text"
|
||||
value={obj[key]}
|
||||
className={editNode ? "input-edit-node" : ""}
|
||||
|
|
@ -88,7 +92,11 @@ export default function KeypairListComponent({
|
|||
newInputList.push({ "": "" });
|
||||
onChange(newInputList);
|
||||
}}
|
||||
id={"plusbtn" + index.toString()}
|
||||
id={
|
||||
editNode
|
||||
? "editNodeplusbtn" + index.toString()
|
||||
: "plusbtn" + index.toString()
|
||||
}
|
||||
>
|
||||
<IconComponent
|
||||
name="Plus"
|
||||
|
|
@ -102,7 +110,11 @@ export default function KeypairListComponent({
|
|||
newInputList.splice(index, 1);
|
||||
onChange(newInputList);
|
||||
}}
|
||||
id={"minusbtn" + index.toString()}
|
||||
id={
|
||||
editNode
|
||||
? "editNodeminusbtn" + index.toString()
|
||||
: "minusbtn" + index.toString()
|
||||
}
|
||||
>
|
||||
<IconComponent
|
||||
name="X"
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@ export default function PromptAreaComponent({
|
|||
<div className="flex w-full items-center">
|
||||
<span
|
||||
id={id}
|
||||
data-testid={id}
|
||||
className={
|
||||
editNode
|
||||
? "input-edit-node input-dialog"
|
||||
|
|
@ -64,6 +65,7 @@ export default function PromptAreaComponent({
|
|||
</span>
|
||||
{!editNode && (
|
||||
<IconComponent
|
||||
id={id}
|
||||
name="ExternalLink"
|
||||
className={
|
||||
"icons-parameters-comp" +
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ export default function TextAreaComponent({
|
|||
/>
|
||||
{!editNode && (
|
||||
<IconComponent
|
||||
id={id}
|
||||
name="ExternalLink"
|
||||
className={
|
||||
"icons-parameters-comp" +
|
||||
|
|
|
|||
|
|
@ -663,3 +663,15 @@ export const LAST_USED_SPAN_1 = "The last time this key was used.";
|
|||
|
||||
export const LAST_USED_SPAN_2 =
|
||||
"Accurate to within the hour from the most recent usage.";
|
||||
|
||||
export const LANGFLOW_SUPPORTED_TYPES = new Set([
|
||||
"str",
|
||||
"bool",
|
||||
"float",
|
||||
"code",
|
||||
"prompt",
|
||||
"file",
|
||||
"int",
|
||||
"dict",
|
||||
"NestedDict",
|
||||
]);
|
||||
|
|
|
|||
|
|
@ -56,7 +56,11 @@ const FlowsContextInitialValue: FlowsContextType = {
|
|||
isLoading: true,
|
||||
flows: [],
|
||||
removeFlow: (id: string) => {},
|
||||
addFlow: async (newProject: boolean, flowData?: FlowType) => "",
|
||||
addFlow: async (
|
||||
newProject: boolean,
|
||||
flowData?: FlowType,
|
||||
override?: boolean
|
||||
) => "",
|
||||
updateFlow: (newFlow: FlowType) => {},
|
||||
incrementNodeId: () => uid(),
|
||||
downloadFlow: (flow: FlowType) => {},
|
||||
|
|
@ -78,7 +82,7 @@ const FlowsContextInitialValue: FlowsContextType = {
|
|||
selection: { nodes: any; edges: any },
|
||||
position: { x: number; y: number; paneX?: number; paneY?: number }
|
||||
) => {},
|
||||
saveComponent: async (component: NodeDataType) => "",
|
||||
saveComponent: async (component: NodeDataType, override: boolean) => "",
|
||||
deleteComponent: (key: string) => {},
|
||||
version: "",
|
||||
};
|
||||
|
|
@ -496,7 +500,8 @@ export function FlowsProvider({ children }: { children: ReactNode }) {
|
|||
|
||||
const addFlow = async (
|
||||
newProject: Boolean,
|
||||
flow?: FlowType
|
||||
flow?: FlowType,
|
||||
override?: boolean
|
||||
): Promise<String | undefined> => {
|
||||
if (newProject) {
|
||||
let flowData = flow
|
||||
|
|
@ -505,6 +510,15 @@ export function FlowsProvider({ children }: { children: ReactNode }) {
|
|||
|
||||
// Create a new flow with a default name if no flow is provided.
|
||||
|
||||
if (override) {
|
||||
deleteComponent(flow!.name);
|
||||
const newFlow = createNewFlow(flowData, flow!);
|
||||
const { id } = await saveFlowToDatabase(newFlow);
|
||||
newFlow.id = id;
|
||||
addFlowToLocalState(newFlow);
|
||||
return;
|
||||
}
|
||||
|
||||
const newFlow = createNewFlow(flowData, flow!);
|
||||
|
||||
const newName = addVersionToDuplicates(newFlow, flows);
|
||||
|
|
@ -595,14 +609,16 @@ export function FlowsProvider({ children }: { children: ReactNode }) {
|
|||
newFlows[index].data = newFlow.data;
|
||||
newFlows[index].name = newFlow.name;
|
||||
}
|
||||
newFlow = {
|
||||
...newFlow,
|
||||
};
|
||||
return newFlows;
|
||||
});
|
||||
}
|
||||
|
||||
async function saveFlow(newFlow: FlowType, silent?: boolean) {
|
||||
console.log(newFlow);
|
||||
|
||||
if (newFlow?.data?.nodes?.length === 0) return;
|
||||
|
||||
try {
|
||||
// updates flow in db
|
||||
const updatedFlow = await updateFlowInDatabase(newFlow);
|
||||
|
|
@ -615,14 +631,10 @@ export function FlowsProvider({ children }: { children: ReactNode }) {
|
|||
const newFlows = [...prevState];
|
||||
const index = newFlows.findIndex((flow) => flow.id === newFlow.id);
|
||||
if (index !== -1) {
|
||||
newFlows[index] = {
|
||||
...newFlows[index],
|
||||
description: updatedFlow.description,
|
||||
data: updatedFlow.data,
|
||||
name: updatedFlow.name,
|
||||
};
|
||||
newFlows[index].description = newFlow.description ?? "";
|
||||
newFlows[index].data = newFlow.data;
|
||||
newFlows[index].name = newFlow.name;
|
||||
}
|
||||
|
||||
return newFlows;
|
||||
});
|
||||
//update tabs state
|
||||
|
|
@ -644,9 +656,9 @@ export function FlowsProvider({ children }: { children: ReactNode }) {
|
|||
}
|
||||
}
|
||||
|
||||
function saveComponent(component: NodeDataType) {
|
||||
function saveComponent(component: NodeDataType, override: boolean) {
|
||||
component.node!.official = false;
|
||||
return addFlow(true, createFlowComponent(component, version));
|
||||
return addFlow(true, createFlowComponent(component, version), override);
|
||||
}
|
||||
|
||||
function deleteComponent(key: string) {
|
||||
|
|
|
|||
|
|
@ -360,6 +360,16 @@ export async function postCustomComponent(
|
|||
return await api.post(`${BASE_URL_API}custom_component`, { code });
|
||||
}
|
||||
|
||||
export async function postCustomComponentUpdate(
|
||||
code: string,
|
||||
field: string
|
||||
): Promise<AxiosResponse<APIClassType>> {
|
||||
return await api.post(`${BASE_URL_API}custom_component/update`, {
|
||||
code,
|
||||
field,
|
||||
});
|
||||
}
|
||||
|
||||
export async function onLogin(user: LoginType) {
|
||||
try {
|
||||
const response = await api.post(
|
||||
|
|
|
|||
|
|
@ -13,7 +13,10 @@ import {
|
|||
// import "ace-builds/webpack-resolver";
|
||||
import CodeTabsComponent from "../../components/codeTabsComponent";
|
||||
import IconComponent from "../../components/genericIconComponent";
|
||||
import { EXPORT_CODE_DIALOG } from "../../constants/constants";
|
||||
import {
|
||||
EXPORT_CODE_DIALOG,
|
||||
LANGFLOW_SUPPORTED_TYPES,
|
||||
} from "../../constants/constants";
|
||||
import { AuthContext } from "../../contexts/authContext";
|
||||
import { FlowsContext } from "../../contexts/flowsContext";
|
||||
import { TemplateVariableType } from "../../types/api";
|
||||
|
|
@ -99,15 +102,9 @@ const ApiModal = forwardRef(
|
|||
(templateField) =>
|
||||
templateField.charAt(0) !== "_" &&
|
||||
node.data.node.template[templateField].show &&
|
||||
(node.data.node.template[templateField].type === "str" ||
|
||||
node.data.node.template[templateField].type === "bool" ||
|
||||
node.data.node.template[templateField].type === "float" ||
|
||||
node.data.node.template[templateField].type === "code" ||
|
||||
node.data.node.template[templateField].type === "prompt" ||
|
||||
node.data.node.template[templateField].type === "file" ||
|
||||
node.data.node.template[templateField].type === "int" ||
|
||||
node.data.node.template[templateField].type === "dict" ||
|
||||
node.data.node.template[templateField].type === "NestedDict")
|
||||
LANGFLOW_SUPPORTED_TYPES.has(
|
||||
node.data.node.template[templateField].type
|
||||
)
|
||||
)
|
||||
.map((n, i) => {
|
||||
arrNodesWithValues.push(node["id"]);
|
||||
|
|
@ -146,9 +143,9 @@ const ApiModal = forwardRef(
|
|||
);
|
||||
|
||||
if (existingTweak) {
|
||||
existingTweak[tw][template["name"]] = changes as string;
|
||||
existingTweak[tw][template["name"]!] = changes as string;
|
||||
|
||||
if (existingTweak[tw][template["name"]] == template.value) {
|
||||
if (existingTweak[tw][template["name"]!] == template.value) {
|
||||
tweak.current.forEach((element) => {
|
||||
if (element[tw] && Object.keys(element[tw])?.length === 0) {
|
||||
tweak.current = tweak.current.filter((obj) => {
|
||||
|
|
@ -161,7 +158,7 @@ const ApiModal = forwardRef(
|
|||
} else {
|
||||
const newTweak = {
|
||||
[tw]: {
|
||||
[template["name"]]: changes,
|
||||
[template["name"]!]: changes,
|
||||
},
|
||||
} as uniqueTweakType;
|
||||
tweak.current.push(newTweak);
|
||||
|
|
|
|||
|
|
@ -36,10 +36,15 @@ function ConfirmationModal({
|
|||
size,
|
||||
open,
|
||||
onClose,
|
||||
onCancel,
|
||||
}: ConfirmationModalType) {
|
||||
const Icon: any = nodeIconsLucide[icon];
|
||||
const [modalOpen, setModalOpen] = useState(open ?? false);
|
||||
|
||||
useEffect(() => {
|
||||
if (open) setModalOpen(open);
|
||||
}, [open]);
|
||||
|
||||
useEffect(() => {
|
||||
if (onClose) onClose!(modalOpen);
|
||||
}, [modalOpen]);
|
||||
|
|
@ -86,6 +91,7 @@ function ConfirmationModal({
|
|||
className="mt-5"
|
||||
variant="outline"
|
||||
onClick={() => {
|
||||
if (onCancel) onCancel();
|
||||
setModalOpen(false);
|
||||
}}
|
||||
>
|
||||
|
|
|
|||
|
|
@ -25,7 +25,10 @@ import {
|
|||
TableHeader,
|
||||
TableRow,
|
||||
} from "../../components/ui/table";
|
||||
import { limitScrollFieldsModal } from "../../constants/constants";
|
||||
import {
|
||||
LANGFLOW_SUPPORTED_TYPES,
|
||||
limitScrollFieldsModal,
|
||||
} from "../../constants/constants";
|
||||
import { FlowsContext } from "../../contexts/flowsContext";
|
||||
import { typesContext } from "../../contexts/typesContext";
|
||||
import { NodeDataType } from "../../types/flow";
|
||||
|
|
@ -123,7 +126,7 @@ const EditNodeModal = forwardRef(
|
|||
"edit-node-modal-box",
|
||||
nodeLength > limitScrollFieldsModal
|
||||
? "overflow-scroll overflow-x-hidden custom-scroll"
|
||||
: "overflow-hidden"
|
||||
: ""
|
||||
)}
|
||||
>
|
||||
{nodeLength > 0 && (
|
||||
|
|
@ -144,24 +147,9 @@ const EditNodeModal = forwardRef(
|
|||
(templateParam) =>
|
||||
templateParam.charAt(0) !== "_" &&
|
||||
myData.node?.template[templateParam].show &&
|
||||
(myData.node.template[templateParam]
|
||||
.type === "str" ||
|
||||
myData.node.template[templateParam]
|
||||
.type === "bool" ||
|
||||
myData.node.template[templateParam]
|
||||
.type === "float" ||
|
||||
myData.node.template[templateParam]
|
||||
.type === "code" ||
|
||||
myData.node.template[templateParam]
|
||||
.type === "prompt" ||
|
||||
myData.node.template[templateParam]
|
||||
.type === "file" ||
|
||||
myData.node.template[templateParam]
|
||||
.type === "int" ||
|
||||
myData.node.template[templateParam]
|
||||
.type === "dict" ||
|
||||
myData.node.template[templateParam]
|
||||
.type === "NestedDict")
|
||||
LANGFLOW_SUPPORTED_TYPES.has(
|
||||
myData.node.template[templateParam].type
|
||||
)
|
||||
)
|
||||
.map((templateParam, index) => (
|
||||
<TableRow key={index} className="h-10">
|
||||
|
|
@ -261,7 +249,7 @@ const EditNodeModal = forwardRef(
|
|||
value={
|
||||
myData.node!.template[
|
||||
templateParam
|
||||
].value.toString() === "{}"
|
||||
]?.value?.toString() === "{}"
|
||||
? {
|
||||
yourkey: "value",
|
||||
}
|
||||
|
|
@ -275,6 +263,7 @@ const EditNodeModal = forwardRef(
|
|||
].value = newValue;
|
||||
handleOnNewValue(newValue, templateParam);
|
||||
}}
|
||||
id="editnode-div-dict-input"
|
||||
/>
|
||||
</div>
|
||||
) : myData.node?.template[templateParam]
|
||||
|
|
@ -380,6 +369,7 @@ const EditNodeModal = forwardRef(
|
|||
templateParam
|
||||
].value ?? "Choose an option"
|
||||
}
|
||||
id={"dropdown-edit-" + index}
|
||||
></Dropdown>
|
||||
</div>
|
||||
) : myData.node?.template[templateParam]
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@ export default function DictAreaModal({
|
|||
/>
|
||||
<div className="flex h-fit w-full justify-end">
|
||||
<Button
|
||||
data-testid="save-dict-button"
|
||||
className="mt-3"
|
||||
type="submit"
|
||||
onClick={() => {
|
||||
|
|
|
|||
|
|
@ -213,6 +213,7 @@ export default function GenericModal({
|
|||
{type === TypeModal.PROMPT && isEdit && !readonly ? (
|
||||
<Textarea
|
||||
id={"modal-" + id}
|
||||
data-testid={"modal-" + id}
|
||||
ref={divRefPrompt}
|
||||
className="form-input h-full w-full rounded-lg custom-scroll focus-visible:ring-1"
|
||||
value={inputValue}
|
||||
|
|
@ -252,6 +253,8 @@ export default function GenericModal({
|
|||
handleKeyDown(e, value, "");
|
||||
}}
|
||||
readOnly={readonly}
|
||||
id={"text-area-modal"}
|
||||
data-testid={"text-area-modal"}
|
||||
/>
|
||||
) : (
|
||||
<></>
|
||||
|
|
@ -308,6 +311,7 @@ export default function GenericModal({
|
|||
)}
|
||||
</div>
|
||||
<Button
|
||||
data-testid="genericModalBtnSave"
|
||||
id="genericModalBtnSave"
|
||||
disabled={readonly}
|
||||
onClick={() => {
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import { Button } from "../../components/ui/button";
|
|||
import { Checkbox } from "../../components/ui/checkbox";
|
||||
import { alertContext } from "../../contexts/alertContext";
|
||||
import { FlowsContext } from "../../contexts/flowsContext";
|
||||
import { StoreContext } from "../../contexts/storeContext";
|
||||
import {
|
||||
getStoreComponents,
|
||||
getStoreTags,
|
||||
|
|
@ -22,14 +23,17 @@ export default function ShareModal({
|
|||
children,
|
||||
open,
|
||||
setOpen,
|
||||
disabled,
|
||||
}: {
|
||||
children?: ReactNode;
|
||||
is_component: boolean;
|
||||
component: FlowType;
|
||||
open?: boolean;
|
||||
setOpen?: (open: boolean) => void;
|
||||
disabled?: boolean;
|
||||
}): JSX.Element {
|
||||
const { version, addFlow } = useContext(FlowsContext);
|
||||
const { hasApiKey } = useContext(StoreContext);
|
||||
const { setSuccessData, setErrorData } = useContext(alertContext);
|
||||
const [checked, setChecked] = useState(true);
|
||||
const [name, setName] = useState(component?.name ?? "");
|
||||
|
|
@ -46,10 +50,12 @@ export default function ShareModal({
|
|||
|
||||
useEffect(() => {
|
||||
if (open || internalOpen) {
|
||||
handleGetTags();
|
||||
handleGetNames();
|
||||
if (hasApiKey) {
|
||||
handleGetTags();
|
||||
handleGetNames();
|
||||
}
|
||||
}
|
||||
}, [open, internalOpen]);
|
||||
}, [open, internalOpen, hasApiKey]);
|
||||
|
||||
function handleGetTags() {
|
||||
setLoadingTags(true);
|
||||
|
|
@ -113,7 +119,7 @@ export default function ShareModal({
|
|||
return (
|
||||
<BaseModal
|
||||
size="smaller-h-full"
|
||||
open={open ?? internalOpen}
|
||||
open={(!disabled && open) ?? internalOpen}
|
||||
setOpen={setOpen ?? internalSetOpen}
|
||||
>
|
||||
<BaseModal.Trigger>{children ? children : <></>}</BaseModal.Trigger>
|
||||
|
|
|
|||
|
|
@ -70,6 +70,7 @@ export default function Page({
|
|||
saveFlow,
|
||||
setTabsState,
|
||||
tabId,
|
||||
flows,
|
||||
} = useContext(FlowsContext);
|
||||
const {
|
||||
types,
|
||||
|
|
@ -144,7 +145,6 @@ export default function Page({
|
|||
document.removeEventListener("mousemove", handleMouseMove);
|
||||
};
|
||||
}, [position, lastCopiedSelection, lastSelection]);
|
||||
|
||||
const [selectionMenuVisible, setSelectionMenuVisible] = useState(false);
|
||||
|
||||
const { setExtraComponent, setExtraNavigation } = useContext(locationContext);
|
||||
|
|
@ -181,6 +181,8 @@ export default function Page({
|
|||
const [seconds, setSeconds] = useState(0);
|
||||
|
||||
useEffect(() => {
|
||||
const index = flows.findIndex((flowId) => flowId.id === flow.id);
|
||||
|
||||
const interval = setInterval(() => {
|
||||
setSeconds((prevSeconds) => {
|
||||
let updatedSeconds = prevSeconds + 1;
|
||||
|
|
@ -188,7 +190,7 @@ export default function Page({
|
|||
if (updatedSeconds % 30 === 0) {
|
||||
saveFlow(
|
||||
{
|
||||
...flow!,
|
||||
...flows[index]!,
|
||||
data: reactFlowInstance
|
||||
? reactFlowInstance!.toObject()
|
||||
: flow!.data,
|
||||
|
|
@ -318,9 +320,9 @@ export default function Page({
|
|||
);
|
||||
|
||||
// Calculate the position where the node should be created
|
||||
const position = reactFlowInstance!.project({
|
||||
x: event.clientX - reactflowBounds!.left,
|
||||
y: event.clientY - reactflowBounds!.top,
|
||||
const position = reactFlowInstance!.screenToFlowPosition({
|
||||
x: event.clientX,
|
||||
y: event.clientY,
|
||||
});
|
||||
|
||||
// Generate a unique node ID
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import { Input } from "../../../../components/ui/input";
|
|||
import { Separator } from "../../../../components/ui/separator";
|
||||
import { alertContext } from "../../../../contexts/alertContext";
|
||||
import { FlowsContext } from "../../../../contexts/flowsContext";
|
||||
import { StoreContext } from "../../../../contexts/storeContext";
|
||||
import { typesContext } from "../../../../contexts/typesContext";
|
||||
import ApiModal from "../../../../modals/ApiModal";
|
||||
import ExportModal from "../../../../modals/exportModal";
|
||||
|
|
@ -29,6 +30,7 @@ export default function ExtraSidebar(): JSX.Element {
|
|||
useContext(typesContext);
|
||||
const { flows, tabId, uploadFlow, tabsState, saveFlow, isBuilt, version } =
|
||||
useContext(FlowsContext);
|
||||
const { hasApiKey, validApiKey } = useContext(StoreContext);
|
||||
const { setErrorData } = useContext(alertContext);
|
||||
const [dataFilter, setFilterData] = useState(data);
|
||||
const [search, setSearch] = useState("");
|
||||
|
|
@ -179,25 +181,56 @@ export default function ExtraSidebar(): JSX.Element {
|
|||
}, [getFilterEdge, data]);
|
||||
|
||||
const ModalMemo = useMemo(
|
||||
() => (
|
||||
<ShareModal is_component={false} component={flow!}>
|
||||
<ShadTooltip content="Share" side="top">
|
||||
<div className={classNames("extra-side-bar-buttons")}>
|
||||
<IconComponent name="Share2" className="side-bar-button-size" />
|
||||
</div>
|
||||
</ShadTooltip>
|
||||
</ShareModal>
|
||||
),
|
||||
[]
|
||||
() =>
|
||||
!hasApiKey || !validApiKey ? (
|
||||
<button
|
||||
disabled={!hasApiKey || !validApiKey}
|
||||
className={classNames(
|
||||
"extra-side-bar-buttons",
|
||||
!hasApiKey || !validApiKey ? "button-disable cursor-default" : ""
|
||||
)}
|
||||
>
|
||||
<IconComponent
|
||||
name="Share2"
|
||||
className={classNames(
|
||||
"side-bar-button-size",
|
||||
!hasApiKey || !validApiKey ? "extra-side-bar-save-disable" : ""
|
||||
)}
|
||||
/>
|
||||
</button>
|
||||
) : (
|
||||
<ShareModal
|
||||
is_component={false}
|
||||
component={flow!}
|
||||
disabled={!hasApiKey || !validApiKey}
|
||||
>
|
||||
<button
|
||||
disabled={!hasApiKey || !validApiKey}
|
||||
className={classNames(
|
||||
"extra-side-bar-buttons",
|
||||
!hasApiKey || !validApiKey ? "button-disable cursor-default" : ""
|
||||
)}
|
||||
>
|
||||
<IconComponent
|
||||
name="Share2"
|
||||
className={classNames(
|
||||
"side-bar-button-size",
|
||||
!hasApiKey || !validApiKey ? "extra-side-bar-save-disable" : ""
|
||||
)}
|
||||
/>
|
||||
</button>
|
||||
</ShareModal>
|
||||
),
|
||||
[hasApiKey, validApiKey]
|
||||
);
|
||||
|
||||
const ExportMemo = useMemo(
|
||||
() => (
|
||||
<ExportModal>
|
||||
<ShadTooltip content="Export" side="top">
|
||||
<div className={classNames("extra-side-bar-buttons")}>
|
||||
<button className={classNames("extra-side-bar-buttons")}>
|
||||
<IconComponent name="FileDown" className="side-bar-button-size" />
|
||||
</div>
|
||||
</button>
|
||||
</ShadTooltip>
|
||||
</ExportModal>
|
||||
),
|
||||
|
|
@ -276,8 +309,9 @@ export default function ExtraSidebar(): JSX.Element {
|
|||
</div>
|
||||
</ShadTooltip>
|
||||
</div>
|
||||
|
||||
<div className="side-bar-button">{ModalMemo}</div>
|
||||
<ShadTooltip content="Share" side="top" styleClasses="cursor-default">
|
||||
<div className="side-bar-button">{ModalMemo}</div>
|
||||
</ShadTooltip>
|
||||
</div>
|
||||
<Separator />
|
||||
<div className="side-bar-search-div-placement">
|
||||
|
|
@ -305,7 +339,15 @@ export default function ExtraSidebar(): JSX.Element {
|
|||
|
||||
<div className="side-bar-components-div-arrangement">
|
||||
{Object.keys(dataFilter)
|
||||
.sort()
|
||||
.sort((a, b) => {
|
||||
if (a.toLowerCase() === "saved_components") {
|
||||
return -1;
|
||||
} else if (b.toLowerCase() === "saved_components") {
|
||||
return 1;
|
||||
} else {
|
||||
return a.localeCompare(b);
|
||||
}
|
||||
})
|
||||
.map((SBSectionName: keyof APIObjectType, index) =>
|
||||
Object.keys(dataFilter[SBSectionName]).length > 0 ? (
|
||||
<DisclosureComponent
|
||||
|
|
|
|||
|
|
@ -88,17 +88,17 @@ export default function SidebarDraggableComponent({
|
|||
}}
|
||||
>
|
||||
<div
|
||||
data-testid={sectionName + display_name}
|
||||
id={sectionName + display_name}
|
||||
className="side-bar-components-div-form"
|
||||
>
|
||||
<span className="side-bar-components-text">{display_name}</span>
|
||||
<div>
|
||||
<SelectTrigger>
|
||||
<IconComponent
|
||||
name="Menu"
|
||||
className="side-bar-components-icon "
|
||||
/>
|
||||
</SelectTrigger>
|
||||
<IconComponent
|
||||
name="Menu"
|
||||
className="side-bar-components-icon "
|
||||
/>
|
||||
<SelectTrigger></SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value={"download"}>
|
||||
<div className="flex">
|
||||
|
|
|
|||
|
|
@ -10,6 +10,8 @@ import {
|
|||
SelectTrigger,
|
||||
} from "../../../../components/ui/select-custom";
|
||||
import { FlowsContext } from "../../../../contexts/flowsContext";
|
||||
import { StoreContext } from "../../../../contexts/storeContext";
|
||||
import ConfirmationModal from "../../../../modals/ConfirmationModal";
|
||||
import EditNodeModal from "../../../../modals/EditNodeModal";
|
||||
import ShareModal from "../../../../modals/shareModal";
|
||||
import { nodeToolbarPropsType } from "../../../../types/components";
|
||||
|
|
@ -49,6 +51,7 @@ export default function NodeToolbarComponent({
|
|||
);
|
||||
const updateNodeInternals = useUpdateNodeInternals();
|
||||
const { getNodeId } = useContext(FlowsContext);
|
||||
const { hasApiKey, validApiKey } = useContext(StoreContext);
|
||||
|
||||
function canMinimize() {
|
||||
let countHandles: number = 0;
|
||||
|
|
@ -61,17 +64,18 @@ export default function NodeToolbarComponent({
|
|||
const isMinimal = canMinimize();
|
||||
const isGroup = data.node?.flow ? true : false;
|
||||
|
||||
const { paste, saveComponent, version } = useContext(FlowsContext);
|
||||
const { paste, saveComponent, version, flows } = useContext(FlowsContext);
|
||||
const reactFlowInstance = useReactFlow();
|
||||
const [showModalAdvanced, setShowModalAdvanced] = useState(false);
|
||||
const [showconfirmShare, setShowconfirmShare] = useState(false);
|
||||
const [selectedValue, setSelectedValue] = useState("");
|
||||
const [showOverrideModal, setShowOverrideModal] = useState(false);
|
||||
|
||||
const [flowComponent, setFlowComponent] = useState<FlowType>();
|
||||
|
||||
useEffect(() => {
|
||||
setFlowComponent(createFlowComponent(cloneDeep(data), version));
|
||||
}, [data]);
|
||||
}, [data, showModalAdvanced]);
|
||||
|
||||
const handleSelectChange = (event) => {
|
||||
switch (event) {
|
||||
|
|
@ -86,10 +90,10 @@ export default function NodeToolbarComponent({
|
|||
downloadNode(createFlowComponent(cloneDeep(data), version));
|
||||
break;
|
||||
case "Share":
|
||||
setShowconfirmShare(true);
|
||||
if (hasApiKey) setShowconfirmShare(true);
|
||||
break;
|
||||
case "SaveAll":
|
||||
saveComponent(cloneDeep(data));
|
||||
saveComponent(cloneDeep(data), false);
|
||||
break;
|
||||
case "disabled":
|
||||
break;
|
||||
|
|
@ -97,9 +101,16 @@ export default function NodeToolbarComponent({
|
|||
updateFlowPosition(position, data.node?.flow!);
|
||||
expandGroupNode(data, reactFlowInstance, getNodeId);
|
||||
break;
|
||||
case "override":
|
||||
setShowOverrideModal(true);
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
const isSaved = flows.some((flow) =>
|
||||
Object.values(flow).includes(data.node?.display_name!)
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="w-26 h-10">
|
||||
|
|
@ -174,10 +185,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" +
|
||||
(nodeLength == 0
|
||||
? " text-muted-foreground"
|
||||
: " text-foreground")
|
||||
"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
|
||||
|
|
@ -191,7 +199,7 @@ export default function NodeToolbarComponent({
|
|||
<SelectContent>
|
||||
{nodeLength > 0 && (
|
||||
<SelectItem value={nodeLength === 0 ? "disabled" : "advanced"}>
|
||||
<div className="flex">
|
||||
<div className="flex" data-testid="edit-button-modal">
|
||||
<IconComponent
|
||||
name="Settings2"
|
||||
className="relative top-0.5 mr-2 h-4 w-4"
|
||||
|
|
@ -201,16 +209,29 @@ export default function NodeToolbarComponent({
|
|||
</SelectItem>
|
||||
)}
|
||||
|
||||
<SelectItem value={"SaveAll"}>
|
||||
<div className="flex">
|
||||
<IconComponent
|
||||
name="SaveAll"
|
||||
className="relative top-0.5 mr-2 h-4 w-4"
|
||||
/>{" "}
|
||||
Save{" "}
|
||||
</div>{" "}
|
||||
</SelectItem>
|
||||
<SelectItem value={"Share"}>
|
||||
{isSaved ? (
|
||||
<SelectItem value={"override"}>
|
||||
<div className="flex">
|
||||
<IconComponent
|
||||
name="SaveAll"
|
||||
className="relative top-0.5 mr-2 h-4 w-4"
|
||||
/>{" "}
|
||||
Save{" "}
|
||||
</div>{" "}
|
||||
</SelectItem>
|
||||
) : (
|
||||
<SelectItem value={"SaveAll"}>
|
||||
<div className="flex">
|
||||
<IconComponent
|
||||
name="SaveAll"
|
||||
className="relative top-0.5 mr-2 h-4 w-4"
|
||||
/>{" "}
|
||||
Save{" "}
|
||||
</div>{" "}
|
||||
</SelectItem>
|
||||
)}
|
||||
|
||||
<SelectItem disabled={!hasApiKey || !validApiKey} value={"Share"}>
|
||||
<div className="flex">
|
||||
<IconComponent
|
||||
name="Share2"
|
||||
|
|
@ -252,6 +273,33 @@ export default function NodeToolbarComponent({
|
|||
)}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
|
||||
<ConfirmationModal
|
||||
asChild
|
||||
open={showOverrideModal}
|
||||
title={`Replace ${data.node?.display_name}`}
|
||||
titleHeader={`Please, confirm your save actions`}
|
||||
modalContentTitle="Attention!"
|
||||
cancelText="New"
|
||||
confirmationText="Replace"
|
||||
icon={"SaveAll"}
|
||||
index={6}
|
||||
onConfirm={(index, user) => {
|
||||
saveComponent(cloneDeep(data), true);
|
||||
}}
|
||||
onClose={setShowOverrideModal}
|
||||
onCancel={() => saveComponent(cloneDeep(data), false)}
|
||||
>
|
||||
<ConfirmationModal.Content>
|
||||
<span>
|
||||
It seems {data.node?.display_name} already exists. Replacing it
|
||||
will switch the current component. Proceed with replacement?
|
||||
</span>
|
||||
</ConfirmationModal.Content>
|
||||
<ConfirmationModal.Trigger>
|
||||
<></>
|
||||
</ConfirmationModal.Trigger>
|
||||
</ConfirmationModal>
|
||||
<EditNodeModal
|
||||
data={data}
|
||||
nodeLength={nodeLength}
|
||||
|
|
|
|||
|
|
@ -275,8 +275,18 @@ export default function StorePage(): JSX.Element {
|
|||
<SelectContent>
|
||||
<SelectGroup>
|
||||
<SelectItem value="all">All</SelectItem>
|
||||
<SelectItem value="createdbyme">Created By Me</SelectItem>
|
||||
<SelectItem value="likedbyme">Liked By Me</SelectItem>
|
||||
<SelectItem
|
||||
disabled={!hasApiKey || !validApiKey}
|
||||
value="createdbyme"
|
||||
>
|
||||
Created By Me
|
||||
</SelectItem>
|
||||
<SelectItem
|
||||
disabled={!hasApiKey || !validApiKey}
|
||||
value="likedbyme"
|
||||
>
|
||||
Liked By Me
|
||||
</SelectItem>
|
||||
</SelectGroup>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
|
|
|
|||
|
|
@ -114,7 +114,7 @@
|
|||
@apply pointer-events-none;
|
||||
}
|
||||
.extra-side-bar-buttons {
|
||||
@apply relative inline-flex w-full items-center justify-center rounded-md bg-background px-2 py-2 text-foreground shadow-sm ring-1 ring-inset ring-input transition-all duration-500 ease-in-out;
|
||||
@apply relative inline-flex w-full items-center justify-center rounded-md bg-background px-2 py-2 text-foreground shadow-sm ring-1 ring-inset ring-input transition-all duration-500 ease-in-out;
|
||||
}
|
||||
.extra-side-bar-buttons:hover {
|
||||
@apply hover:bg-muted;
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ export type DropDownComponentType = {
|
|||
editNode?: boolean;
|
||||
apiModal?: boolean;
|
||||
numberOfOptions?: number;
|
||||
id?: string;
|
||||
};
|
||||
export type ParameterComponentType = {
|
||||
data: NodeDataType;
|
||||
|
|
@ -67,6 +68,7 @@ export type KeyPairListComponentType = {
|
|||
disabled: boolean;
|
||||
editNode?: boolean;
|
||||
duplicateKey?: boolean;
|
||||
editNodeModal?: boolean;
|
||||
};
|
||||
|
||||
export type DictComponentType = {
|
||||
|
|
@ -74,6 +76,7 @@ export type DictComponentType = {
|
|||
onChange: (value) => void;
|
||||
disabled: boolean;
|
||||
editNode?: boolean;
|
||||
id?: string;
|
||||
};
|
||||
|
||||
export type TextAreaComponentType = {
|
||||
|
|
@ -214,6 +217,7 @@ export type IconComponentProps = {
|
|||
iconColor?: string;
|
||||
onClick?: () => void;
|
||||
stroke?: string;
|
||||
id?: string;
|
||||
};
|
||||
|
||||
export type InputProps = {
|
||||
|
|
@ -277,6 +281,7 @@ export type PaginatorComponentType = {
|
|||
};
|
||||
|
||||
export type ConfirmationModalType = {
|
||||
onCancel?: () => void;
|
||||
title: string;
|
||||
titleHeader: string;
|
||||
asChild?: boolean;
|
||||
|
|
|
|||
|
|
@ -10,7 +10,8 @@ export type FlowsContextType = {
|
|||
removeFlow: (id: string) => void;
|
||||
addFlow: (
|
||||
newProject: boolean,
|
||||
flow?: FlowType
|
||||
flow?: FlowType,
|
||||
override?: boolean
|
||||
) => Promise<String | undefined>;
|
||||
updateFlow: (newFlow: FlowType) => void;
|
||||
incrementNodeId: () => string;
|
||||
|
|
@ -44,7 +45,10 @@ export type FlowsContextType = {
|
|||
setLastCopiedSelection: (selection: { nodes: any; edges: any }) => void;
|
||||
setTweak: (tweak: tweakType) => tweakType | void;
|
||||
getTweak: tweakType;
|
||||
saveComponent: (component: NodeDataType) => Promise<String | undefined>;
|
||||
saveComponent: (
|
||||
component: NodeDataType,
|
||||
override: boolean
|
||||
) => Promise<String | undefined>;
|
||||
deleteComponent: (key: string) => void;
|
||||
version: string;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -9,7 +9,10 @@ import {
|
|||
XYPosition,
|
||||
} from "reactflow";
|
||||
import ShortUniqueId from "short-unique-id";
|
||||
import { specialCharsRegex } from "../constants/constants";
|
||||
import {
|
||||
LANGFLOW_SUPPORTED_TYPES,
|
||||
specialCharsRegex,
|
||||
} from "../constants/constants";
|
||||
import { APITemplateType, TemplateVariableType } from "../types/api";
|
||||
import {
|
||||
FlowType,
|
||||
|
|
@ -634,15 +637,7 @@ function updateGroupNodeTemplate(template: APITemplateType) {
|
|||
let type = template[key].type;
|
||||
let input_types = template[key].input_types;
|
||||
if (
|
||||
(type === "str" ||
|
||||
type === "bool" ||
|
||||
type === "float" ||
|
||||
type === "code" ||
|
||||
type === "prompt" ||
|
||||
type === "file" ||
|
||||
type === "int" ||
|
||||
type === "dict" ||
|
||||
type === "NestedDict") &&
|
||||
LANGFLOW_SUPPORTED_TYPES.has(type) &&
|
||||
!template[key].required &&
|
||||
!input_types
|
||||
) {
|
||||
|
|
|
|||
|
|
@ -67,6 +67,7 @@ import {
|
|||
Pencil,
|
||||
Plus,
|
||||
Redo,
|
||||
RefreshCcw,
|
||||
Rocket,
|
||||
Save,
|
||||
SaveAll,
|
||||
|
|
@ -195,7 +196,7 @@ export const nodeNames: { [char: string]: string } = {
|
|||
agents: "Agents",
|
||||
tools: "Tools",
|
||||
memories: "Memories",
|
||||
saved_components: "Saved Components",
|
||||
saved_components: "Saved",
|
||||
advanced: "Advanced",
|
||||
chat: "Chat",
|
||||
embeddings: "Embeddings",
|
||||
|
|
@ -354,4 +355,5 @@ export const nodeIconsLucide: iconsType = {
|
|||
Heart,
|
||||
Link,
|
||||
ToyBrick,
|
||||
RefreshCcw,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ test("CodeAreaModalComponent", async ({ page }) => {
|
|||
await page.waitForTimeout(2000);
|
||||
|
||||
await page
|
||||
.locator('//*[@id="sidePythonFunctionTool"]')
|
||||
.getByTestId("toolsPythonFunctionTool")
|
||||
.dragTo(page.locator('//*[@id="react-flow-id"]'));
|
||||
await page.mouse.up();
|
||||
await page.mouse.down();
|
||||
|
|
@ -34,8 +34,9 @@ test("CodeAreaModalComponent", async ({ page }) => {
|
|||
await page
|
||||
.locator('//*[@id="react-flow-id"]/div[1]/div[1]/div[1]/div/div[2]/div')
|
||||
.click();
|
||||
await page.locator('//*[@id="advancedIcon"]').click();
|
||||
await page.locator('//*[@id="editAdvancedBtn"]').click();
|
||||
await page.getByTestId("genericModalBtnSave").click();
|
||||
await page.getByTestId("more-options-modal").click();
|
||||
await page.getByTestId("edit-button-modal").click();
|
||||
|
||||
await page.locator('//*[@id="showcode"]').click();
|
||||
expect(await page.locator('//*[@id="showcode"]').isChecked()).toBeFalsy();
|
||||
|
|
@ -114,8 +115,8 @@ test("CodeAreaModalComponent", async ({ page }) => {
|
|||
await page
|
||||
.locator('//*[@id="react-flow-id"]/div[1]/div[1]/div[1]/div/div[2]/div')
|
||||
.click();
|
||||
await page.locator('//*[@id="advancedIcon"]').click();
|
||||
await page.locator('//*[@id="editAdvancedBtn"]').click();
|
||||
await page.getByTestId("more-options-modal").click();
|
||||
await page.getByTestId("edit-button-modal").click();
|
||||
|
||||
await page.locator('//*[@id="showcode"]').click();
|
||||
expect(await page.locator('//*[@id="showcode"]').isChecked()).toBeTruthy();
|
||||
|
|
|
|||
104
src/frontend/tests/end-to-end/dropdownComponent.spec.ts
Normal file
104
src/frontend/tests/end-to-end/dropdownComponent.spec.ts
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
import { expect, test } from "@playwright/test";
|
||||
|
||||
test("dropDownComponent", async ({ page }) => {
|
||||
await page.goto("http://localhost:3000/");
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
await page.locator('//*[@id="new-project-btn"]').click();
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
await page.getByPlaceholder("Search").click();
|
||||
await page.getByPlaceholder("Search").fill("amazon");
|
||||
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
await page
|
||||
.getByTestId("llmsAmazon Bedrock")
|
||||
.first()
|
||||
.dragTo(page.locator('//*[@id="react-flow-id"]'));
|
||||
await page.mouse.up();
|
||||
await page.mouse.down();
|
||||
|
||||
await page.getByTestId("dropdown-2-display").click();
|
||||
await page.getByTestId("ai21.j2-grande-instruct-0-option").click();
|
||||
|
||||
let value = await page.getByTestId("dropdown-2-display").innerText();
|
||||
if (value !== "ai21.j2-grande-instruct") {
|
||||
expect(false).toBeTruthy();
|
||||
}
|
||||
|
||||
await page.getByTestId("dropdown-2-display").click();
|
||||
await page.getByTestId("ai21.j2-jumbo-instruct-1-option").click();
|
||||
|
||||
value = await page.getByTestId("dropdown-2-display").innerText();
|
||||
if (value !== "ai21.j2-jumbo-instruct") {
|
||||
expect(false).toBeTruthy();
|
||||
}
|
||||
|
||||
await page.getByTestId("more-options-modal").click();
|
||||
await page.getByTestId("edit-button-modal").click();
|
||||
|
||||
value = await page.getByTestId("dropdown-edit-1-display").innerText();
|
||||
if (value !== "ai21.j2-jumbo-instruct") {
|
||||
expect(false).toBeTruthy();
|
||||
}
|
||||
|
||||
// showcredentials_profile_name
|
||||
await page.locator('//*[@id="showcredentials_profile_name"]').click();
|
||||
expect(
|
||||
await page.locator('//*[@id="showcredentials_profile_name"]').isChecked()
|
||||
).toBeFalsy();
|
||||
|
||||
// showmodel_id
|
||||
await page.locator('//*[@id="showmodel_id"]').click();
|
||||
expect(await page.locator('//*[@id="showmodel_id"]').isChecked()).toBeFalsy();
|
||||
|
||||
// showcredentials_profile_name
|
||||
await page.locator('//*[@id="showcredentials_profile_name"]').click();
|
||||
expect(
|
||||
await page.locator('//*[@id="showcredentials_profile_name"]').isChecked()
|
||||
).toBeTruthy();
|
||||
|
||||
// showmodel_id
|
||||
await page.locator('//*[@id="showmodel_id"]').click();
|
||||
expect(
|
||||
await page.locator('//*[@id="showmodel_id"]').isChecked()
|
||||
).toBeTruthy();
|
||||
|
||||
// showcredentials_profile_name
|
||||
await page.locator('//*[@id="showcredentials_profile_name"]').click();
|
||||
expect(
|
||||
await page.locator('//*[@id="showcredentials_profile_name"]').isChecked()
|
||||
).toBeFalsy();
|
||||
|
||||
// showmodel_id
|
||||
await page.locator('//*[@id="showmodel_id"]').click();
|
||||
expect(await page.locator('//*[@id="showmodel_id"]').isChecked()).toBeFalsy();
|
||||
|
||||
// showcredentials_profile_name
|
||||
await page.locator('//*[@id="showcredentials_profile_name"]').click();
|
||||
expect(
|
||||
await page.locator('//*[@id="showcredentials_profile_name"]').isChecked()
|
||||
).toBeTruthy();
|
||||
|
||||
// showmodel_id
|
||||
await page.locator('//*[@id="showmodel_id"]').click();
|
||||
expect(
|
||||
await page.locator('//*[@id="showmodel_id"]').isChecked()
|
||||
).toBeTruthy();
|
||||
|
||||
await page.getByTestId("dropdown-edit-1-display").click();
|
||||
await page.getByTestId("ai21.j2-ultra-v1-5-option").click();
|
||||
|
||||
value = await page.getByTestId("dropdown-edit-1-display").innerText();
|
||||
if (value !== "ai21.j2-ultra-v1") {
|
||||
expect(false).toBeTruthy();
|
||||
}
|
||||
|
||||
await page.locator('//*[@id="saveChangesBtn"]').click();
|
||||
|
||||
value = await page.getByTestId("dropdown-2-display").innerText();
|
||||
if (value !== "ai21.j2-ultra-v1") {
|
||||
expect(false).toBeTruthy();
|
||||
}
|
||||
});
|
||||
|
|
@ -42,6 +42,7 @@ test("FloatComponent", async ({ page }) => {
|
|||
)
|
||||
.click();
|
||||
await page.getByTestId("more-options-modal").click();
|
||||
await page.getByTestId("edit-button-modal").click();
|
||||
|
||||
await page.locator('//*[@id="showcache"]').click();
|
||||
expect(await page.locator('//*[@id="showcache"]').isChecked()).toBeTruthy();
|
||||
|
|
@ -385,7 +386,8 @@ test("FloatComponent", async ({ page }) => {
|
|||
'//*[@id="react-flow-id"]/div[1]/div[1]/div[1]/div/div[2]/div/div/div[1]/div/div[1]/div'
|
||||
)
|
||||
.click();
|
||||
await page.locator('//*[@id="editAdvancedIcon"]').click();
|
||||
await page.getByTestId("more-options-modal").click();
|
||||
await page.getByTestId("edit-button-modal").click();
|
||||
|
||||
// showtemperature
|
||||
await page.locator('//*[@id="showtemperature"]').click();
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ test.describe("Flow Page tests", () => {
|
|||
.filter({ hasText: /^Custom Component$/ })
|
||||
.nth(4)
|
||||
.dragTo(page.locator(".react-flow__pane"));
|
||||
await page.locator("div:nth-child(4) > .extra-side-bar-buttons").click();
|
||||
await page.locator(".success-alert").click();
|
||||
await page.getByTestId("icon-ExternalLink").click();
|
||||
await page.locator('//*[@id="checkAndSaveBtn"]').click();
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -13,7 +13,8 @@ test("IntComponent", async ({ page }) => {
|
|||
await page.waitForTimeout(2000);
|
||||
|
||||
await page
|
||||
.locator('//*[@id="sideGET Request"]')
|
||||
.getByTestId("utilitiesGET Request")
|
||||
.first()
|
||||
.dragTo(page.locator('//*[@id="react-flow-id"]'));
|
||||
await page.mouse.up();
|
||||
await page.mouse.down();
|
||||
|
|
@ -30,7 +31,7 @@ test("IntComponent", async ({ page }) => {
|
|||
}
|
||||
|
||||
await page.locator('//*[@id="int-input-2"]').click();
|
||||
await page.locator('//*[@id="int-input-2"]').fill("-3");
|
||||
await page.locator('//*[@id="int-input-2"]').fill("0");
|
||||
|
||||
value = await page.locator('//*[@id="int-input-2"]').inputValue();
|
||||
|
||||
|
|
@ -41,8 +42,8 @@ test("IntComponent", async ({ page }) => {
|
|||
await page
|
||||
.locator('//*[@id="react-flow-id"]/div[1]/div[1]/div[1]/div/div[2]/div')
|
||||
.click();
|
||||
await page.locator('//*[@id="advancedIcon"]').click();
|
||||
await page.locator('//*[@id="editAdvancedBtn"]').click();
|
||||
await page.getByTestId("more-options-modal").click();
|
||||
await page.getByTestId("edit-button-modal").click();
|
||||
|
||||
value = await page.locator('//*[@id="int-input-1"]').inputValue();
|
||||
|
||||
|
|
@ -80,8 +81,8 @@ test("IntComponent", async ({ page }) => {
|
|||
await page
|
||||
.locator('//*[@id="react-flow-id"]/div[1]/div[1]/div[1]/div/div[2]/div')
|
||||
.click();
|
||||
await page.locator('//*[@id="advancedIcon"]').click();
|
||||
await page.locator('//*[@id="editAdvancedBtn"]').click();
|
||||
await page.getByTestId("more-options-modal").click();
|
||||
await page.getByTestId("edit-button-modal").click();
|
||||
|
||||
await page.locator('//*[@id="showtimeout"]').click();
|
||||
expect(
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ test("KeypairListComponent", async ({ page }) => {
|
|||
await page.waitForTimeout(2000);
|
||||
|
||||
await page
|
||||
.locator('//*[@id="sideCSVLoader"]')
|
||||
.getByTestId("documentloadersCSVLoader")
|
||||
.dragTo(page.locator('//*[@id="react-flow-id"]'));
|
||||
await page.mouse.up();
|
||||
await page.mouse.down();
|
||||
|
|
@ -66,8 +66,8 @@ test("KeypairListComponent", async ({ page }) => {
|
|||
'//*[@id="react-flow-id"]/div[1]/div[1]/div[1]/div/div[2]/div/div/div[1]/div/div[1]/div'
|
||||
)
|
||||
.click();
|
||||
await page.locator('//*[@id="advancedIcon"]').click();
|
||||
await page.locator('//*[@id="editAdvancedBtn"]').click();
|
||||
await page.getByTestId("more-options-modal").click();
|
||||
await page.getByTestId("edit-button-modal").click();
|
||||
|
||||
await page.locator('//*[@id="showfile_path"]').click();
|
||||
expect(
|
||||
|
|
@ -87,8 +87,8 @@ test("KeypairListComponent", async ({ page }) => {
|
|||
'//*[@id="react-flow-id"]/div[1]/div[1]/div[1]/div/div[2]/div/div/div[1]/div/div[1]/div'
|
||||
)
|
||||
.click();
|
||||
await page.locator('//*[@id="advancedIcon"]').click();
|
||||
await page.locator('//*[@id="editAdvancedBtn"]').click();
|
||||
await page.getByTestId("more-options-modal").click();
|
||||
await page.getByTestId("edit-button-modal").click();
|
||||
|
||||
await page.locator('//*[@id="showfile_path"]').click();
|
||||
expect(
|
||||
|
|
@ -99,11 +99,11 @@ test("KeypairListComponent", async ({ page }) => {
|
|||
await page.locator('//*[@id="showmetadata"]').isChecked()
|
||||
).toBeTruthy();
|
||||
|
||||
await page.locator('//*[@id="keypair0"]').click();
|
||||
await page.locator('//*[@id="keypair0"]').fill("testtesttesttest");
|
||||
await page.locator('//*[@id="keypair100"]').click();
|
||||
await page.locator('//*[@id="editNodekeypair0"]').click();
|
||||
await page.locator('//*[@id="editNodekeypair0"]').fill("testtesttesttest");
|
||||
await page.locator('//*[@id="editNodekeypair100"]').click();
|
||||
await page
|
||||
.locator('//*[@id="keypair100"]')
|
||||
.locator('//*[@id="editNodekeypair100"]')
|
||||
.fill("test test test test test test");
|
||||
|
||||
const plusButtonLocator = page.locator('//*[@id="plusbtn0"]');
|
||||
|
|
@ -112,24 +112,24 @@ test("KeypairListComponent", async ({ page }) => {
|
|||
await plusButtonLocator.click();
|
||||
}
|
||||
|
||||
await page.locator('//*[@id="keypair1"]').click();
|
||||
await page.locator('//*[@id="keypair1"]').fill("testtesttesttest1");
|
||||
await page.locator('//*[@id="keypair101"]').click();
|
||||
await page.locator('//*[@id="editNodekeypair1"]').click();
|
||||
await page.locator('//*[@id="editNodekeypair1"]').fill("testtesttesttest1");
|
||||
await page.locator('//*[@id="editNodekeypair101"]').first().click();
|
||||
await page
|
||||
.locator('//*[@id="keypair101"]')
|
||||
.locator('//*[@id="editNodekeypair101"]')
|
||||
.fill("testtesttesttesttesttest1");
|
||||
await page.locator('//*[@id="plusbtn1"]').click();
|
||||
await page.locator('//*[@id="editNodeplusbtn1"]').click();
|
||||
|
||||
await page.locator('//*[@id="keypair2"]').click();
|
||||
await page.locator('//*[@id="keypair2"]').fill("testtesttesttest2");
|
||||
await page.locator('//*[@id="keypair102"]').click();
|
||||
await page.locator('//*[@id="editNodekeypair2"]').click();
|
||||
await page.locator('//*[@id="editNodekeypair2"]').fill("testtesttesttest2");
|
||||
await page.locator('//*[@id="editNodekeypair102"]').click();
|
||||
await page
|
||||
.locator('//*[@id="keypair102"]')
|
||||
.locator('//*[@id="editNodekeypair102"]')
|
||||
.fill("testtesttesttesttesttest2");
|
||||
|
||||
await page.locator('//*[@id="minusbtn1"]').click();
|
||||
await page.locator('//*[@id="editNodeminusbtn1"]').click();
|
||||
|
||||
const keyPairVerification = page.locator('//*[@id="keypair102"]');
|
||||
const keyPairVerification = page.locator('//*[@id="editNodekeypair102"]');
|
||||
const elementKeyCount = await keyPairVerification.count();
|
||||
|
||||
if (elementKeyCount === 0) {
|
||||
|
|
@ -143,8 +143,8 @@ test("KeypairListComponent", async ({ page }) => {
|
|||
if (
|
||||
key1 === "testtesttesttest" &&
|
||||
value1 === "test test test test test test" &&
|
||||
key2 === "testtesttesttest2" &&
|
||||
value2 === "testtesttesttesttesttest2"
|
||||
key2 === "testtesttesttest1" &&
|
||||
value2 === "testtesttesttesttesttest1"
|
||||
) {
|
||||
expect(true).toBeTruthy();
|
||||
} else {
|
||||
|
|
|
|||
239
src/frontend/tests/end-to-end/nestedComponent.spec.ts
Normal file
239
src/frontend/tests/end-to-end/nestedComponent.spec.ts
Normal file
|
|
@ -0,0 +1,239 @@
|
|||
import { expect, test } from "@playwright/test";
|
||||
|
||||
test("NestedComponent", async ({ page }) => {
|
||||
await page.goto("http://localhost:3000/");
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
await page.locator('//*[@id="new-project-btn"]').click();
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
await page.getByPlaceholder("Search").click();
|
||||
await page.getByPlaceholder("Search").fill("pinecone");
|
||||
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
await page
|
||||
.getByTestId("vectorstoresPinecone")
|
||||
.first()
|
||||
.dragTo(page.locator('//*[@id="react-flow-id"]'));
|
||||
await page.mouse.up();
|
||||
await page.mouse.down();
|
||||
|
||||
await page.getByTestId("more-options-modal").click();
|
||||
await page.getByTestId("edit-button-modal").click();
|
||||
|
||||
// showindex_name
|
||||
await page.locator('//*[@id="showindex_name"]').click();
|
||||
|
||||
expect(
|
||||
await page.locator('//*[@id="showindex_name"]').isChecked()
|
||||
).toBeFalsy();
|
||||
|
||||
// shownamespace
|
||||
await page.locator('//*[@id="shownamespace"]').click();
|
||||
|
||||
expect(
|
||||
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()
|
||||
).toBeTruthy();
|
||||
|
||||
// showpinecone_env
|
||||
await page.locator('//*[@id="showpinecone_env"]').click();
|
||||
|
||||
expect(
|
||||
await page.locator('//*[@id="showpinecone_env"]').isChecked()
|
||||
).toBeTruthy();
|
||||
|
||||
// showsearch_kwargs
|
||||
await page.locator('//*[@id="showsearch_kwargs"]').click();
|
||||
|
||||
expect(
|
||||
await page.locator('//*[@id="showsearch_kwargs"]').isChecked()
|
||||
).toBeTruthy();
|
||||
|
||||
// showindex_name
|
||||
await page.locator('//*[@id="showindex_name"]').click();
|
||||
|
||||
expect(
|
||||
await page.locator('//*[@id="showindex_name"]').isChecked()
|
||||
).toBeTruthy();
|
||||
|
||||
// shownamespace
|
||||
await page.locator('//*[@id="shownamespace"]').click();
|
||||
|
||||
expect(
|
||||
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()
|
||||
).toBeFalsy();
|
||||
|
||||
// showpinecone_env
|
||||
await page.locator('//*[@id="showpinecone_env"]').click();
|
||||
|
||||
expect(
|
||||
await page.locator('//*[@id="showpinecone_env"]').isChecked()
|
||||
).toBeFalsy();
|
||||
|
||||
// showsearch_kwargs
|
||||
await page.locator('//*[@id="showsearch_kwargs"]').click();
|
||||
|
||||
expect(
|
||||
await page.locator('//*[@id="showsearch_kwargs"]').isChecked()
|
||||
).toBeFalsy();
|
||||
|
||||
// showindex_name
|
||||
await page.locator('//*[@id="showindex_name"]').click();
|
||||
|
||||
expect(
|
||||
await page.locator('//*[@id="showindex_name"]').isChecked()
|
||||
).toBeFalsy();
|
||||
|
||||
// shownamespace
|
||||
await page.locator('//*[@id="shownamespace"]').click();
|
||||
|
||||
expect(
|
||||
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()
|
||||
).toBeTruthy();
|
||||
|
||||
// showpinecone_env
|
||||
await page.locator('//*[@id="showpinecone_env"]').click();
|
||||
|
||||
expect(
|
||||
await page.locator('//*[@id="showpinecone_env"]').isChecked()
|
||||
).toBeTruthy();
|
||||
|
||||
// showsearch_kwargs
|
||||
await page.locator('//*[@id="showsearch_kwargs"]').click();
|
||||
|
||||
expect(
|
||||
await page.locator('//*[@id="showsearch_kwargs"]').isChecked()
|
||||
).toBeTruthy();
|
||||
|
||||
// showindex_name
|
||||
await page.locator('//*[@id="showindex_name"]').click();
|
||||
|
||||
expect(
|
||||
await page.locator('//*[@id="showindex_name"]').isChecked()
|
||||
).toBeTruthy();
|
||||
|
||||
// shownamespace
|
||||
await page.locator('//*[@id="shownamespace"]').click();
|
||||
|
||||
expect(
|
||||
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()
|
||||
).toBeFalsy();
|
||||
|
||||
// showpinecone_env
|
||||
await page.locator('//*[@id="showpinecone_env"]').click();
|
||||
|
||||
expect(
|
||||
await page.locator('//*[@id="showpinecone_env"]').isChecked()
|
||||
).toBeFalsy();
|
||||
|
||||
// showsearch_kwargs
|
||||
await page.locator('//*[@id="showsearch_kwargs"]').click();
|
||||
|
||||
expect(
|
||||
await page.locator('//*[@id="showsearch_kwargs"]').isChecked()
|
||||
).toBeFalsy();
|
||||
|
||||
// showindex_name
|
||||
await page.locator('//*[@id="showindex_name"]').click();
|
||||
|
||||
expect(
|
||||
await page.locator('//*[@id="showindex_name"]').isChecked()
|
||||
).toBeFalsy();
|
||||
|
||||
// shownamespace
|
||||
await page.locator('//*[@id="shownamespace"]').click();
|
||||
|
||||
expect(
|
||||
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()
|
||||
).toBeTruthy();
|
||||
|
||||
// showpinecone_env
|
||||
await page.locator('//*[@id="showpinecone_env"]').click();
|
||||
|
||||
expect(
|
||||
await page.locator('//*[@id="showpinecone_env"]').isChecked()
|
||||
).toBeTruthy();
|
||||
|
||||
// showsearch_kwargs
|
||||
await page.locator('//*[@id="showsearch_kwargs"]').click();
|
||||
|
||||
expect(
|
||||
await page.locator('//*[@id="showsearch_kwargs"]').isChecked()
|
||||
).toBeTruthy();
|
||||
|
||||
// showindex_name
|
||||
await page.locator('//*[@id="showindex_name"]').click();
|
||||
|
||||
expect(
|
||||
await page.locator('//*[@id="showindex_name"]').isChecked()
|
||||
).toBeTruthy();
|
||||
|
||||
// shownamespace
|
||||
await page.locator('//*[@id="shownamespace"]').click();
|
||||
|
||||
expect(
|
||||
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()
|
||||
).toBeFalsy();
|
||||
|
||||
// showpinecone_env
|
||||
await page.locator('//*[@id="showpinecone_env"]').click();
|
||||
|
||||
expect(
|
||||
await page.locator('//*[@id="showpinecone_env"]').isChecked()
|
||||
).toBeFalsy();
|
||||
|
||||
await page.locator('//*[@id="saveChangesBtn"]').click();
|
||||
|
||||
await page.getByTestId("div-dict-input").click();
|
||||
|
||||
const spanElement = await page
|
||||
.locator('//*[@id="radix-:r4i:"]/div[2]/div/div/code/div/div/span[1]')
|
||||
.innerHTML();
|
||||
|
||||
if (spanElement !== "yourkey") {
|
||||
expect(true).toBeFalsy();
|
||||
}
|
||||
});
|
||||
|
|
@ -13,19 +13,20 @@ test("PromptTemplateComponent", async ({ page }) => {
|
|||
await page.waitForTimeout(2000);
|
||||
|
||||
await page
|
||||
.locator('//*[@id="sidePromptTemplate"]')
|
||||
.locator('//*[@id="promptsPromptTemplate"]')
|
||||
.dragTo(page.locator('//*[@id="react-flow-id"]'));
|
||||
await page.mouse.up();
|
||||
await page.mouse.down();
|
||||
|
||||
await page.locator('//*[@id="prompt-input-4"]').click();
|
||||
await page
|
||||
.locator('//*[@id="modal-prompt-input-4"]')
|
||||
.fill("{prompt} example {prompt1}");
|
||||
await page.getByTestId("prompt-input-4-ExternalLink").click();
|
||||
// await page.getByTestId("edit-prompt-sanitized").click();
|
||||
|
||||
let value = await page
|
||||
.locator('//*[@id="modal-prompt-input-4"]')
|
||||
.inputValue();
|
||||
await page
|
||||
.getByTestId("modal-prompt-input-4")
|
||||
.fill("{prompt} example {prompt1}");
|
||||
// await page.getByTestId("edit-prompt-sanitized").click();
|
||||
|
||||
let value = await page.getByTestId("modal-prompt-input-4").inputValue();
|
||||
|
||||
if (value != "{prompt} example {prompt1}") {
|
||||
expect(false).toBeTruthy();
|
||||
|
|
@ -43,33 +44,38 @@ test("PromptTemplateComponent", async ({ page }) => {
|
|||
|
||||
await page.locator('//*[@id="genericModalBtnSave"]').click();
|
||||
|
||||
await page.locator('//*[@id="textarea-7"]').click();
|
||||
await page.locator('//*[@id="textarea-7"]').fill("prompt_value_!@#!@#");
|
||||
await page.getByTestId("textarea-4-ExternalLink").click();
|
||||
await page.getByTestId("text-area-modal").fill("prompt_value_!@#!@#");
|
||||
|
||||
value = await page.locator('//*[@id="textarea-7"]').inputValue();
|
||||
value = await page.getByTestId("text-area-modal").inputValue();
|
||||
|
||||
if (value != "prompt_value_!@#!@#") {
|
||||
expect(false).toBeTruthy();
|
||||
}
|
||||
|
||||
await page.locator('//*[@id="textarea-8"]').click();
|
||||
await page.getByTestId("genericModalBtnSave").click();
|
||||
|
||||
await page.getByTestId("textarea-5-ExternalLink").click();
|
||||
await page
|
||||
.locator('//*[@id="textarea-8"]')
|
||||
.getByTestId("text-area-modal")
|
||||
.fill("prompt_name_test_123123!@#!@#");
|
||||
|
||||
value = await page.locator('//*[@id="textarea-8"]').inputValue();
|
||||
value = await page.getByTestId("text-area-modal").inputValue();
|
||||
|
||||
if (value != "prompt_name_test_123123!@#!@#") {
|
||||
expect(false).toBeTruthy();
|
||||
}
|
||||
|
||||
value = await page.locator('//*[@id="prompt-input-4"]').innerText();
|
||||
value = await page.getByTestId("text-area-modal").inputValue();
|
||||
|
||||
if (value != "{prompt} example {prompt1}") {
|
||||
if (value != "prompt_name_test_123123!@#!@#") {
|
||||
expect(false).toBeTruthy();
|
||||
}
|
||||
|
||||
await page.locator('//*[@id="editAdvancedIcon"]').click();
|
||||
await page.getByTestId("genericModalBtnSave").click();
|
||||
|
||||
await page.getByTestId("more-options-modal").click();
|
||||
await page.getByTestId("edit-button-modal").click();
|
||||
|
||||
value = await page.locator('//*[@id="textarea-edit-1"]').inputValue();
|
||||
|
||||
|
|
@ -146,7 +152,8 @@ test("PromptTemplateComponent", async ({ page }) => {
|
|||
)
|
||||
.click();
|
||||
|
||||
await page.locator('//*[@id="editAdvancedIcon"]').click();
|
||||
await page.getByTestId("more-options-modal").click();
|
||||
await page.getByTestId("edit-button-modal").click();
|
||||
|
||||
await page.locator('//*[@id="showprompt1"]').click();
|
||||
expect(
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ test("InputComponent", async ({ page }) => {
|
|||
await page.waitForTimeout(2000);
|
||||
|
||||
await page
|
||||
.locator('//*[@id="sideChroma"]')
|
||||
.getByTestId("vectorstoresChroma")
|
||||
.dragTo(page.locator('//*[@id="react-flow-id"]'));
|
||||
await page.mouse.up();
|
||||
await page.mouse.down();
|
||||
|
|
@ -44,7 +44,8 @@ test("InputComponent", async ({ page }) => {
|
|||
'//*[@id="react-flow-id"]/div[1]/div[1]/div[1]/div/div[2]/div/div/div[1]/div/div[1]/div'
|
||||
)
|
||||
.click();
|
||||
await page.locator('//*[@id="editAdvancedIcon"]').click();
|
||||
await page.getByTestId("more-options-modal").click();
|
||||
await page.getByTestId("edit-button-modal").click();
|
||||
|
||||
await page.locator('//*[@id="showchroma_server_cors_allow_origins"]').click();
|
||||
expect(
|
||||
|
|
@ -154,7 +155,8 @@ test("InputComponent", async ({ page }) => {
|
|||
'//*[@id="react-flow-id"]/div[1]/div[1]/div[1]/div/div[2]/div/div/div[1]/div/div[1]/div'
|
||||
)
|
||||
.click();
|
||||
await page.locator('//*[@id="editAdvancedIcon"]').click();
|
||||
await page.getByTestId("more-options-modal").click();
|
||||
await page.getByTestId("edit-button-modal").click();
|
||||
|
||||
await page.locator('//*[@id="showcollection_name"]').click();
|
||||
expect(
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ test("ToggleComponent", async ({ page }) => {
|
|||
|
||||
await page.waitForTimeout(2000);
|
||||
await page
|
||||
.locator('//*[@id="sideDirectoryLoader"]')
|
||||
.getByTestId("documentloadersDirectoryLoader")
|
||||
.dragTo(page.locator('//*[@id="react-flow-id"]'));
|
||||
await page.mouse.up();
|
||||
await page.mouse.down();
|
||||
|
|
@ -32,8 +32,8 @@ test("ToggleComponent", async ({ page }) => {
|
|||
'//*[@id="react-flow-id"]/div[1]/div[1]/div/div/div[2]/div/div/div[1]/div'
|
||||
)
|
||||
.click();
|
||||
await page.locator('//*[@id="advancedIcon"]').click();
|
||||
await page.locator('//*[@id="editAdvancedBtn"]').click();
|
||||
await page.getByTestId("more-options-modal").click();
|
||||
await page.getByTestId("edit-button-modal").click();
|
||||
|
||||
await page.locator('//*[@id="showload_hidden"]').click();
|
||||
expect(
|
||||
|
|
@ -62,8 +62,8 @@ test("ToggleComponent", async ({ page }) => {
|
|||
'//*[@id="react-flow-id"]/div[1]/div[1]/div/div/div[2]/div/div/div[1]/div'
|
||||
)
|
||||
.click();
|
||||
await page.locator('//*[@id="advancedIcon"]').click();
|
||||
await page.locator('//*[@id="editAdvancedBtn"]').click();
|
||||
await page.getByTestId("more-options-modal").click();
|
||||
await page.getByTestId("edit-button-modal").click();
|
||||
|
||||
expect(
|
||||
await page.locator('//*[@id="toggle-edit-1"]').isChecked()
|
||||
|
|
@ -144,8 +144,8 @@ test("ToggleComponent", async ({ page }) => {
|
|||
await page
|
||||
.locator('//*[@id="react-flow-id"]/div[1]/div[1]/div[1]/div/div[2]/div')
|
||||
.click();
|
||||
await page.locator('//*[@id="advancedIcon"]').click();
|
||||
await page.locator('//*[@id="editAdvancedBtn"]').click();
|
||||
await page.getByTestId("more-options-modal").click();
|
||||
await page.getByTestId("edit-button-modal").click();
|
||||
|
||||
await page.locator('//*[@id="showload_hidden"]').click();
|
||||
expect(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue