'use client' import type { CredentialSlot } from '@dify/contracts/enterprise/types.gen' import type { RuntimeCredentialBindingSelections, RuntimeCredentialSelectOption, } from './runtime-credential-bindings-utils' import { cn } from '@langgenius/dify-ui/cn' import { Select, SelectContent, SelectItem, SelectItemIndicator, SelectItemText, SelectTrigger, } from '@langgenius/dify-ui/select' import { useTranslation } from 'react-i18next' import { hasMissingRequiredRuntimeCredentialBinding, runtimeCredentialCandidateOptions, runtimeCredentialProviderName, runtimeCredentialSlotKey, } from './runtime-credential-bindings-utils' import { TitleTooltip } from './title-tooltip' type RuntimeCredentialBindingsPanelProps = { slots: CredentialSlot[] selections: RuntimeCredentialBindingSelections title: string hint: string noBindingRequiredLabel: string noCredentialCandidatesLabel: string selectCredentialLabel: string missingRequiredLabel: string bindingCountLabel?: string showMissingRequired?: boolean listScrollable?: boolean onChange: (slotKey: string, value: string) => void className?: string listClassName?: string } function RuntimeCredentialSelect({ ariaLabel, value, options, placeholder, onChange, }: { ariaLabel: string value?: string options: RuntimeCredentialSelectOption[] placeholder: string onChange: (value: string) => void }) { const selectedOption = options.find((option) => option.value === value) return ( ) } export function RuntimeCredentialBindingsPanel({ slots, selections, title, hint, noBindingRequiredLabel, noCredentialCandidatesLabel, selectCredentialLabel, missingRequiredLabel, bindingCountLabel, showMissingRequired = false, listScrollable = true, onChange, className, listClassName, }: RuntimeCredentialBindingsPanelProps) { const { t } = useTranslation('plugin') return (
{title}
{slots.length > 0 && ( {bindingCountLabel ?? slots.length} )}
{hint}
{slots.length === 0 ? (
{noBindingRequiredLabel}
) : (
{slots.map((slot) => { const slotKey = runtimeCredentialSlotKey(slot) const candidates = runtimeCredentialCandidateOptions(slot) const selectedValue = selections[slotKey] const missing = showMissingRequired && hasMissingRequiredRuntimeCredentialBinding(slot, selectedValue) const slotName = runtimeCredentialProviderName(slot.providerId) ?? slotKey const categoryLabel = slot.category === 'PLUGIN_CATEGORY_MODEL' ? t(($) => $['categorySingle.model']) : slot.category === 'PLUGIN_CATEGORY_TOOL' ? t(($) => $['categorySingle.tool']) : undefined return (
{slotName}
{categoryLabel && ( {categoryLabel} )}
{candidates.length === 0 ? (
{noCredentialCandidatesLabel}
) : ( onChange(slotKey, value)} options={candidates} placeholder={selectCredentialLabel} /> )}
{missing && (
{missingRequiredLabel}
)}
) })}
)}
) }