mirror of https://github.com/langgenius/dify.git
chore: i18n for install from GitHub section
This commit is contained in:
parent
7751070da8
commit
18a266eac2
|
|
@ -3,33 +3,21 @@
|
|||
import React, { useState } from 'react'
|
||||
import Modal from '@/app/components/base/modal'
|
||||
import type { Item } from '@/app/components/base/select'
|
||||
import type { GitHubRepoReleaseResponse } from '@/app/components/plugins/types'
|
||||
import type { GitHubUrlInfo, InstallState } from '@/app/components/plugins/types'
|
||||
import { InstallStepFromGitHub } from '../../types'
|
||||
import Toast from '@/app/components/base/toast'
|
||||
import SetURL from './steps/setURL'
|
||||
import SetVersion from './steps/setVersion'
|
||||
import SetPackage from './steps/setPackage'
|
||||
import Installed from './steps/installed'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
type InstallFromGitHubProps = {
|
||||
onClose: () => void
|
||||
}
|
||||
|
||||
type GitHubUrlInfo = {
|
||||
isValid: boolean
|
||||
owner?: string
|
||||
repo?: string
|
||||
}
|
||||
|
||||
type InstallState = {
|
||||
step: InstallStepFromGitHub
|
||||
repoUrl: string
|
||||
selectedVersion: string
|
||||
selectedPackage: string
|
||||
releases: GitHubRepoReleaseResponse[]
|
||||
}
|
||||
|
||||
const InstallFromGitHub: React.FC<InstallFromGitHubProps> = ({ onClose }) => {
|
||||
const { t } = useTranslation()
|
||||
const [state, setState] = useState<InstallState>({
|
||||
step: InstallStepFromGitHub.setUrl,
|
||||
repoUrl: '',
|
||||
|
|
@ -92,7 +80,7 @@ const InstallFromGitHub: React.FC<InstallFromGitHubProps> = ({ onClose }) => {
|
|||
if (!isValid || !owner || !repo) {
|
||||
Toast.notify({
|
||||
type: 'error',
|
||||
message: 'Invalid GitHub URL. Please enter a valid URL in the format: https://github.com/owner/repo',
|
||||
message: t('plugin.error.inValidGitHubUrl'),
|
||||
})
|
||||
break
|
||||
}
|
||||
|
|
@ -151,10 +139,10 @@ const InstallFromGitHub: React.FC<InstallFromGitHubProps> = ({ onClose }) => {
|
|||
<div className='flex pt-6 pl-6 pb-3 pr-14 items-start gap-2 self-stretch'>
|
||||
<div className='flex flex-col items-start gap-1 flex-grow'>
|
||||
<div className='self-stretch text-text-primary title-2xl-semi-bold'>
|
||||
Install plugin from GitHub
|
||||
{t('plugin.installFromGitHub.installPlugin')}
|
||||
</div>
|
||||
<div className='self-stretch text-text-tertiary system-xs-regular'>
|
||||
{state.step !== InstallStepFromGitHub.installed && 'Please make sure that you only install plugins from a trusted source.'}
|
||||
{state.step !== InstallStepFromGitHub.installed && t('plugin.installFromGitHub.installNote')}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import React from 'react'
|
||||
import Button from '@/app/components/base/button'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
type InstalledProps = {
|
||||
repoUrl: string
|
||||
|
|
@ -23,28 +24,31 @@ const InfoRow = ({ label, value }: { label: string; value: string }) => (
|
|||
</div>
|
||||
)
|
||||
|
||||
const Installed: React.FC<InstalledProps> = ({ repoUrl, selectedVersion, selectedPackage, onClose }) => (
|
||||
<>
|
||||
<div className='text-text-secondary system-md-regular'>The plugin has been installed successfully.</div>
|
||||
<div className='flex w-full p-4 flex-col justify-center items-start gap-2 rounded-2xl bg-background-section-burn'>
|
||||
{[
|
||||
{ label: 'Repository', value: repoUrl },
|
||||
{ label: 'Version', value: selectedVersion },
|
||||
{ label: 'Package', value: selectedPackage },
|
||||
].map(({ label, value }) => (
|
||||
<InfoRow key={label} label={label} value={value} />
|
||||
))}
|
||||
</div>
|
||||
<div className='flex justify-end items-center gap-2 self-stretch mt-4'>
|
||||
<Button
|
||||
variant='primary'
|
||||
className='min-w-[72px]'
|
||||
onClick={onClose}
|
||||
>
|
||||
Close
|
||||
</Button>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
const Installed: React.FC<InstalledProps> = ({ repoUrl, selectedVersion, selectedPackage, onClose }) => {
|
||||
const { t } = useTranslation()
|
||||
return (
|
||||
<>
|
||||
<div className='text-text-secondary system-md-regular'>The plugin has been installed successfully.</div>
|
||||
<div className='flex w-full p-4 flex-col justify-center items-start gap-2 rounded-2xl bg-background-section-burn'>
|
||||
{[
|
||||
{ label: t('plugin.installModal.labels.repository'), value: repoUrl },
|
||||
{ label: t('plugin.installModal.labels.version'), value: selectedVersion },
|
||||
{ label: t('plugin.installModal.labels.package'), value: selectedPackage },
|
||||
].map(({ label, value }) => (
|
||||
<InfoRow key={label} label={label} value={value} />
|
||||
))}
|
||||
</div>
|
||||
<div className='flex justify-end items-center gap-2 self-stretch mt-4'>
|
||||
<Button
|
||||
variant='primary'
|
||||
className='min-w-[72px]'
|
||||
onClick={onClose}
|
||||
>
|
||||
{t('plugin.installModal.close')}
|
||||
</Button>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default Installed
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import React from 'react'
|
|||
import type { Item } from '@/app/components/base/select'
|
||||
import { PortalSelect } from '@/app/components/base/select'
|
||||
import Button from '@/app/components/base/button'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
type SetPackageProps = {
|
||||
selectedPackage: string
|
||||
|
|
@ -11,39 +12,42 @@ type SetPackageProps = {
|
|||
onBack: () => void
|
||||
}
|
||||
|
||||
const SetPackage: React.FC<SetPackageProps> = ({ selectedPackage, packages, onSelect, onInstall, onBack }) => (
|
||||
<>
|
||||
<label
|
||||
htmlFor='package'
|
||||
className='flex flex-col justify-center items-start self-stretch text-text-secondary'
|
||||
>
|
||||
<span className='system-sm-semibold'>Select package</span>
|
||||
</label>
|
||||
<PortalSelect
|
||||
value={selectedPackage}
|
||||
onSelect={onSelect}
|
||||
items={packages}
|
||||
placeholder="Please select a package"
|
||||
popupClassName='w-[432px] z-[1001]'
|
||||
/>
|
||||
<div className='flex justify-end items-center gap-2 self-stretch mt-4'>
|
||||
<Button
|
||||
variant='secondary'
|
||||
className='min-w-[72px]'
|
||||
onClick={onBack}
|
||||
const SetPackage: React.FC<SetPackageProps> = ({ selectedPackage, packages, onSelect, onInstall, onBack }) => {
|
||||
const { t } = useTranslation()
|
||||
return (
|
||||
<>
|
||||
<label
|
||||
htmlFor='package'
|
||||
className='flex flex-col justify-center items-start self-stretch text-text-secondary'
|
||||
>
|
||||
Back
|
||||
</Button>
|
||||
<Button
|
||||
variant='primary'
|
||||
className='min-w-[72px]'
|
||||
onClick={onInstall}
|
||||
disabled={!selectedPackage}
|
||||
>
|
||||
Install
|
||||
</Button>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
<span className='system-sm-semibold'>{t('plugin.installFromGitHub.selectPackage')}</span>
|
||||
</label>
|
||||
<PortalSelect
|
||||
value={selectedPackage}
|
||||
onSelect={onSelect}
|
||||
items={packages}
|
||||
placeholder={t('plugin.installFromGitHub.selectPackagePlaceholder') || ''}
|
||||
popupClassName='w-[432px] z-[1001]'
|
||||
/>
|
||||
<div className='flex justify-end items-center gap-2 self-stretch mt-4'>
|
||||
<Button
|
||||
variant='secondary'
|
||||
className='min-w-[72px]'
|
||||
onClick={onBack}
|
||||
>
|
||||
{t('plugin.installModal.back')}
|
||||
</Button>
|
||||
<Button
|
||||
variant='primary'
|
||||
className='min-w-[72px]'
|
||||
onClick={onInstall}
|
||||
disabled={!selectedPackage}
|
||||
>
|
||||
{t('plugin.installModal.install')}
|
||||
</Button>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default SetPackage
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import React from 'react'
|
||||
import Button from '@/app/components/base/button'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
type SetURLProps = {
|
||||
repoUrl: string
|
||||
|
|
@ -8,43 +9,46 @@ type SetURLProps = {
|
|||
onCancel: () => void
|
||||
}
|
||||
|
||||
const SetURL: React.FC<SetURLProps> = ({ repoUrl, onChange, onNext, onCancel }) => (
|
||||
<>
|
||||
<label
|
||||
htmlFor='repoUrl'
|
||||
className='flex flex-col justify-center items-start self-stretch text-text-secondary'
|
||||
>
|
||||
<span className='system-sm-semibold'>GitHub repository</span>
|
||||
</label>
|
||||
<input
|
||||
type='url'
|
||||
id='repoUrl'
|
||||
name='repoUrl'
|
||||
value={repoUrl}
|
||||
onChange={e => onChange(e.target.value)}
|
||||
className='flex items-center self-stretch rounded-lg border border-components-input-border-active
|
||||
bg-components-input-bg-active shadows-shadow-xs p-2 gap-[2px] flex-grow overflow-hidden
|
||||
text-components-input-text-filled text-ellipsis system-sm-regular'
|
||||
placeholder='Please enter GitHub repo URL'
|
||||
/>
|
||||
<div className='flex justify-end items-center gap-2 self-stretch mt-4'>
|
||||
<Button
|
||||
variant='secondary'
|
||||
className='min-w-[72px]'
|
||||
onClick={onCancel}
|
||||
const SetURL: React.FC<SetURLProps> = ({ repoUrl, onChange, onNext, onCancel }) => {
|
||||
const { t } = useTranslation()
|
||||
return (
|
||||
<>
|
||||
<label
|
||||
htmlFor='repoUrl'
|
||||
className='flex flex-col justify-center items-start self-stretch text-text-secondary'
|
||||
>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button
|
||||
variant='primary'
|
||||
className='min-w-[72px]'
|
||||
onClick={onNext}
|
||||
disabled={!repoUrl.trim()}
|
||||
>
|
||||
Next
|
||||
</Button>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
<span className='system-sm-semibold'>{t('plugin.installFromGitHub.gitHubRepo')}</span>
|
||||
</label>
|
||||
<input
|
||||
type='url'
|
||||
id='repoUrl'
|
||||
name='repoUrl'
|
||||
value={repoUrl}
|
||||
onChange={e => onChange(e.target.value)}
|
||||
className='flex items-center self-stretch rounded-lg border border-components-input-border-active
|
||||
bg-components-input-bg-active shadows-shadow-xs p-2 gap-[2px] flex-grow overflow-hidden
|
||||
text-components-input-text-filled text-ellipsis system-sm-regular'
|
||||
placeholder='Please enter GitHub repo URL'
|
||||
/>
|
||||
<div className='flex justify-end items-center gap-2 self-stretch mt-4'>
|
||||
<Button
|
||||
variant='secondary'
|
||||
className='min-w-[72px]'
|
||||
onClick={onCancel}
|
||||
>
|
||||
{t('plugin.installModal.cancel')}
|
||||
</Button>
|
||||
<Button
|
||||
variant='primary'
|
||||
className='min-w-[72px]'
|
||||
onClick={onNext}
|
||||
disabled={!repoUrl.trim()}
|
||||
>
|
||||
{t('plugin.installModal.next')}
|
||||
</Button>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default SetURL
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import React from 'react'
|
|||
import type { Item } from '@/app/components/base/select'
|
||||
import { PortalSelect } from '@/app/components/base/select'
|
||||
import Button from '@/app/components/base/button'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
type SetVersionProps = {
|
||||
selectedVersion: string
|
||||
|
|
@ -11,39 +12,42 @@ type SetVersionProps = {
|
|||
onBack: () => void
|
||||
}
|
||||
|
||||
const SetVersion: React.FC<SetVersionProps> = ({ selectedVersion, versions, onSelect, onNext, onBack }) => (
|
||||
<>
|
||||
<label
|
||||
htmlFor='version'
|
||||
className='flex flex-col justify-center items-start self-stretch text-text-secondary'
|
||||
>
|
||||
<span className='system-sm-semibold'>Select version</span>
|
||||
</label>
|
||||
<PortalSelect
|
||||
value={selectedVersion}
|
||||
onSelect={onSelect}
|
||||
items={versions}
|
||||
placeholder="Please select a version"
|
||||
popupClassName='w-[432px] z-[1001]'
|
||||
/>
|
||||
<div className='flex justify-end items-center gap-2 self-stretch mt-4'>
|
||||
<Button
|
||||
variant='secondary'
|
||||
className='min-w-[72px]'
|
||||
onClick={onBack}
|
||||
const SetVersion: React.FC<SetVersionProps> = ({ selectedVersion, versions, onSelect, onNext, onBack }) => {
|
||||
const { t } = useTranslation()
|
||||
return (
|
||||
<>
|
||||
<label
|
||||
htmlFor='version'
|
||||
className='flex flex-col justify-center items-start self-stretch text-text-secondary'
|
||||
>
|
||||
Back
|
||||
</Button>
|
||||
<Button
|
||||
variant='primary'
|
||||
className='min-w-[72px]'
|
||||
onClick={onNext}
|
||||
disabled={!selectedVersion}
|
||||
>
|
||||
Next
|
||||
</Button>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
<span className='system-sm-semibold'>{t('plugin.installFromGitHub.selectVersion')}</span>
|
||||
</label>
|
||||
<PortalSelect
|
||||
value={selectedVersion}
|
||||
onSelect={onSelect}
|
||||
items={versions}
|
||||
placeholder={t('plugin.installFromGitHub.selectVersionPlaceholder') || ''}
|
||||
popupClassName='w-[432px] z-[1001]'
|
||||
/>
|
||||
<div className='flex justify-end items-center gap-2 self-stretch mt-4'>
|
||||
<Button
|
||||
variant='secondary'
|
||||
className='min-w-[72px]'
|
||||
onClick={onBack}
|
||||
>
|
||||
{t('plugin.installModal.back')}
|
||||
</Button>
|
||||
<Button
|
||||
variant='primary'
|
||||
className='min-w-[72px]'
|
||||
onClick={onNext}
|
||||
disabled={!selectedVersion}
|
||||
>
|
||||
{t('plugin.installModal.next')}
|
||||
</Button>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default SetVersion
|
||||
|
|
|
|||
|
|
@ -12,7 +12,8 @@ const SearchBox: React.FC<SearchBoxProps> = ({
|
|||
}) => {
|
||||
return (
|
||||
<Input
|
||||
wrapperClassName='flex w-[200px] items-center rounded-lg bg-components-input-bg-normal'
|
||||
wrapperClassName='flex w-[200px] items-center rounded-lg'
|
||||
className='bg-components-input-bg-normal'
|
||||
showLeftIcon
|
||||
value={searchQuery}
|
||||
placeholder='Search'
|
||||
|
|
|
|||
|
|
@ -124,6 +124,20 @@ export enum InstallStepFromGitHub {
|
|||
installed = 'installed',
|
||||
}
|
||||
|
||||
export type InstallState = {
|
||||
step: InstallStepFromGitHub
|
||||
repoUrl: string
|
||||
selectedVersion: string
|
||||
selectedPackage: string
|
||||
releases: GitHubRepoReleaseResponse[]
|
||||
}
|
||||
|
||||
export type GitHubUrlInfo = {
|
||||
isValid: boolean
|
||||
owner?: string
|
||||
repo?: string
|
||||
}
|
||||
|
||||
// endpoint
|
||||
export type CreateEndpointRequest = {
|
||||
plugin_unique_identifier: string
|
||||
|
|
|
|||
|
|
@ -67,6 +67,24 @@ const translation = {
|
|||
uploadingPackage: 'Uploading {{packageName}}...',
|
||||
readyToInstall: 'About to install the following plugin.',
|
||||
fromTrustSource: 'Please make sure that you only install plugins from a <trustSource>trusted source</trustSource>.',
|
||||
labels: {
|
||||
repository: 'Repository',
|
||||
version: 'Version',
|
||||
package: 'Package',
|
||||
},
|
||||
close: 'Close',
|
||||
cancel: 'Cancel',
|
||||
back: 'Back',
|
||||
next: 'Next',
|
||||
},
|
||||
installFromGitHub: {
|
||||
installPlugin: 'Install plugin from GitHub',
|
||||
gitHubRepo: 'GitHub repository',
|
||||
selectVersion: 'Select version',
|
||||
selectVersionPlaceholder: 'Please select a version',
|
||||
installNote: 'Please make sure that you only install plugins from a trusted source.',
|
||||
selectPackage: 'Select package',
|
||||
selectPackagePlaceholder: 'Please select a package',
|
||||
},
|
||||
upgrade: {
|
||||
title: 'Upgrade Plugin',
|
||||
|
|
@ -77,6 +95,9 @@ const translation = {
|
|||
upgrading: 'Upgrading...',
|
||||
close: 'Close',
|
||||
},
|
||||
error: {
|
||||
inValidGitHubUrl: 'Invalid GitHub URL. Please enter a valid URL in the format: https://github.com/owner/repo',
|
||||
},
|
||||
}
|
||||
|
||||
export default translation
|
||||
|
|
|
|||
|
|
@ -67,6 +67,24 @@ const translation = {
|
|||
uploadingPackage: '上传 {{packageName}} 中...',
|
||||
readyToInstall: '即将安装以下插件。',
|
||||
fromTrustSource: '请保证仅从<trustSource>可信源</trustSource>安装插件。',
|
||||
labels: {
|
||||
repository: '仓库',
|
||||
version: '版本',
|
||||
package: '包',
|
||||
},
|
||||
close: '关闭',
|
||||
cancel: '取消',
|
||||
back: '返回',
|
||||
next: '下一步',
|
||||
},
|
||||
installFromGitHub: {
|
||||
installPlugin: '从 GitHub 安装插件',
|
||||
gitHubRepo: 'GitHub 仓库',
|
||||
selectVersion: '选择版本',
|
||||
selectVersionPlaceholder: '请选择一个版本',
|
||||
installNote: '请确保只从可信源安装插件。',
|
||||
selectPackage: '选择包',
|
||||
selectPackagePlaceholder: '请选择一个包',
|
||||
},
|
||||
upgrade: {
|
||||
title: '升级插件',
|
||||
|
|
@ -77,6 +95,9 @@ const translation = {
|
|||
upgrading: '升级中...',
|
||||
close: '关闭',
|
||||
},
|
||||
error: {
|
||||
inValidGitHubUrl: '无效的 GitHub URL。请输入格式为 https://github.com/owner/repo 的有效 URL',
|
||||
},
|
||||
}
|
||||
|
||||
export default translation
|
||||
|
|
|
|||
Loading…
Reference in New Issue