mirror of
https://github.com/tiennm99/litellm.git
synced 2026-07-12 17:04:30 +00:00
polish changes
This commit is contained in:
+1
-3
@@ -1,8 +1,6 @@
|
||||
import { deleteHashicorpVaultConfig } from "@/components/networking";
|
||||
import { useMutation, useQueryClient } from "@tanstack/react-query";
|
||||
import { createQueryKeys } from "../common/queryKeysFactory";
|
||||
|
||||
const hashicorpVaultKeys = createQueryKeys("hashicorpVaultConfig");
|
||||
import { hashicorpVaultKeys } from "./useHashicorpVaultConfig";
|
||||
|
||||
export const useDeleteHashicorpVaultConfig = (accessToken: string | null) => {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@ import { useQuery } from "@tanstack/react-query";
|
||||
import useAuthorized from "../useAuthorized";
|
||||
import { createQueryKeys } from "../common/queryKeysFactory";
|
||||
|
||||
const hashicorpVaultKeys = createQueryKeys("hashicorpVaultConfig");
|
||||
export const hashicorpVaultKeys = createQueryKeys("hashicorpVaultConfig");
|
||||
|
||||
export const useHashicorpVaultConfig = () => {
|
||||
const { accessToken } = useAuthorized();
|
||||
|
||||
+1
-3
@@ -1,8 +1,6 @@
|
||||
import { updateHashicorpVaultConfig } from "@/components/networking";
|
||||
import { useMutation, useQueryClient } from "@tanstack/react-query";
|
||||
import { createQueryKeys } from "../common/queryKeysFactory";
|
||||
|
||||
const hashicorpVaultKeys = createQueryKeys("hashicorpVaultConfig");
|
||||
import { hashicorpVaultKeys } from "./useHashicorpVaultConfig";
|
||||
|
||||
export const useUpdateHashicorpVaultConfig = (accessToken: string | null) => {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
+3
-3
@@ -50,7 +50,7 @@ const EditHashicorpVaultModal: React.FC<EditHashicorpVaultModalProps> = ({
|
||||
const [form] = Form.useForm();
|
||||
const { accessToken } = useAuthorized();
|
||||
const { data } = useHashicorpVaultConfig();
|
||||
const { mutateAsync, isPending } = useUpdateHashicorpVaultConfig(accessToken);
|
||||
const { mutate, isPending } = useUpdateHashicorpVaultConfig(accessToken);
|
||||
|
||||
const schema = data?.field_schema;
|
||||
const properties = schema?.properties ?? {};
|
||||
@@ -70,7 +70,7 @@ const EditHashicorpVaultModal: React.FC<EditHashicorpVaultModalProps> = ({
|
||||
}
|
||||
}, [isVisible, data, form]);
|
||||
|
||||
const handleSubmit = async (formValues: Record<string, any>) => {
|
||||
const handleSubmit = (formValues: Record<string, any>) => {
|
||||
const config: Record<string, any> = {};
|
||||
for (const [key, value] of Object.entries(formValues)) {
|
||||
if (value !== undefined && value !== null && value !== "") {
|
||||
@@ -83,7 +83,7 @@ const EditHashicorpVaultModal: React.FC<EditHashicorpVaultModalProps> = ({
|
||||
// Sensitive field left blank → omit from payload (keep existing)
|
||||
}
|
||||
|
||||
await mutateAsync(config, {
|
||||
mutate(config, {
|
||||
onSuccess: () => {
|
||||
NotificationManager.success("Hashicorp Vault configuration updated successfully");
|
||||
onSuccess();
|
||||
|
||||
+76
-84
@@ -28,14 +28,13 @@ const descriptionsConfig = {
|
||||
|
||||
export default function HashicorpVault() {
|
||||
const { accessToken } = useAuthorized();
|
||||
const { data, isLoading, isError, error, refetch } = useHashicorpVaultConfig();
|
||||
const { data, isLoading, isError, error } = useHashicorpVaultConfig();
|
||||
const { mutate: deleteConfig, isPending: isDeleting } = useDeleteHashicorpVaultConfig(accessToken);
|
||||
const { mutateAsync: updateConfig } = useUpdateHashicorpVaultConfig(accessToken);
|
||||
const { mutate: updateConfig, isPending: isClearingField } = useUpdateHashicorpVaultConfig(accessToken);
|
||||
|
||||
const [isEditModalVisible, setIsEditModalVisible] = useState(false);
|
||||
const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false);
|
||||
const [clearingField, setClearingField] = useState<string | null>(null);
|
||||
const [isClearingField, setIsClearingField] = useState(false);
|
||||
const [isTesting, setIsTesting] = useState(false);
|
||||
|
||||
const rawValues = data?.values ?? {};
|
||||
@@ -66,19 +65,17 @@ export default function HashicorpVault() {
|
||||
});
|
||||
};
|
||||
|
||||
const handleClearField = async () => {
|
||||
const handleClearField = () => {
|
||||
if (!clearingField) return;
|
||||
setIsClearingField(true);
|
||||
try {
|
||||
await updateConfig({ [clearingField]: "" });
|
||||
NotificationManager.success(`${FIELD_LABELS[clearingField] ?? clearingField} cleared`);
|
||||
setClearingField(null);
|
||||
refetch();
|
||||
} catch (err) {
|
||||
NotificationManager.fromBackend(err);
|
||||
} finally {
|
||||
setIsClearingField(false);
|
||||
}
|
||||
updateConfig({ [clearingField]: "" }, {
|
||||
onSuccess: () => {
|
||||
NotificationManager.success(`${FIELD_LABELS[clearingField] ?? clearingField} cleared`);
|
||||
setClearingField(null);
|
||||
},
|
||||
onError: (err) => {
|
||||
NotificationManager.fromBackend(err);
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const renderValue = (key: string) => {
|
||||
@@ -140,84 +137,79 @@ export default function HashicorpVault() {
|
||||
/>
|
||||
</Card>
|
||||
) : (
|
||||
<Space direction="vertical" size="large" className="w-full">
|
||||
<Card>
|
||||
<Space direction="vertical" size="large" className="w-full">
|
||||
{/* Header */}
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex items-center gap-3">
|
||||
<KeyRound className="w-6 h-6 text-gray-400" />
|
||||
<div>
|
||||
<Title level={3} style={{ marginBottom: 0 }}>Hashicorp Vault</Title>
|
||||
<Text type="secondary">Manage secret manager configuration</Text>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-3">
|
||||
{isConfigured && (
|
||||
<>
|
||||
<Button
|
||||
icon={<PlugZap className="w-4 h-4" />}
|
||||
loading={isTesting}
|
||||
onClick={handleTestConnection}
|
||||
>
|
||||
Test Connection
|
||||
</Button>
|
||||
<Button
|
||||
icon={<Edit className="w-4 h-4" />}
|
||||
onClick={() => setIsEditModalVisible(true)}
|
||||
>
|
||||
Edit Configuration
|
||||
</Button>
|
||||
<Button
|
||||
danger
|
||||
icon={<Trash2 className="w-4 h-4" />}
|
||||
onClick={() => setIsDeleteModalOpen(true)}
|
||||
>
|
||||
Delete Configuration
|
||||
</Button>
|
||||
</>
|
||||
)}
|
||||
<Card>
|
||||
<Space direction="vertical" size="large" className="w-full">
|
||||
{/* Header */}
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex items-center gap-3">
|
||||
<KeyRound className="w-6 h-6 text-gray-400" />
|
||||
<div>
|
||||
<Title level={3} style={{ marginBottom: 0 }}>Hashicorp Vault</Title>
|
||||
<Text type="secondary">Manage secret manager configuration</Text>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{isConfigured && (
|
||||
<Alert
|
||||
type="info"
|
||||
showIcon
|
||||
message="Secrets must be stored with the field name "key""
|
||||
description={
|
||||
<>
|
||||
<Text code>vault kv put secret/SECRET_NAME key=secret_value</Text>
|
||||
<br />
|
||||
<Typography.Link
|
||||
href="https://docs.litellm.ai/docs/secret_managers/hashicorp_vault"
|
||||
target="_blank"
|
||||
>
|
||||
View documentation
|
||||
</Typography.Link>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
)}
|
||||
<div className="flex items-center gap-3">
|
||||
{isConfigured && (
|
||||
<>
|
||||
<Button
|
||||
icon={<PlugZap className="w-4 h-4" />}
|
||||
loading={isTesting}
|
||||
onClick={handleTestConnection}
|
||||
>
|
||||
Test Connection
|
||||
</Button>
|
||||
<Button
|
||||
icon={<Edit className="w-4 h-4" />}
|
||||
onClick={() => setIsEditModalVisible(true)}
|
||||
>
|
||||
Edit Configuration
|
||||
</Button>
|
||||
<Button
|
||||
danger
|
||||
icon={<Trash2 className="w-4 h-4" />}
|
||||
onClick={() => setIsDeleteModalOpen(true)}
|
||||
>
|
||||
Delete Configuration
|
||||
</Button>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{isConfigured ? (
|
||||
renderSettings()
|
||||
) : (
|
||||
<HashicorpVaultEmptyPlaceholder onAdd={() => setIsEditModalVisible(true)} />
|
||||
)}
|
||||
</Space>
|
||||
</Card>
|
||||
</Space>
|
||||
{isConfigured && (
|
||||
<Alert
|
||||
type="info"
|
||||
showIcon
|
||||
message={'Secrets must be stored with the field name "key"'}
|
||||
description={
|
||||
<>
|
||||
<Text code>vault kv put secret/SECRET_NAME key=secret_value</Text>
|
||||
<br />
|
||||
<Typography.Link
|
||||
href="https://docs.litellm.ai/docs/secret_managers/hashicorp_vault"
|
||||
target="_blank"
|
||||
>
|
||||
View documentation
|
||||
</Typography.Link>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
)}
|
||||
|
||||
{isConfigured ? (
|
||||
renderSettings()
|
||||
) : (
|
||||
<HashicorpVaultEmptyPlaceholder onAdd={() => setIsEditModalVisible(true)} />
|
||||
)}
|
||||
</Space>
|
||||
</Card>
|
||||
)}
|
||||
|
||||
<EditHashicorpVaultModal
|
||||
isVisible={isEditModalVisible}
|
||||
onCancel={() => setIsEditModalVisible(false)}
|
||||
onSuccess={() => {
|
||||
setIsEditModalVisible(false);
|
||||
refetch();
|
||||
}}
|
||||
onSuccess={() => setIsEditModalVisible(false)}
|
||||
/>
|
||||
|
||||
<DeleteResourceModal
|
||||
|
||||
@@ -8893,11 +8893,7 @@ export const getHashicorpVaultConfig = async (accessToken: string) => {
|
||||
});
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json();
|
||||
const detail = errorData?.detail;
|
||||
const errorMessage =
|
||||
(typeof detail === "object" && detail?.error) ||
|
||||
(typeof detail === "string" && detail) ||
|
||||
deriveErrorMessage(errorData);
|
||||
const errorMessage = deriveErrorMessage(errorData);
|
||||
throw new Error(errorMessage);
|
||||
}
|
||||
const data = await response.json();
|
||||
|
||||
Reference in New Issue
Block a user