{!config && (
diff --git a/studio/frontend/src/features/canvas-lab/dialogs/import-dialog.tsx b/studio/frontend/src/features/canvas-lab/dialogs/import-dialog.tsx
index c5b93501bf..83badb8a98 100644
--- a/studio/frontend/src/features/canvas-lab/dialogs/import-dialog.tsx
+++ b/studio/frontend/src/features/canvas-lab/dialogs/import-dialog.tsx
@@ -7,29 +7,31 @@ import {
DialogTitle,
} from "@/components/ui/dialog";
import { Textarea } from "@/components/ui/textarea";
-import { type ReactElement, useEffect, useState } from "react";
+import { type ReactElement, useState } from "react";
type ImportDialogProps = {
open: boolean;
onOpenChange: (open: boolean) => void;
onImport: (value: string) => string | null;
+ container?: HTMLDivElement | null;
};
export function ImportDialog({
open,
onOpenChange,
onImport,
+ container,
}: ImportDialogProps): ReactElement {
const [value, setValue] = useState("");
const [error, setError] = useState
(null);
const payloadId = "canvas-import-payload";
-
- useEffect(() => {
- if (!open) {
+ const handleOpenChange = (nextOpen: boolean) => {
+ if (!nextOpen) {
setValue("");
setError(null);
}
- }, [open]);
+ onOpenChange(nextOpen);
+ };
const handleImport = () => {
const message = onImport(value);
@@ -37,12 +39,18 @@ export function ImportDialog({
setError(message);
return;
}
- onOpenChange(false);
+ handleOpenChange(false);
};
return (
-
{config.llm_type === "code" && (
diff --git a/studio/frontend/src/features/canvas-lab/dialogs/models/model-config-dialog.tsx b/studio/frontend/src/features/canvas-lab/dialogs/models/model-config-dialog.tsx
index 0848ac0ee1..899e79ee34 100644
--- a/studio/frontend/src/features/canvas-lab/dialogs/models/model-config-dialog.tsx
+++ b/studio/frontend/src/features/canvas-lab/dialogs/models/model-config-dialog.tsx
@@ -1,6 +1,14 @@
import { Checkbox } from "@/components/ui/checkbox";
+import {
+ Combobox,
+ ComboboxContent,
+ ComboboxEmpty,
+ ComboboxInput,
+ ComboboxItem,
+ ComboboxList,
+} from "@/components/ui/combobox";
import { Input } from "@/components/ui/input";
-import type { ReactElement } from "react";
+import { type ReactElement, useMemo, useRef } from "react";
import type { ModelConfig } from "../../types";
import { useCanvasLabStore } from "../../stores/canvas-lab";
import { NameField } from "../shared/name-field";
@@ -14,17 +22,20 @@ export function ModelConfigDialog({
config,
onUpdate,
}: ModelConfigDialogProps): ReactElement {
- const providerOptions = useCanvasLabStore((state) =>
- Object.values(state.configs)
- .filter((item) => item.kind === "model_provider")
- .map((item) => item.name),
+ const configs = useCanvasLabStore((state) => state.configs);
+ const providerOptions = useMemo(
+ () =>
+ Object.values(configs)
+ .filter((item) => item.kind === "model_provider")
+ .map((item) => item.name),
+ [configs],
);
const modelId = `${config.id}-model`;
const providerId = `${config.id}-provider`;
- const providerListId = `${config.id}-provider-list`;
const tempId = `${config.id}-temperature`;
const topPId = `${config.id}-top-p`;
const maxTokensId = `${config.id}-max-tokens`;
+ const providerAnchorRef = useRef
(null);
const updateField = (
key: K,
value: ModelConfig[K],
@@ -60,18 +71,37 @@ export function ModelConfigDialog({
>
Provider name
- updateField("provider", event.target.value)}
- />
-
+
+ updateField("provider", value ?? "")}
+ onInputValueChange={(value) => updateField("provider", value)}
+ itemToStringValue={(value) => value}
+ autoHighlight={true}
+ >
+
+
+ No providers found
+
+ {(provider: string) => (
+
+ {provider}
+
+ )}
+
+
+
+
+
+ Pick provider name from list. Matching node link becomes semantic.
+