Files
dify/web/app/components/plugins/install-plugin/install-from-github/steps/selectPackage.tsx
Stephen Zhou a84c2d36a3 style: format with vp fmt (#38803)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-12 15:57:46 +00:00

183 lines
6.2 KiB
TypeScript

'use client'
import type { PluginDeclaration, UpdateFromGitHubPayload } from '../../../types'
import { Button } from '@langgenius/dify-ui/button'
import { Field } from '@langgenius/dify-ui/field'
import {
Select,
SelectContent,
SelectItem,
SelectItemIndicator,
SelectItemText,
SelectLabel,
SelectTrigger,
} from '@langgenius/dify-ui/select'
import * as React from 'react'
import { useTranslation } from 'react-i18next'
import Badge from '@/app/components/base/badge'
import { handleUpload } from '../../hooks'
const i18nPrefix = 'installFromGitHub'
type SelectOption = {
value: string
name: string
}
type SelectPackageProps = {
updatePayload: UpdateFromGitHubPayload
repoUrl: string
selectedVersion: string
versions: SelectOption[]
onSelectVersion: (item: SelectOption) => void
selectedPackage: string
packages: SelectOption[]
onSelectPackage: (item: SelectOption) => void
onUploaded: (result: { uniqueIdentifier: string; manifest: PluginDeclaration }) => void
onFailed: (errorMsg: string) => void
onBack: () => void
}
const SelectPackage: React.FC<SelectPackageProps> = ({
updatePayload,
repoUrl,
selectedVersion,
versions,
onSelectVersion,
selectedPackage,
packages,
onSelectPackage,
onUploaded,
onFailed,
onBack,
}) => {
const { t } = useTranslation()
const isEdit = Boolean(updatePayload)
const [isUploading, setIsUploading] = React.useState(false)
const selectedVersionOption = versions.find((item) => item.value === selectedVersion) ?? null
const selectedPackageOption = packages.find((item) => item.value === selectedPackage) ?? null
const handleUploadPackage = async () => {
if (isUploading) return
setIsUploading(true)
try {
const repo = repoUrl.replace('https://github.com/', '')
await handleUpload(repo, selectedVersion, selectedPackage, (GitHubPackage) => {
onUploaded({
uniqueIdentifier: GitHubPackage.unique_identifier,
manifest: GitHubPackage.manifest,
})
})
} catch (e: any) {
if (e.response?.message) onFailed(e.response?.message)
else onFailed(t(($) => $[`${i18nPrefix}.uploadFailed`], { ns: 'plugin' }))
} finally {
setIsUploading(false)
}
}
return (
<>
<Field name="version" className="gap-4 self-stretch">
<Select
value={selectedVersionOption?.value ?? null}
onValueChange={(value) => {
if (value == null) return
const selectedItem = versions.find((item) => item.value === value)
if (selectedItem) onSelectVersion(selectedItem)
}}
>
<SelectLabel className="flex w-full flex-col items-start justify-center p-0 text-text-secondary">
<span className="system-sm-semibold">
{t(($) => $[`${i18nPrefix}.selectVersion`], { ns: 'plugin' })}
</span>
</SelectLabel>
<SelectTrigger className="h-9 text-components-input-text-filled">
<div className="flex items-center justify-between gap-2">
<span className="truncate">
{selectedVersionOption?.name ??
t(($) => $[`${i18nPrefix}.selectVersionPlaceholder`], { ns: 'plugin' }) ??
''}
</span>
{!!(
updatePayload?.originalPackageInfo.version &&
selectedVersionOption &&
selectedVersionOption.value !== updatePayload.originalPackageInfo.version
) && (
<Badge>
{updatePayload.originalPackageInfo.version} {'->'} {selectedVersionOption.value}
</Badge>
)}
</div>
</SelectTrigger>
<SelectContent popupClassName="w-[512px]">
{versions.map((item) => (
<SelectItem key={item.value} value={item.value}>
<SelectItemText>{item.name}</SelectItemText>
{item.value === updatePayload?.originalPackageInfo.version && (
<Badge uppercase={true} className="ml-1 shrink-0">
INSTALLED
</Badge>
)}
<SelectItemIndicator />
</SelectItem>
))}
</SelectContent>
</Select>
</Field>
<Field name="package" className="gap-4 self-stretch">
<Select
value={selectedPackageOption?.value ?? null}
readOnly={!selectedVersion}
onValueChange={(value) => {
if (value == null) return
const selectedItem = packages.find((item) => item.value === value)
if (selectedItem) onSelectPackage(selectedItem)
}}
>
<SelectLabel className="flex w-full flex-col items-start justify-center p-0 text-text-secondary">
<span className="system-sm-semibold">
{t(($) => $[`${i18nPrefix}.selectPackage`], { ns: 'plugin' })}
</span>
</SelectLabel>
<SelectTrigger className="h-9 text-components-input-text-filled">
{selectedPackageOption?.name ??
t(($) => $[`${i18nPrefix}.selectPackagePlaceholder`], { ns: 'plugin' }) ??
''}
</SelectTrigger>
<SelectContent popupClassName="w-[512px]">
{packages.map((item) => (
<SelectItem key={item.value} value={item.value}>
<SelectItemText>{item.name}</SelectItemText>
<SelectItemIndicator />
</SelectItem>
))}
</SelectContent>
</Select>
</Field>
<div className="mt-4 flex items-center justify-end gap-2 self-stretch">
{!isEdit && (
<Button
variant="secondary"
className="min-w-[72px]"
onClick={onBack}
disabled={isUploading}
>
{t(($) => $['installModal.back'], { ns: 'plugin' })}
</Button>
)}
<Button
variant="primary"
className="min-w-[72px]"
onClick={handleUploadPackage}
disabled={!selectedVersion || !selectedPackage || isUploading}
>
{t(($) => $['installModal.next'], { ns: 'plugin' })}
</Button>
</div>
</>
)
}
export default SelectPackage