temp commit

This commit is contained in:
yuneng-jiang 2026-03-13 17:12:30 -07:00
parent 0e44c460b5
commit c6da45795b
3 changed files with 138 additions and 3 deletions

View File

@ -0,0 +1,52 @@
import React from "react";
import { Select } from "antd";
import { Organization } from "../networking";
interface OrganizationDropdownProps {
organizations?: Organization[] | null;
value?: string;
onChange?: (value: string) => void;
disabled?: boolean;
loading?: boolean;
}
const OrganizationDropdown: React.FC<OrganizationDropdownProps> = ({
organizations,
value,
onChange,
disabled,
loading,
}) => {
return (
<Select
showSearch
placeholder="Search or select an organization"
value={value}
onChange={onChange}
disabled={disabled}
loading={loading}
allowClear
filterOption={(input, option) => {
if (!option) return false;
const org = organizations?.find((o) => o.organization_id === option.key);
if (!org) return false;
const searchTerm = input.toLowerCase().trim();
const orgAlias = (org.organization_alias || "").toLowerCase();
const orgId = (org.organization_id || "").toLowerCase();
return orgAlias.includes(searchTerm) || orgId.includes(searchTerm);
}}
optionFilterProp="children"
>
{organizations?.map((org) => (
<Select.Option key={org.organization_id} value={org.organization_id}>
<span className="font-medium">{org.organization_alias}</span>{" "}
<span className="text-gray-500">({org.organization_id})</span>
</Select.Option>
))}
</Select>
);
};
export default OrganizationDropdown;

View File

