diff --git a/src/frontend/package-lock.json b/src/frontend/package-lock.json
index 2d61fd033..e0fcfbd47 100644
--- a/src/frontend/package-lock.json
+++ b/src/frontend/package-lock.json
@@ -42,6 +42,7 @@
"base64-js": "^1.5.1",
"class-variance-authority": "^0.6.1",
"clsx": "^1.2.1",
+ "cmdk": "^1.0.0",
"dompurify": "^3.0.5",
"esbuild": "^0.17.19",
"framer-motion": "^11.0.6",
@@ -4797,6 +4798,19 @@
"node": ">=6"
}
},
+ "node_modules/cmdk": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/cmdk/-/cmdk-1.0.0.tgz",
+ "integrity": "sha512-gDzVf0a09TvoJ5jnuPvygTB77+XdOSwEmJ88L6XPFPlv7T3RxbP9jgenfylrAMD0+Le1aO0nVjQUzl2g+vjz5Q==",
+ "dependencies": {
+ "@radix-ui/react-dialog": "1.0.5",
+ "@radix-ui/react-primitive": "1.0.3"
+ },
+ "peerDependencies": {
+ "react": "^18.0.0",
+ "react-dom": "^18.0.0"
+ }
+ },
"node_modules/code-block-writer": {
"version": "12.0.0",
"resolved": "https://registry.npmjs.org/code-block-writer/-/code-block-writer-12.0.0.tgz",
diff --git a/src/frontend/package.json b/src/frontend/package.json
index dd865530e..8b20d5e6b 100644
--- a/src/frontend/package.json
+++ b/src/frontend/package.json
@@ -37,6 +37,7 @@
"base64-js": "^1.5.1",
"class-variance-authority": "^0.6.1",
"clsx": "^1.2.1",
+ "cmdk": "^1.0.0",
"dompurify": "^3.0.5",
"esbuild": "^0.17.19",
"framer-motion": "^11.0.6",
diff --git a/src/frontend/src/CustomNodes/GenericNode/components/parameterComponent/index.tsx b/src/frontend/src/CustomNodes/GenericNode/components/parameterComponent/index.tsx
index 3e7df4e73..0ac69afe8 100644
--- a/src/frontend/src/CustomNodes/GenericNode/components/parameterComponent/index.tsx
+++ b/src/frontend/src/CustomNodes/GenericNode/components/parameterComponent/index.tsx
@@ -16,6 +16,7 @@ import PromptAreaComponent from "../../../../components/promptComponent";
import TextAreaComponent from "../../../../components/textAreaComponent";
import ToggleShadComponent from "../../../../components/toggleShadComponent";
import { Button } from "../../../../components/ui/button";
+import { CommandItem } from "../../../../components/ui/command";
import { RefreshButton } from "../../../../components/ui/refreshButton";
import {
INPUT_HANDLER_HOVER,
@@ -23,6 +24,7 @@ import {
OUTPUT_HANDLER_HOVER,
TOOLTIP_EMPTY,
} from "../../../../constants/constants";
+import AddNewVariableButton from "../../../../pages/globalVariablesPage/components/addNewVariableButton";
import useAlertStore from "../../../../stores/alertStore";
import useFlowStore from "../../../../stores/flowStore";
import useFlowsManagerStore from "../../../../stores/flowsManagerStore";
@@ -46,7 +48,7 @@ import {
nodeIconsLucide,
nodeNames,
} from "../../../../utils/styleUtils";
-import { classNames, groupByFamily } from "../../../../utils/utils";
+import { classNames, cn, groupByFamily } from "../../../../utils/utils";
export default function ParameterComponent({
left,
@@ -386,7 +388,7 @@ export default function ParameterComponent({
<>
@@ -546,33 +548,47 @@ export default function ParameterComponent({
password={data.node?.template[name].password ?? false}
value={data.node?.template[name].value ?? ""}
options={globalVariablesEntries}
- onChange={(value) => {
- handleOnNewValue(value);
- if (globalVariablesEntries.includes(value)) {
- setNoticeData({
- title: `the value inserted in ${data.node?.display_name} is a global variable, \n
- the real value will be update on run`,
- });
- setNode(data.id, (oldNode) => {
- let newNode = cloneDeep(oldNode);
- newNode.data = {
- ...newNode.data,
- };
- newNode.data.node.template[name].load_from_db = true;
- return newNode;
- });
- } else {
- setNode(data.id, (oldNode) => {
- let newNode = cloneDeep(oldNode);
- newNode.data = {
- ...newNode.data,
- };
- newNode.data.node.template[name].load_from_db = false;
- return newNode;
- });
- }
- //mark as global variable
- }}
+ optionsPlaceholder={"Global Variables"}
+ optionsButton={
+
+
+
+ Add New Variable
+
+
+ }
+ selectedOption={
+ data?.node?.template[name].load_from_db ?? false
+ ? data?.node?.template[name].value
+ : ""
+ }
+ setSelectedOption={(value) => {
+ handleOnNewValue(value);
+ setNode(data.id, (oldNode) => {
+ let newNode = cloneDeep(oldNode);
+ newNode.data = {
+ ...newNode.data,
+ };
+ newNode.data.node.template[name].load_from_db =
+ value === "" ? false : true;
+ return newNode;
+ });
+ }}
+ onChange={(value) => {
+ handleOnNewValue(value);
+ setNode(data.id, (oldNode) => {
+ let newNode = cloneDeep(oldNode);
+ newNode.data = {
+ ...newNode.data,
+ };
+ newNode.data.node.template[name].load_from_db = false;
+ return newNode;
+ });
+ }}
/>
{data.node?.template[name].refresh_button && (
diff --git a/src/frontend/src/components/inputComponent/index.tsx b/src/frontend/src/components/inputComponent/index.tsx
index b3177954d..b9ed74dc2 100644
--- a/src/frontend/src/components/inputComponent/index.tsx
+++ b/src/frontend/src/components/inputComponent/index.tsx
@@ -1,13 +1,20 @@
-import { Listbox, Transition } from "@headlessui/react";
import * as Form from "@radix-ui/react-form";
-import { Fragment, useEffect, useRef, useState } from "react";
-import AddNewVariableButton from "../../pages/globalVariablesPage/components/addNewVariableButton";
+import { PopoverAnchor } from "@radix-ui/react-popover";
+import { useEffect, useRef, useState } from "react";
import { InputComponentType } from "../../types/components";
import { handleKeyDown } from "../../utils/reactflowUtils";
import { classNames, cn } from "../../utils/utils";
import IconComponent from "../genericIconComponent";
+import {
+ Command,
+ CommandEmpty,
+ CommandGroup,
+ CommandInput,
+ CommandItem,
+ CommandList,
+} from "../ui/command";
import { Input } from "../ui/input";
-import { Separator } from "../ui/separator";
+import { Popover, PopoverContentWithoutPortal } from "../ui/popover";
export default function InputComponent({
autoFocus = false,
@@ -23,7 +30,11 @@ export default function InputComponent({
className,
id = "",
blurOnEnter = false,
+ selectedOption,
+ setSelectedOption,
options = [],
+ optionsPlaceholder = "Search options...",
+ optionsButton,
}: InputComponentType): JSX.Element {
const [pwdVisible, setPwdVisible] = useState(false);
const refInput = useRef(null);
@@ -36,10 +47,6 @@ export default function InputComponent({
}
}, [disabled]);
- const filteredOptions = options.filter((option) =>
- option.toLowerCase().includes(value.toLowerCase())
- );
-
function onInputLostFocus(event): void {
if (onBlur) onBlur(event);
}
@@ -81,144 +88,118 @@ export default function InputComponent({
) : (
<>
- {
- onChange(e.target.value);
- }}
- onKeyDown={(e) => {
- handleKeyDown(e, value, "");
- if (blurOnEnter && e.key === "Enter") refInput.current?.blur();
- }}
- data-testid={editNode ? id + "-edit" : id}
- />
- {
- onChange(val);
- }}
- >
- <>
-
-
-
-
-
-
- Global Variables
-
-
-
-
- {filteredOptions.map((option, id) => (
-
+
+ {
+ selectedOption !== "" && setShowOptions(true);
+ }}
+ required={required}
+ className={classNames(
+ password && !pwdVisible && value !== ""
+ ? " text-clip password "
+ : "",
+ editNode ? " input-edit-node " : "",
+ password && editNode ? "pr-8" : "",
+ password && !editNode ? "pr-10" : "",
+ className!
+ )}
+ placeholder={password && editNode ? "Key" : placeholder}
+ onChange={(e) => {
+ onChange(e.target.value);
+ }}
+ onKeyDown={(e) => {
+ handleKeyDown(e, value, "");
+ if (blurOnEnter && e.key === "Enter")
+ refInput.current?.blur();
+ }}
+ data-testid={editNode ? id + "-edit" : id}
+ />
+
+
+
+
+
+ No results found.
+
+ {options.map((option, id) => (
+
- classNames(
- active ? " bg-accent" : "",
- editNode
- ? "dropdown-component-false-option"
- : "dropdown-component-true-option",
- " hover:bg-accent"
- )
- }
value={option}
+ onSelect={(currentValue) => {
+ setSelectedOption &&
+ setSelectedOption(
+ currentValue === selectedOption
+ ? ""
+ : currentValue
+ );
+ setShowOptions(false);
+ }}
>
- {({ selected, active }) => (
- <>
-
- {option}
-
-
- {selected ? (
-
-
-
- ) : null}
- >
- )}
-
+
+ {option}
+
))}
-
-
-
- >
-
+ {optionsButton && optionsButton}
+
+
+
+
+
+ {
+ setShowOptions((old) => !old);
+ e.preventDefault();
+ e.stopPropagation();
+ }
+ : () => {}
+ }
+ >
>
)}
- {options.length > 0 && (
-
+
- )}
+
+
+
{password && (
,
+ React.ComponentPropsWithoutRef
+>(({ className, align = "center", sideOffset = 4, ...props }, ref) => (
+
+));
+PopoverContentWithoutPortal.displayName = PopoverPrimitive.Content.displayName;
+
+export { Popover, PopoverContent, PopoverContentWithoutPortal, PopoverTrigger };
diff --git a/src/frontend/src/types/components/index.ts b/src/frontend/src/types/components/index.ts
index 590664c22..bf561f471 100644
--- a/src/frontend/src/types/components/index.ts
+++ b/src/frontend/src/types/components/index.ts
@@ -20,7 +20,11 @@ export type InputComponentType = {
className?: string;
id?: string;
blurOnEnter?: boolean;
+ optionsPlaceholder?: string;
options?: string[];
+ optionsButton?: ReactElement;
+ selectedOption?: string;
+ setSelectedOption?: (value: string) => void;
};
export type ToggleComponentType = {
enabled: boolean;