mirror of
https://github.com/langgenius/dify.git
synced 2026-08-02 02:40:43 +08:00
161 lines
5.7 KiB
TypeScript
161 lines
5.7 KiB
TypeScript
import type {
|
|
ConfigurationMethodEnum,
|
|
CustomConfigurationModelFixedFields,
|
|
ModelProvider,
|
|
} from '@/app/components/header/account-setting/model-provider-page/declarations'
|
|
import { Button } from '@langgenius/dify-ui/button'
|
|
import { cn } from '@langgenius/dify-ui/cn'
|
|
import { Popover, PopoverContent, PopoverTrigger } from '@langgenius/dify-ui/popover'
|
|
import { Tooltip, TooltipContent, TooltipTrigger } from '@langgenius/dify-ui/tooltip'
|
|
import { memo, useCallback, useState } from 'react'
|
|
import { useTranslation } from 'react-i18next'
|
|
import { ModelModalModeEnum } from '@/app/components/header/account-setting/model-provider-page/declarations'
|
|
import { useCredentialPermissions } from '@/hooks/use-credential-permissions'
|
|
import ModelIcon from '../model-icon'
|
|
import { useAuth } from './hooks/use-auth'
|
|
import { useCanAddedModels } from './hooks/use-custom-models'
|
|
|
|
type AddCustomModelProps = {
|
|
provider: ModelProvider
|
|
configurationMethod: ConfigurationMethodEnum
|
|
currentCustomConfigurationModelFixedFields?: CustomConfigurationModelFixedFields
|
|
open?: boolean
|
|
onOpenChange?: (open: boolean) => void
|
|
}
|
|
const AddCustomModel = ({
|
|
provider,
|
|
configurationMethod,
|
|
currentCustomConfigurationModelFixedFields,
|
|
}: AddCustomModelProps) => {
|
|
const { t } = useTranslation()
|
|
const [open, setOpen] = useState(false)
|
|
const canAddedModels = useCanAddedModels(provider)
|
|
const noModels = !canAddedModels.length
|
|
const { canUseCredential, canCreateCredential } = useCredentialPermissions()
|
|
const { handleOpenModal: handleOpenModalForAddNewCustomModel } = useAuth(
|
|
provider,
|
|
configurationMethod,
|
|
currentCustomConfigurationModelFixedFields,
|
|
{
|
|
isModelCredential: true,
|
|
mode: ModelModalModeEnum.configCustomModel,
|
|
},
|
|
)
|
|
const { handleOpenModal: handleOpenModalForAddCustomModelToModelList } = useAuth(
|
|
provider,
|
|
configurationMethod,
|
|
currentCustomConfigurationModelFixedFields,
|
|
{
|
|
isModelCredential: true,
|
|
mode: ModelModalModeEnum.addCustomModelToModelList,
|
|
},
|
|
)
|
|
const notAllowCustomCredential = provider.allow_custom_token === false
|
|
const renderTrigger = useCallback(
|
|
(open?: boolean, onClick?: () => void) => {
|
|
const disabled = noModels ? !canCreateCredential : !canUseCredential && !canCreateCredential
|
|
const item = (
|
|
<Button
|
|
variant="ghost"
|
|
size="small"
|
|
onClick={onClick}
|
|
className={cn(
|
|
'text-text-tertiary',
|
|
open && 'bg-components-button-ghost-bg-hover',
|
|
notAllowCustomCredential && !!noModels && 'cursor-not-allowed opacity-50',
|
|
disabled && 'cursor-not-allowed opacity-50',
|
|
)}
|
|
>
|
|
<span className="mr-1 i-ri-add-circle-fill size-3.5" />
|
|
{t(($) => $['modelProvider.addModel'], { ns: 'common' })}
|
|
</Button>
|
|
)
|
|
if ((notAllowCustomCredential && !!noModels) || disabled) {
|
|
return (
|
|
<Tooltip>
|
|
<TooltipTrigger render={item} />
|
|
<TooltipContent>
|
|
{t(($) => $['auth.credentialUnavailable'], { ns: 'plugin' })}
|
|
</TooltipContent>
|
|
</Tooltip>
|
|
)
|
|
}
|
|
return item
|
|
},
|
|
[canCreateCredential, canUseCredential, t, notAllowCustomCredential, noModels],
|
|
)
|
|
|
|
if (noModels) {
|
|
return renderTrigger(
|
|
false,
|
|
notAllowCustomCredential || !canCreateCredential
|
|
? undefined
|
|
: handleOpenModalForAddNewCustomModel,
|
|
)
|
|
}
|
|
|
|
return (
|
|
<Popover open={open} onOpenChange={setOpen}>
|
|
<PopoverTrigger
|
|
nativeButton={false}
|
|
render={<div className="inline-block">{renderTrigger(open)}</div>}
|
|
/>
|
|
<PopoverContent
|
|
placement="bottom-end"
|
|
sideOffset={4}
|
|
popupClassName="border-0 bg-transparent p-0 shadow-none backdrop-blur-none"
|
|
>
|
|
<div className="w-[320px] rounded-xl border-[0.5px] border-components-panel-border bg-components-panel-bg-blur shadow-lg">
|
|
<div className="max-h-[304px] overflow-y-auto p-1">
|
|
{canAddedModels.map((model) => (
|
|
<div
|
|
key={model.model}
|
|
className={cn(
|
|
'flex h-8 items-center rounded-lg px-2',
|
|
canUseCredential
|
|
? 'cursor-pointer hover:bg-state-base-hover'
|
|
: 'cursor-not-allowed opacity-50',
|
|
)}
|
|
aria-disabled={!canUseCredential}
|
|
onClick={() => {
|
|
if (!canUseCredential) return
|
|
|
|
setOpen(false)
|
|
handleOpenModalForAddCustomModelToModelList(undefined, model)
|
|
}}
|
|
>
|
|
<ModelIcon
|
|
className="mr-1 size-5 shrink-0"
|
|
iconClassName="h-5 w-5"
|
|
provider={provider}
|
|
modelName={model.model}
|
|
/>
|
|
<div
|
|
className="grow truncate system-md-regular text-text-primary"
|
|
title={model.model}
|
|
>
|
|
{model.model}
|
|
</div>
|
|
</div>
|
|
))}
|
|
</div>
|
|
{!notAllowCustomCredential && canCreateCredential && (
|
|
<div
|
|
className="flex cursor-pointer items-center border-t border-t-divider-subtle p-3 system-xs-medium text-text-accent-light-mode-only"
|
|
onClick={() => {
|
|
setOpen(false)
|
|
handleOpenModalForAddNewCustomModel()
|
|
}}
|
|
>
|
|
<span className="mr-1 i-ri-add-line size-4" />
|
|
{t(($) => $['modelProvider.auth.addNewModel'], { ns: 'common' })}
|
|
</div>
|
|
)}
|
|
</div>
|
|
</PopoverContent>
|
|
</Popover>
|
|
)
|
|
}
|
|
|
|
export default memo(AddCustomModel)
|