@ -1,5 +1,6 @@
"use client";
import { keyKeys } from "@/app/(dashboard)/hooks/keys/useKeys";
import { useOrganizations } from "@/app/(dashboard)/hooks/organizations/useOrganizations";
import { useProjects } from "@/app/(dashboard)/hooks/projects/useProjects";
import { useUISettings } from "@/app/(dashboard)/hooks/uiSettings/useUISettings";
import useAuthorized from "@/app/(dashboard)/hooks/useAuthorized";
@ -23,6 +24,7 @@ import PremiumLoggingSettings from "../common_components/PremiumLoggingSettings"
import RateLimitTypeFormItem from "../common_components/RateLimitTypeFormItem";
import RouterSettingsAccordion, { RouterSettingsAccordionValue } from "../common_components/RouterSettingsAccordion";
import TeamDropdown from "../common_components/team_dropdown";
import OrganizationDropdown from "../common_components/OrganizationDropdown";
import ProjectDropdown from "../common_components/ProjectDropdown";
import { CreateUserButton } from "../CreateUserButton";
import { getModelDisplayName } from "../key_team_helpers/fetch_available_models_team_key";
@ -160,6 +162,7 @@ export const fetchUserModels = async (
const CreateKey: React.FC<CreateKeyProps> = ({ team, teams, data, addKey, autoOpenCreate, prefillData }) => {
const { accessToken, userId: userID, userRole, premiumUser } = useAuthorized();
const canEditGuardrails = premiumUser || (userRole != null && rolesWithWriteAccess.includes(userRole));
const { data: organizations, isLoading: isOrganizationsLoading } = useOrganizations();
const { data: projects, isLoading: isProjectsLoading } = useProjects();
const { data: uiSettingsData } = useUISettings();
const enableProjectsUI = Boolean(uiSettingsData?.values?.enable_projects_ui);
@ -179,6 +182,7 @@ const CreateKey: React.FC<CreateKeyProps> = ({ team, teams, data, addKey, autoOp
const [promptsList, setPromptsList] = useState<string[]>([]);
const [loggingSettings, setLoggingSettings] = useState<any[]>([]);
const [selectedCreateKeyTeam, setSelectedCreateKeyTeam] = useState<Team | null>(team);
const [selectedOrganizationId, setSelectedOrganizationId] = useState<string | null>(null);
const [selectedProjectId, setSelectedProjectId] = useState<string | null>(null);
const [isCreateUserModalVisible, setIsCreateUserModalVisible] = useState(false);
const [newlyCreatedUserId, setNewlyCreatedUserId] = useState<string | null>(null);
@ -207,6 +211,7 @@ const CreateKey: React.FC<CreateKeyProps> = ({ team, teams, data, addKey, autoOp
setRouterSettings(null);
setRouterSettingsKey((prev) => prev + 1);
setSelectedAgentId(null);
setSelectedOrganizationId(null);
setSelectedProjectId(null);
};
@ -224,6 +229,7 @@ const CreateKey: React.FC<CreateKeyProps> = ({ team, teams, data, addKey, autoOp
setRouterSettings(null);
setRouterSettingsKey((prev) => prev + 1);
setSelectedAgentId(null);
setSelectedOrganizationId(null);
setSelectedProjectId(null);
};
@ -752,6 +758,32 @@ const CreateKey: React.FC<CreateKeyProps> = ({ team, teams, data, addKey, autoOp
</div>
</div>
)}
<Form.Item
label={
<span>
Organization{" "}
<Tooltip title="The organization this key belongs to. Selecting an organization filters the available teams.">
<InfoCircleOutlined style={{ marginLeft: "4px" }} />
</Tooltip>
</span>
}
name="organization_id"
className="mt-4"
>
<OrganizationDropdown
organizations={organizations}
loading={isOrganizationsLoading}
disabled={userRole !== "Admin"}
onChange={(orgId) => {
setSelectedOrganizationId(orgId || null);
// Clear team and project when org changes
setSelectedCreateKeyTeam(null);
setSelectedProjectId(null);
form.setFieldValue("team_id", undefined);
form.setFieldValue("project_id", undefined);
}}
/>
</Form.Item>
<Form.Item
label={
<span>
@ -773,7 +805,7 @@ const CreateKey: React.FC<CreateKeyProps> = ({ team, teams, data, addKey, autoOp
help={keyOwner === "service_account" ? "required" : ""}
>
<TeamDropdown
teams={teams}
teams={selectedOrganizationId ? teams?.filter((t) => t.organization_id === selectedOrganizationId) : teams}
disabled={selectedProjectId !== null}
loading={!teams}
onChange={(teamId) => {
@ -781,6 +813,14 @@ const CreateKey: React.FC<CreateKeyProps> = ({ team, teams, data, addKey, autoOp
setSelectedCreateKeyTeam(selectedTeam);
setSelectedProjectId(null);
form.setFieldValue("project_id", undefined);
// Auto-populate org from team for non-admin users
if (selectedTeam?.organization_id) {
setSelectedOrganizationId(selectedTeam.organization_id);
form.setFieldValue("organization_id", selectedTeam.organization_id);
} else if (!teamId) {
setSelectedOrganizationId(null);
form.setFieldValue("organization_id", undefined);
}
}}
/>
</Form.Item>
@ -1531,6 +1571,7 @@ const CreateKey: React.FC<CreateKeyProps> = ({ team, teams, data, addKey, autoOp
excludedFields={[
"key_alias",
"team_id",
"organization_id",
"models",
"duration",
"metadata",

View File

@ -1,4 +1,5 @@
import GuardrailSelector from "@/components/guardrails/GuardrailSelector";
import { useOrganizations } from "@/app/(dashboard)/hooks/organizations/useOrganizations";
import { useProjects } from "@/app/(dashboard)/hooks/projects/useProjects";
import { useUISettings } from "@/app/(dashboard)/hooks/uiSettings/useUISettings";
import PolicySelector from "@/components/policies/PolicySelector";
@ -13,6 +14,7 @@ import { mapInternalToDisplayNames } from "../callback_info_helpers";
import KeyLifecycleSettings from "../common_components/KeyLifecycleSettings";
import PassThroughRoutesSelector from "../common_components/PassThroughRoutesSelector";
import RateLimitTypeFormItem from "../common_components/RateLimitTypeFormItem";
import OrganizationDropdown from "../common_components/OrganizationDropdown";
import { extractLoggingSettings, formatMetadataForDisplay, stripTagsFromMetadata } from "../key_info_utils";
import { KeyResponse } from "../key_team_helpers/key_list";
import MCPServerSelector from "../mcp_server_management/MCPServerSelector";
@ -96,10 +98,12 @@ export function KeyEditView({
? mapInternalToDisplayNames(keyData.metadata.litellm_disabled_callbacks)
: [],
);
const [selectedOrganizationId, setSelectedOrganizationId] = useState<string | null>(keyData.organization_id || null);
const [autoRotationEnabled, setAutoRotationEnabled] = useState<boolean>(keyData.auto_rotate || false);
const [rotationInterval, setRotationInterval] = useState<string>(keyData.rotation_interval || "");
const [neverExpire, setNeverExpire] = useState<boolean>(!keyData.expires);
const [isKeySaving, setIsKeySaving] = useState(false);
const { data: organizations, isLoading: isOrganizationsLoading } = useOrganizations();
const { data: projects } = useProjects();
const { data: uiSettingsData } = useUISettings();
const enableProjectsUI = Boolean(uiSettingsData?.values?.enable_projects_ui);
@ -610,6 +614,28 @@ export function KeyEditView({
/>
</Form.Item>
<Form.Item
label={
<span>
Organization{" "}
<Tooltip title="The organization this key belongs to. Selecting an organization filters the available teams.">
<InfoCircleOutlined style={{ marginLeft: "4px" }} />
</Tooltip>
</span>
}
name="organization_id"
>
<OrganizationDropdown
organizations={organizations}
loading={isOrganizationsLoading}
disabled={userRole !== "Admin"}
onChange={(orgId) => {
setSelectedOrganizationId(orgId || null);
form.setFieldValue("team_id", undefined);
}}
/>
</Form.Item>
<Form.Item
label="Team ID"
name="team_id"
@ -620,13 +646,29 @@ export function KeyEditView({
showSearch
disabled={enableProjectsUI && hasProject}
style={{ width: "100%" }}
onChange={(teamId) => {
const selectedTeam = teams?.find((t) => t.team_id === teamId) || null;
if (selectedTeam?.organization_id) {
setSelectedOrganizationId(selectedTeam.organization_id);
form.setFieldValue("organization_id", selectedTeam.organization_id);
} else if (!teamId) {
setSelectedOrganizationId(null);
form.setFieldValue("organization_id", undefined);
}
}}
filterOption={(input, option) => {
const team = teams?.find((t) => t.team_id === option?.value);
const filteredTeams = selectedOrganizationId
? teams?.filter((t) => t.organization_id === selectedOrganizationId)
: teams;
const team = filteredTeams?.find((t) => t.team_id === option?.value);
if (!team) return false;
return team.team_alias?.toLowerCase().includes(input.toLowerCase()) ?? false;
}}
>
{teams?.map((team) => (
{(selectedOrganizationId
? teams?.filter((t) => t.organization_id === selectedOrganizationId)
: teams
)?.map((team) => (
<Select.Option key={team.team_id} value={team.team_id}>
{`${team.team_alias} (${team.team_id})`}
</Select.Option>