fix(web): align CLI user credentials picker with MCP pattern

Replace raw Combobox + useUserPicker with UserPickerCombobox
component (source="tenant_user") to match MCP user credentials
dialog. Both systems use the same runtime user ID from context.
This commit is contained in:
viettranx committed 2026-04-02 15:15:36 +07:00
1 parent ddc5964b85
commit 5bad031908
1 file changed
+4 -12
@@ -12,11 +12,10 @@ import {
import { Button } from "@/components/ui/button";
import { Label } from "@/components/ui/label";
import { Badge } from "@/components/ui/badge";
import { Combobox } from "@/components/ui/combobox";
import { UserPickerCombobox } from "@/components/shared/user-picker-combobox";
import { KeyValueEditor } from "@/components/shared/key-value-editor";
import { toast } from "@/stores/use-toast-store";
import { useHttp } from "@/hooks/use-ws";
import { useUserPicker } from "@/hooks/use-user-picker";
import i18next from "i18next";
import type { SecureCLIBinary } from "./hooks/use-cli-credentials";
@@ -53,13 +52,11 @@ export function CLIUserCredentialsDialog({ open, onOpenChange, binary }: CLIUser
// Form state
const [editEntry, setEditEntry] = useState<UserCredEntry | null>(null);
const [userId, setUserId] = useState("");
const [userSearch, setUserSearch] = useState("");
const [env, setEnv] = useState<Record<string, string>>({});
const [saving, setSaving] = useState(false);
const [deleting, setDeletingId] = useState<string | null>(null);
// User picker for the form
const { options: userOptions } = useUserPicker(userSearch, undefined, "tenant_user");
const loadList = useCallback(async () => {
setLoadingList(true);
@@ -80,7 +77,6 @@ export function CLIUserCredentialsDialog({ open, onOpenChange, binary }: CLIUser
setView("list");
setEditEntry(null);
setUserId("");
setUserSearch("");
setEnv({});
loadList();
}, [open, loadList]);
@@ -88,7 +84,6 @@ export function CLIUserCredentialsDialog({ open, onOpenChange, binary }: CLIUser
const openAdd = () => {
setEditEntry(null);
setUserId("");
setUserSearch("");
setEnv({});
setView("form");
};
@@ -96,7 +91,6 @@ export function CLIUserCredentialsDialog({ open, onOpenChange, binary }: CLIUser
const openEdit = async (entry: UserCredEntry) => {
setEditEntry(entry);
setUserId(entry.user_id);
setUserSearch("");
setEnv({});
setView("form");
// Load existing env for edit
@@ -239,14 +233,12 @@ export function CLIUserCredentialsDialog({ open, onOpenChange, binary }: CLIUser
<div className="flex flex-col gap-4 max-h-[60vh] overflow-y-auto pr-1">
<div className="flex flex-col gap-1.5">
<Label>{t("userCredentials.userId")}</Label>
<Combobox
<UserPickerCombobox
value={userId}
onChange={(v) => { setUserId(v); setUserSearch(v); }}
onSelect={(v) => setUserId(v)}
options={userOptions}
onChange={setUserId}
placeholder={t("userCredentials.userIdPlaceholder")}
source="tenant_user"
allowCustom
className="text-base md:text-sm font-mono"
/>
</div>