mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-09 03:18:44 +00:00
temp commit for merge
This commit is contained in:
parent
da5fbfe17c
commit
3e97c0d5d6
2 changed files with 130 additions and 0 deletions
|
|
@ -0,0 +1,112 @@
|
|||
import React from "react";
|
||||
import { Select, Skeleton } from "antd";
|
||||
import { TeamOutlined } from "@ant-design/icons";
|
||||
import { Text } from "@tremor/react";
|
||||
import {
|
||||
useAccessGroups,
|
||||
AccessGroupResponse,
|
||||
} from "@/app/(dashboard)/hooks/accessGroups/useAccessGroups";
|
||||
|
||||
export interface AccessGroupSelectorProps {
|
||||
value?: string[];
|
||||
onChange?: (value: string[]) => void;
|
||||
placeholder?: string;
|
||||
disabled?: boolean;
|
||||
style?: React.CSSProperties;
|
||||
className?: string;
|
||||
showLabel?: boolean;
|
||||
labelText?: string;
|
||||
/** Allow clearing the selection */
|
||||
allowClear?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reusable multi-select selector for access groups.
|
||||
*
|
||||
* - Displays the **access_group_name** in the dropdown.
|
||||
* - Returns an array of **access_group_id** values.
|
||||
* - Always multi-select since users can assign multiple access groups.
|
||||
* - Integrates with Ant Design `<Form.Item>` out of the box via `value` / `onChange`.
|
||||
*/
|
||||
const AccessGroupSelector: React.FC<AccessGroupSelectorProps> = ({
|
||||
value,
|
||||
onChange,
|
||||
placeholder = "Select access groups",
|
||||
disabled = false,
|
||||
style,
|
||||
className,
|
||||
showLabel = false,
|
||||
labelText = "Access Group",
|
||||
allowClear = true,
|
||||
}) => {
|
||||
const { data: accessGroups, isLoading, isError } = useAccessGroups();
|
||||
|
||||
// ── Loading skeleton ─────────────────────────────────────────────────────
|
||||
if (isLoading) {
|
||||
return (
|
||||
<div>
|
||||
{showLabel && (
|
||||
<Text className="font-medium block mb-2 text-gray-700 flex items-center">
|
||||
<TeamOutlined className="mr-2" /> {labelText}
|
||||
</Text>
|
||||
)}
|
||||
<Skeleton.Input active block style={{ height: 32, ...style }} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// ── Build options ────────────────────────────────────────────────────────
|
||||
const options = (accessGroups ?? []).map((group: AccessGroupResponse) => ({
|
||||
label: (
|
||||
<span>
|
||||
<span className="font-medium">{group.access_group_name}</span>{" "}
|
||||
<span className="text-gray-400 text-xs">({group.access_group_id})</span>
|
||||
</span>
|
||||
),
|
||||
value: group.access_group_id,
|
||||
selectedLabel: group.access_group_name,
|
||||
searchText: `${group.access_group_name} ${group.access_group_id}`,
|
||||
}));
|
||||
|
||||
// ── Render ───────────────────────────────────────────────────────────────
|
||||
return (
|
||||
<div>
|
||||
{showLabel && (
|
||||
<Text className="font-medium block mb-2 text-gray-700 flex items-center">
|
||||
<TeamOutlined className="mr-2" /> {labelText}
|
||||
</Text>
|
||||
)}
|
||||
<Select
|
||||
mode="multiple"
|
||||
value={value}
|
||||
placeholder={placeholder}
|
||||
onChange={onChange}
|
||||
disabled={disabled}
|
||||
allowClear={allowClear}
|
||||
showSearch
|
||||
style={{ width: "100%", ...style }}
|
||||
className={`rounded-md ${className ?? ""}`}
|
||||
notFoundContent={
|
||||
isError ? (
|
||||
<span className="text-red-500">Failed to load access groups</span>
|
||||
) : (
|
||||
"No access groups found"
|
||||
)
|
||||
}
|
||||
filterOption={(input, option) => {
|
||||
const searchText =
|
||||
options.find((opt) => opt.value === option?.value)?.searchText ?? "";
|
||||
return searchText.toLowerCase().includes(input.toLowerCase());
|
||||
}}
|
||||
optionLabelProp="selectedLabel"
|
||||
options={options.map((opt) => ({
|
||||
label: opt.label,
|
||||
value: opt.value,
|
||||
selectedLabel: opt.selectedLabel,
|
||||
}))}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default AccessGroupSelector;
|
||||
|
|
@ -20,6 +20,7 @@ import PassThroughRoutesSelector from "../common_components/PassThroughRoutesSel
|
|||
import PremiumLoggingSettings from "../common_components/PremiumLoggingSettings";
|
||||
import RateLimitTypeFormItem from "../common_components/RateLimitTypeFormItem";
|
||||
import RouterSettingsAccordion, { RouterSettingsAccordionValue } from "../common_components/RouterSettingsAccordion";
|
||||
import AccessGroupSelector from "../common_components/AccessGroupSelector";
|
||||
import TeamDropdown from "../common_components/team_dropdown";
|
||||
import { CreateUserButton } from "../CreateUserButton";
|
||||
import { getModelDisplayName } from "../key_team_helpers/fetch_available_models_team_key";
|
||||
|
|
@ -998,6 +999,23 @@ const CreateKey: React.FC<CreateKeyProps> = ({ team, teams, data, addKey }) => {
|
|||
options={promptsList.map((name) => ({ value: name, label: name }))}
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label={
|
||||
<span>
|
||||
Access Groups{" "}
|
||||
<Tooltip title="Assign access groups to this key. Access groups control which models, MCP servers, and agents this key can use">
|
||||
<InfoCircleOutlined style={{ marginLeft: "4px" }} />
|
||||
</Tooltip>
|
||||
</span>
|
||||
}
|
||||
name="access_group_ids"
|
||||
className="mt-4"
|
||||
help="Select access groups to assign to this key"
|
||||
>
|
||||
<AccessGroupSelector
|
||||
placeholder="Select access groups (optional)"
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label={
|
||||
<span>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue