Sfoglia il codice sorgente

Fix/language support (#2154)

tags/0.5.0
crazywoola 1 anno fa
parent
commit
e58c3ac374
Nessun account collegato all'indirizzo email del committer
28 ha cambiato i file con 103 aggiunte e 71 eliminazioni
  1. 3
    2
      web/app/(commonLayout)/datasets/Doc.tsx
  2. 4
    5
      web/app/activate/activateForm.tsx
  3. 5
    5
      web/app/components/app/annotation/batch-add-annotation-modal/csv-downloader.tsx
  4. 4
    3
      web/app/components/app/annotation/header-opts/index.tsx
  5. 3
    2
      web/app/components/app/configuration/config/agent/agent-tools/choose-tool/index.tsx
  6. 6
    5
      web/app/components/app/configuration/config/agent/agent-tools/setting-built-in-tool.tsx
  7. 3
    2
      web/app/components/app/configuration/toolbox/moderation/index.tsx
  8. 5
    3
      web/app/components/app/configuration/toolbox/moderation/moderation-setting-modal.tsx
  9. 4
    2
      web/app/components/app/configuration/tools/external-data-tool-modal.tsx
  10. 3
    1
      web/app/components/app/overview/customize/index.tsx
  11. 3
    1
      web/app/components/datasets/create/file-uploader/index.tsx
  12. 3
    2
      web/app/components/datasets/create/step-two/index.tsx
  13. 7
    5
      web/app/components/datasets/documents/detail/batch-modal/csv-downloader.tsx
  14. 4
    2
      web/app/components/develop/doc.tsx
  15. 3
    1
      web/app/components/develop/secret-key/secret-key-modal.tsx
  16. 4
    2
      web/app/components/header/account-about/index.tsx
  17. 3
    2
      web/app/components/header/account-dropdown/index.tsx
  18. 4
    3
      web/app/components/header/account-setting/members-page/index.tsx
  19. 3
    1
      web/app/components/tools/edit-custom-collection-modal/test-api.tsx
  20. 4
    2
      web/app/components/tools/tool-list/header.tsx
  21. 4
    2
      web/app/components/tools/tool-list/item.tsx
  22. 3
    2
      web/app/components/tools/tool-nav-list/item.tsx
  23. 1
    4
      web/app/components/tools/types.ts
  24. 6
    4
      web/app/install/installForm.tsx
  25. 4
    3
      web/app/signin/normalForm.tsx
  26. 4
    4
      web/app/signin/oneMoreStep.tsx
  27. 1
    1
      web/models/common.ts
  28. 2
    0
      web/utils/language.ts

+ 3
- 2
web/app/(commonLayout)/datasets/Doc.tsx Vedi File

import TemplateEn from './template/template.en.mdx' import TemplateEn from './template/template.en.mdx'
import TemplateZh from './template/template.zh.mdx' import TemplateZh from './template/template.zh.mdx'
import I18n from '@/context/i18n' import I18n from '@/context/i18n'
import { LanguagesSupportedUnderscore, getModelRuntimeSupported } from '@/utils/language'


type DocProps = { type DocProps = {
apiBaseUrl: string apiBaseUrl: string
apiBaseUrl, apiBaseUrl,
}) => { }) => {
const { locale } = useContext(I18n) const { locale } = useContext(I18n)
const language = getModelRuntimeSupported(locale)
return ( return (
<article className='mx-1 px-4 sm:mx-12 pt-16 bg-white rounded-t-xl prose prose-xl'> <article className='mx-1 px-4 sm:mx-12 pt-16 bg-white rounded-t-xl prose prose-xl'>
{ {
locale === 'en'
language !== LanguagesSupportedUnderscore[1]
? <TemplateEn apiBaseUrl={apiBaseUrl} /> ? <TemplateEn apiBaseUrl={apiBaseUrl} />
: <TemplateZh apiBaseUrl={apiBaseUrl} /> : <TemplateZh apiBaseUrl={apiBaseUrl} />
} }

+ 4
- 5
web/app/activate/activateForm.tsx Vedi File



import { SimpleSelect } from '@/app/components/base/select' import { SimpleSelect } from '@/app/components/base/select'
import { timezones } from '@/utils/timezone' import { timezones } from '@/utils/timezone'
import { LanguagesSupported, languages } from '@/utils/language'
import { LanguagesSupportedUnderscore, getModelRuntimeSupported, languages } from '@/utils/language'
import { activateMember, invitationCheck } from '@/service/common' import { activateMember, invitationCheck } from '@/service/common'
import Toast from '@/app/components/base/toast' import Toast from '@/app/components/base/toast'
import Loading from '@/app/components/base/loading' import Loading from '@/app/components/base/loading'
import I18n from '@/context/i18n' import I18n from '@/context/i18n'

const validPassword = /^(?=.*[a-zA-Z])(?=.*\d).{8,}$/ const validPassword = /^(?=.*[a-zA-Z])(?=.*\d).{8,}$/


const ActivateForm = () => { const ActivateForm = () => {
const [name, setName] = useState('') const [name, setName] = useState('')
const [password, setPassword] = useState('') const [password, setPassword] = useState('')
const [timezone, setTimezone] = useState('Asia/Shanghai') const [timezone, setTimezone] = useState('Asia/Shanghai')
const [language, setLanguage] = useState('en-US')
const [language, setLanguage] = useState(getModelRuntimeSupported(locale))
const [showSuccess, setShowSuccess] = useState(false) const [showSuccess, setShowSuccess] = useState(false)
const defaultLanguage = useCallback(() => (window.navigator.language.startsWith('zh') ? LanguagesSupported[1] : LanguagesSupported[0]) || LanguagesSupported[0], [])
const defaultLanguage = useCallback(() => (window.navigator.language.startsWith('zh') ? LanguagesSupportedUnderscore[1] : LanguagesSupportedUnderscore[0]) || LanguagesSupportedUnderscore[0], [])


const showErrorMessage = useCallback((message: string) => { const showErrorMessage = useCallback((message: string) => {
Toast.notify({ Toast.notify({
<Link <Link
className='text-primary-600' className='text-primary-600'
target={'_blank'} target={'_blank'}
href={`https://docs.dify.ai/${locale === 'en' ? '' : `v/${locale.toLowerCase()}`}/community/open-source`}
href={`https://docs.dify.ai/${language !== LanguagesSupportedUnderscore[1] ? '' : `v/${locale.toLowerCase()}`}/community/open-source`}
>{t('login.license.link')}</Link> >{t('login.license.link')}</Link>
</div> </div>
</div> </div>

+ 5
- 5
web/app/components/app/annotation/batch-add-annotation-modal/csv-downloader.tsx Vedi File

import { useContext } from 'use-context-selector' import { useContext } from 'use-context-selector'
import { Download02 as DownloadIcon } from '@/app/components/base/icons/src/vender/solid/general' import { Download02 as DownloadIcon } from '@/app/components/base/icons/src/vender/solid/general'
import I18n from '@/context/i18n' import I18n from '@/context/i18n'
import { LanguagesSupportedUnderscore, getModelRuntimeSupported } from '@/utils/language'


const CSV_TEMPLATE_QA_EN = [ const CSV_TEMPLATE_QA_EN = [
['question', 'answer'], ['question', 'answer'],


const CSVDownload: FC = () => { const CSVDownload: FC = () => {
const { t } = useTranslation() const { t } = useTranslation()

const { locale } = useContext(I18n) const { locale } = useContext(I18n)
const language = getModelRuntimeSupported(locale)
const { CSVDownloader, Type } = useCSVDownloader() const { CSVDownloader, Type } = useCSVDownloader()


const getTemplate = () => { const getTemplate = () => {
if (locale === 'en')
return CSV_TEMPLATE_QA_EN

return CSV_TEMPLATE_QA_CN
return language !== LanguagesSupportedUnderscore[1] ? CSV_TEMPLATE_QA_EN : CSV_TEMPLATE_QA_CN
} }


return ( return (
<CSVDownloader <CSVDownloader
className="block mt-2 cursor-pointer" className="block mt-2 cursor-pointer"
type={Type.Link} type={Type.Link}
filename={'template'}
filename={`template-${language}`}
bom={true} bom={true}
data={getTemplate()} data={getTemplate()}
> >

+ 4
- 3
web/app/components/app/annotation/header-opts/index.tsx Vedi File

import BatchAddModal from '../batch-add-annotation-modal' import BatchAddModal from '../batch-add-annotation-modal'
import s from './style.module.css' import s from './style.module.css'
import CustomPopover from '@/app/components/base/popover' import CustomPopover from '@/app/components/base/popover'
// import Divider from '@/app/components/base/divider'
import { FileDownload02, FilePlus02 } from '@/app/components/base/icons/src/vender/line/files' import { FileDownload02, FilePlus02 } from '@/app/components/base/icons/src/vender/line/files'
import I18n from '@/context/i18n' import I18n from '@/context/i18n'
import { fetchExportAnnotationList } from '@/service/annotation' import { fetchExportAnnotationList } from '@/service/annotation'
import { LanguagesSupportedUnderscore, getModelRuntimeSupported } from '@/utils/language'
const CSV_HEADER_QA_EN = ['Question', 'Answer'] const CSV_HEADER_QA_EN = ['Question', 'Answer']
const CSV_HEADER_QA_CN = ['问题', '答案'] const CSV_HEADER_QA_CN = ['问题', '答案']


}) => { }) => {
const { t } = useTranslation() const { t } = useTranslation()
const { locale } = useContext(I18n) const { locale } = useContext(I18n)
const language = getModelRuntimeSupported(locale)
const { CSVDownloader, Type } = useCSVDownloader() const { CSVDownloader, Type } = useCSVDownloader()
const [list, setList] = useState<AnnotationItemBasic[]>([]) const [list, setList] = useState<AnnotationItemBasic[]>([])
const fetchList = async () => { const fetchList = async () => {


<CSVDownloader <CSVDownloader
type={Type.Link} type={Type.Link}
filename="annotations"
filename={`annotations-${language}`}
bom={true} bom={true}
data={[ data={[
locale === 'en' ? CSV_HEADER_QA_EN : CSV_HEADER_QA_CN,
language !== LanguagesSupportedUnderscore[1] ? CSV_HEADER_QA_EN : CSV_HEADER_QA_CN,
...list.map(item => [item.question, item.answer]), ...list.map(item => [item.question, item.answer]),
]} ]}
> >

+ 3
- 2
web/app/components/app/configuration/config/agent/agent-tools/choose-tool/index.tsx Vedi File

import ConfigContext from '@/context/debug-configuration' import ConfigContext from '@/context/debug-configuration'
import type { ModelConfig } from '@/models/debug' import type { ModelConfig } from '@/models/debug'
import I18n from '@/context/i18n' import I18n from '@/context/i18n'
import { getModelRuntimeSupported } from '@/utils/language'
type Props = { type Props = {
show: boolean show: boolean
onHide: () => void onHide: () => void
}) => { }) => {
const { t } = useTranslation() const { t } = useTranslation()
const { locale } = useContext(I18n) const { locale } = useContext(I18n)
const language = getModelRuntimeSupported(locale)
const { const {
modelConfig, modelConfig,
setModelConfig, setModelConfig,
provider_type: collection.type, provider_type: collection.type,
provider_name: collection.name, provider_name: collection.name,
tool_name: tool.name, tool_name: tool.name,
tool_label: tool.label[locale === 'en' ? 'en_US' : 'zh_Hans'],
tool_label: tool.label[language],
tool_parameters: parameters, tool_parameters: parameters,
enabled: true, enabled: true,
}) })

+ 6
- 5
web/app/components/app/configuration/config/agent/agent-tools/setting-built-in-tool.tsx Vedi File

import Button from '@/app/components/base/button' import Button from '@/app/components/base/button'
import Loading from '@/app/components/base/loading' import Loading from '@/app/components/base/loading'
import { DiagonalDividingLine } from '@/app/components/base/icons/src/public/common' import { DiagonalDividingLine } from '@/app/components/base/icons/src/public/common'
import { getModelRuntimeSupported } from '@/utils/language'
type Props = { type Props = {
collection: Collection collection: Collection
toolName: string toolName: string
onSave, onSave,
}) => { }) => {
const { locale } = useContext(I18n) const { locale } = useContext(I18n)
const language = getModelRuntimeSupported(locale)
const { t } = useTranslation() const { t } = useTranslation()


const [isLoading, setIsLoading] = useState(true) const [isLoading, setIsLoading] = useState(true)
{t('tools.setBuiltInTools.toolDescription')} {t('tools.setBuiltInTools.toolDescription')}
</div> </div>
<div className='mt-1 leading-[18px] text-xs font-normal text-gray-600'> <div className='mt-1 leading-[18px] text-xs font-normal text-gray-600'>
{currTool?.description[locale === 'en' ? 'en_US' : 'zh_Hans']}
{currTool?.description[language]}
</div> </div>


{infoSchemas.length > 0 && ( {infoSchemas.length > 0 && (
{infoSchemas.map((item: any, index) => ( {infoSchemas.map((item: any, index) => (
<div key={index}> <div key={index}>
<div className='flex items-center space-x-2 leading-[18px]'> <div className='flex items-center space-x-2 leading-[18px]'>
<div className='text-[13px] font-semibold text-gray-900'>{item.label[locale === 'en' ? 'en_US' : 'zh_Hans']}</div>
<div className='text-[13px] font-semibold text-gray-900'>{item.label[language]}</div>
<div className='text-xs font-medium text-gray-500'>{item.type === 'number-input' ? t('tools.setBuiltInTools.number') : t('tools.setBuiltInTools.string')}</div> <div className='text-xs font-medium text-gray-500'>{item.type === 'number-input' ? t('tools.setBuiltInTools.number') : t('tools.setBuiltInTools.string')}</div>
{item.required && ( {item.required && (
<div className='text-xs font-medium text-[#EC4A0A]'>{t('tools.setBuiltInTools.required')}</div> <div className='text-xs font-medium text-[#EC4A0A]'>{t('tools.setBuiltInTools.required')}</div>
</div> </div>
{item.human_description && ( {item.human_description && (
<div className='mt-1 leading-[18px] text-xs font-normal text-gray-600'> <div className='mt-1 leading-[18px] text-xs font-normal text-gray-600'>
{item.human_description?.[locale === 'en' ? 'en_US' : 'zh_Hans']}
{item.human_description?.[language]}
</div> </div>
)} )}
</div> </div>
backgroundImage: `url(${collection.icon})`, backgroundImage: `url(${collection.icon})`,
}} }}
></div> ></div>
<div className='ml-2 leading-6 text-base font-semibold text-gray-900'>{currTool?.label[locale === 'en' ? 'en_US' : 'zh_Hans']}</div>
<div className='ml-2 leading-6 text-base font-semibold text-gray-900'>{currTool?.label[language]}</div>
{(hasSetting && !readonly) && (<> {(hasSetting && !readonly) && (<>
<DiagonalDividingLine className='mx-4' /> <DiagonalDividingLine className='mx-4' />
<div className='flex space-x-6'> <div className='flex space-x-6'>

+ 3
- 2
web/app/components/app/configuration/toolbox/moderation/index.tsx Vedi File

import ConfigContext from '@/context/debug-configuration' import ConfigContext from '@/context/debug-configuration'
import { fetchCodeBasedExtensionList } from '@/service/common' import { fetchCodeBasedExtensionList } from '@/service/common'
import I18n from '@/context/i18n' import I18n from '@/context/i18n'
import { getModelRuntimeSupported } from '@/utils/language'
const Moderation = () => { const Moderation = () => {
const { t } = useTranslation() const { t } = useTranslation()
const { setShowModerationSettingModal } = useModalContext() const { setShowModerationSettingModal } = useModalContext()
const { locale } = useContext(I18n) const { locale } = useContext(I18n)
const language = getModelRuntimeSupported(locale)
const { const {
moderationConfig, moderationConfig,
setModerationConfig, setModerationConfig,
else if (moderationConfig.type === 'api') else if (moderationConfig.type === 'api')
prefix = t('common.apiBasedExtension.selector.title') prefix = t('common.apiBasedExtension.selector.title')
else else
prefix = codeBasedExtensionList?.data.find(item => item.name === moderationConfig.type)?.label[locale === 'en' ? 'en-US' : 'zh-Hans'] || ''
prefix = codeBasedExtensionList?.data.find(item => item.name === moderationConfig.type)?.label[language] || ''


if (moderationConfig.config?.inputs_config?.enabled && moderationConfig.config?.outputs_config?.enabled) if (moderationConfig.config?.inputs_config?.enabled && moderationConfig.config?.outputs_config?.enabled)
suffix = t('appDebug.feature.moderation.allEnabled') suffix = t('appDebug.feature.moderation.allEnabled')

+ 5
- 3
web/app/components/app/configuration/toolbox/moderation/moderation-setting-modal.tsx Vedi File

} from '@/service/common' } from '@/service/common'
import type { CodeBasedExtensionItem } from '@/models/common' import type { CodeBasedExtensionItem } from '@/models/common'
import I18n from '@/context/i18n' import I18n from '@/context/i18n'
import { LanguagesSupportedUnderscore, getModelRuntimeSupported } from '@/utils/language'
import { InfoCircle } from '@/app/components/base/icons/src/vender/line/general' import { InfoCircle } from '@/app/components/base/icons/src/vender/line/general'
import { useModalContext } from '@/context/modal-context' import { useModalContext } from '@/context/modal-context'
import { CustomConfigurationStatusEnum } from '@/app/components/header/account-setting/model-provider-page/declarations' import { CustomConfigurationStatusEnum } from '@/app/components/header/account-setting/model-provider-page/declarations'
const { t } = useTranslation() const { t } = useTranslation()
const { notify } = useToastContext() const { notify } = useToastContext()
const { locale } = useContext(I18n) const { locale } = useContext(I18n)
const language = getModelRuntimeSupported(locale)
const { data: modelProviders, isLoading, mutate } = useSWR('/workspaces/current/model-providers', fetchModelProviders) const { data: modelProviders, isLoading, mutate } = useSWR('/workspaces/current/model-providers', fetchModelProviders)
const [localeData, setLocaleData] = useState<ModerationConfig>(data) const [localeData, setLocaleData] = useState<ModerationConfig>(data)
const { setShowAccountSettingModal } = useModalContext() const { setShowAccountSettingModal } = useModalContext()
} }


if (localeData.type === 'keywords' && !localeData.config.keywords) { if (localeData.type === 'keywords' && !localeData.config.keywords) {
notify({ type: 'error', message: t('appDebug.errorMessage.valueOfVarRequired', { key: locale === 'en' ? 'keywords' : '关键词' }) })
notify({ type: 'error', message: t('appDebug.errorMessage.valueOfVarRequired', { key: language !== LanguagesSupportedUnderscore[1] ? 'keywords' : '关键词' }) })
return return
} }


if (localeData.type === 'api' && !localeData.config.api_based_extension_id) { if (localeData.type === 'api' && !localeData.config.api_based_extension_id) {
notify({ type: 'error', message: t('appDebug.errorMessage.valueOfVarRequired', { key: locale === 'en' ? 'API Extension' : 'API 扩展' }) })
notify({ type: 'error', message: t('appDebug.errorMessage.valueOfVarRequired', { key: language !== LanguagesSupportedUnderscore[1] ? 'API Extension' : 'API 扩展' }) })
return return
} }


if (!localeData.config?.[currentProvider.form_schema[i].variable] && currentProvider.form_schema[i].required) { if (!localeData.config?.[currentProvider.form_schema[i].variable] && currentProvider.form_schema[i].required) {
notify({ notify({
type: 'error', type: 'error',
message: t('appDebug.errorMessage.valueOfVarRequired', { key: locale === 'en' ? currentProvider.form_schema[i].label['en-US'] : currentProvider.form_schema[i].label['zh-Hans'] }),
message: t('appDebug.errorMessage.valueOfVarRequired', { key: language !== LanguagesSupportedUnderscore[1] ? currentProvider.form_schema[i].label['en-US'] : currentProvider.form_schema[i].label['zh-Hans'] }),
}) })
return return
} }

+ 4
- 2
web/app/components/app/configuration/tools/external-data-tool-modal.tsx Vedi File

import { fetchCodeBasedExtensionList } from '@/service/common' import { fetchCodeBasedExtensionList } from '@/service/common'
import { SimpleSelect } from '@/app/components/base/select' import { SimpleSelect } from '@/app/components/base/select'
import I18n from '@/context/i18n' import I18n from '@/context/i18n'
import { LanguagesSupportedUnderscore, getModelRuntimeSupported } from '@/utils/language'
import type { import type {
CodeBasedExtensionItem, CodeBasedExtensionItem,
ExternalDataTool, ExternalDataTool,
const { t } = useTranslation() const { t } = useTranslation()
const { notify } = useToastContext() const { notify } = useToastContext()
const { locale } = useContext(I18n) const { locale } = useContext(I18n)
const language = getModelRuntimeSupported(locale)
const [localeData, setLocaleData] = useState(data.type ? data : { ...data, type: 'api' }) const [localeData, setLocaleData] = useState(data.type ? data : { ...data, type: 'api' })
const [showEmojiPicker, setShowEmojiPicker] = useState(false) const [showEmojiPicker, setShowEmojiPicker] = useState(false)
const { data: codeBasedExtensionList } = useSWR( const { data: codeBasedExtensionList } = useSWR(
} }


if (localeData.type === 'api' && !localeData.config?.api_based_extension_id) { if (localeData.type === 'api' && !localeData.config?.api_based_extension_id) {
notify({ type: 'error', message: t('appDebug.errorMessage.valueOfVarRequired', { key: locale === 'en' ? 'API Extension' : 'API 扩展' }) })
notify({ type: 'error', message: t('appDebug.errorMessage.valueOfVarRequired', { key: language !== LanguagesSupportedUnderscore[1] ? 'API Extension' : 'API 扩展' }) })
return return
} }


if (!localeData.config?.[currentProvider.form_schema[i].variable] && currentProvider.form_schema[i].required) { if (!localeData.config?.[currentProvider.form_schema[i].variable] && currentProvider.form_schema[i].required) {
notify({ notify({
type: 'error', type: 'error',
message: t('appDebug.errorMessage.valueOfVarRequired', { key: locale === 'en' ? currentProvider.form_schema[i].label['en-US'] : currentProvider.form_schema[i].label['zh-Hans'] }),
message: t('appDebug.errorMessage.valueOfVarRequired', { key: language !== LanguagesSupportedUnderscore[1] ? currentProvider.form_schema[i].label['en-US'] : currentProvider.form_schema[i].label['zh-Hans'] }),
}) })
return return
} }

+ 3
- 1
web/app/components/app/overview/customize/index.tsx Vedi File

import Button from '@/app/components/base/button' import Button from '@/app/components/base/button'
import Modal from '@/app/components/base/modal' import Modal from '@/app/components/base/modal'
import Tag from '@/app/components/base/tag' import Tag from '@/app/components/base/tag'
import { LanguagesSupportedUnderscore, getModelRuntimeSupported } from '@/utils/language'


type IShareLinkProps = { type IShareLinkProps = {
isShow: boolean isShow: boolean
}) => { }) => {
const { t } = useTranslation() const { t } = useTranslation()
const { locale } = useContext(I18n) const { locale } = useContext(I18n)
const language = getModelRuntimeSupported(locale)
const isChatApp = mode === 'chat' const isChatApp = mode === 'chat'


return <Modal return <Modal
<p className='mt-2 text-base font-medium text-gray-800'>{t(`${prefixCustomize}.way2.name`)}</p> <p className='mt-2 text-base font-medium text-gray-800'>{t(`${prefixCustomize}.way2.name`)}</p>
<Button <Button
className='w-36 mt-2' className='w-36 mt-2'
onClick={() => window.open(`https://docs.dify.ai/${locale === 'en' ? '' : `v/${locale.toLowerCase()}`}/application/developing-with-apis`, '_blank')}
onClick={() => window.open(`https://docs.dify.ai/${language !== LanguagesSupportedUnderscore[1] ? '' : `v/${locale.toLowerCase()}`}/application/developing-with-apis`, '_blank')}
> >
<span className='text-sm text-gray-800'>{t(`${prefixCustomize}.way2.operation`)}</span> <span className='text-sm text-gray-800'>{t(`${prefixCustomize}.way2.operation`)}</span>
<ArrowTopRightOnSquareIcon className='w-4 h-4 ml-1 text-gray-800 shrink-0' /> <ArrowTopRightOnSquareIcon className='w-4 h-4 ml-1 text-gray-800 shrink-0' />

+ 3
- 1
web/app/components/datasets/create/file-uploader/index.tsx Vedi File

import { fetchFileUploadConfig } from '@/service/common' import { fetchFileUploadConfig } from '@/service/common'
import { fetchSupportFileTypes } from '@/service/datasets' import { fetchSupportFileTypes } from '@/service/datasets'
import I18n from '@/context/i18n' import I18n from '@/context/i18n'
import { LanguagesSupportedUnderscore, getModelRuntimeSupported } from '@/utils/language'


type IFileUploaderProps = { type IFileUploaderProps = {
fileList: FileItem[] fileList: FileItem[]
const { t } = useTranslation() const { t } = useTranslation()
const { notify } = useContext(ToastContext) const { notify } = useContext(ToastContext)
const { locale } = useContext(I18n) const { locale } = useContext(I18n)
const language = getModelRuntimeSupported(locale)
const [dragging, setDragging] = useState(false) const [dragging, setDragging] = useState(false)
const dropRef = useRef<HTMLDivElement>(null) const dropRef = useRef<HTMLDivElement>(null)
const dragRef = useRef<HTMLDivElement>(null) const dragRef = useRef<HTMLDivElement>(null)
return item return item
}) })


return res.map(item => item.toUpperCase()).join(locale === 'en' ? ', ' : '、 ')
return res.map(item => item.toUpperCase()).join(language !== LanguagesSupportedUnderscore[1] ? ', ' : '、 ')
})() })()
const ACCEPTS = supportTypes.map((ext: string) => `.${ext}`) const ACCEPTS = supportTypes.map((ext: string) => `.${ext}`)
const fileUploadConfig = useMemo(() => fileUploadConfigResponse ?? { const fileUploadConfig = useMemo(() => fileUploadConfigResponse ?? {

+ 3
- 2
web/app/components/datasets/create/step-two/index.tsx Vedi File

import useBreakpoints, { MediaType } from '@/hooks/use-breakpoints' import useBreakpoints, { MediaType } from '@/hooks/use-breakpoints'
import Tooltip from '@/app/components/base/tooltip' import Tooltip from '@/app/components/base/tooltip'
import { useModelListAndDefaultModelAndCurrentProviderAndModel } from '@/app/components/header/account-setting/model-provider-page/hooks' import { useModelListAndDefaultModelAndCurrentProviderAndModel } from '@/app/components/header/account-setting/model-provider-page/hooks'
import { LanguagesSupportedUnderscore, getModelRuntimeSupported } from '@/utils/language'


type ValueOf<T> = T[keyof T] type ValueOf<T> = T[keyof T]
type StepTwoProps = { type StepTwoProps = {
}: StepTwoProps) => { }: StepTwoProps) => {
const { t } = useTranslation() const { t } = useTranslation()
const { locale } = useContext(I18n) const { locale } = useContext(I18n)
const language = getModelRuntimeSupported(locale)
const media = useBreakpoints() const media = useBreakpoints()
const isMobile = media === MediaType.mobile const isMobile = media === MediaType.mobile


const [docForm, setDocForm] = useState<DocForm | string>( const [docForm, setDocForm] = useState<DocForm | string>(
(datasetId && documentDetail) ? documentDetail.doc_form : DocForm.TEXT, (datasetId && documentDetail) ? documentDetail.doc_form : DocForm.TEXT,
) )
const [docLanguage, setDocLanguage] = useState<string>(locale === 'en' ? 'English' : 'Chinese')
const [docLanguage, setDocLanguage] = useState<string>(language !== LanguagesSupportedUnderscore[1] ? 'English' : 'Chinese')
const [QATipHide, setQATipHide] = useState(false) const [QATipHide, setQATipHide] = useState(false)
const [previewSwitched, setPreviewSwitched] = useState(false) const [previewSwitched, setPreviewSwitched] = useState(false)
const [showPreview, { setTrue: setShowPreview, setFalse: hidePreview }] = useBoolean() const [showPreview, { setTrue: setShowPreview, setFalse: hidePreview }] = useBoolean()

+ 7
- 5
web/app/components/datasets/documents/detail/batch-modal/csv-downloader.tsx Vedi File

import { Download02 as DownloadIcon } from '@/app/components/base/icons/src/vender/solid/general' import { Download02 as DownloadIcon } from '@/app/components/base/icons/src/vender/solid/general'
import { DocForm } from '@/models/datasets' import { DocForm } from '@/models/datasets'
import I18n from '@/context/i18n' import I18n from '@/context/i18n'
import { LanguagesSupportedUnderscore, getModelRuntimeSupported } from '@/utils/language'


const CSV_TEMPLATE_QA_EN = [ const CSV_TEMPLATE_QA_EN = [
['question', 'answer'], ['question', 'answer'],
const CSVDownload: FC<{ docForm: DocForm }> = ({ docForm }) => { const CSVDownload: FC<{ docForm: DocForm }> = ({ docForm }) => {
const { t } = useTranslation() const { t } = useTranslation()
const { locale } = useContext(I18n) const { locale } = useContext(I18n)
const language = getModelRuntimeSupported(locale)
const { CSVDownloader, Type } = useCSVDownloader() const { CSVDownloader, Type } = useCSVDownloader()


const getTemplate = () => { const getTemplate = () => {
if (locale === 'en') {
if (language === LanguagesSupportedUnderscore[1]) {
if (docForm === DocForm.QA) if (docForm === DocForm.QA)
return CSV_TEMPLATE_QA_EN
return CSV_TEMPLATE_EN
return CSV_TEMPLATE_QA_CN
return CSV_TEMPLATE_CN
} }
if (docForm === DocForm.QA) if (docForm === DocForm.QA)
return CSV_TEMPLATE_QA_CN
return CSV_TEMPLATE_CN
return CSV_TEMPLATE_QA_EN
return CSV_TEMPLATE_EN
} }


return ( return (

+ 4
- 2
web/app/components/develop/doc.tsx Vedi File

import TemplateChatEn from './template/template_chat.en.mdx' import TemplateChatEn from './template/template_chat.en.mdx'
import TemplateChatZh from './template/template_chat.zh.mdx' import TemplateChatZh from './template/template_chat.zh.mdx'
import I18n from '@/context/i18n' import I18n from '@/context/i18n'
import { LanguagesSupportedUnderscore, getModelRuntimeSupported } from '@/utils/language'


type IDocProps = { type IDocProps = {
appDetail: any appDetail: any


const Doc = ({ appDetail }: IDocProps) => { const Doc = ({ appDetail }: IDocProps) => {
const { locale } = useContext(I18n) const { locale } = useContext(I18n)
const language = getModelRuntimeSupported(locale)
const variables = appDetail?.model_config?.configs?.prompt_variables || [] const variables = appDetail?.model_config?.configs?.prompt_variables || []
const inputs = variables.reduce((res: any, variable: any) => { const inputs = variables.reduce((res: any, variable: any) => {
res[variable.key] = variable.name || '' res[variable.key] = variable.name || ''
<article className="prose prose-xl" > <article className="prose prose-xl" >
{appDetail?.mode === 'completion' {appDetail?.mode === 'completion'
? ( ? (
locale === 'en' ? <TemplateEn appDetail={appDetail} variables={variables} inputs={inputs} /> : <TemplateZh appDetail={appDetail} variables={variables} inputs={inputs} />
language !== LanguagesSupportedUnderscore[1] ? <TemplateEn appDetail={appDetail} variables={variables} inputs={inputs} /> : <TemplateZh appDetail={appDetail} variables={variables} inputs={inputs} />
) )
: ( : (
locale === 'en' ? <TemplateChatEn appDetail={appDetail} variables={variables} inputs={inputs} /> : <TemplateChatZh appDetail={appDetail} variables={variables} inputs={inputs} />
language !== LanguagesSupportedUnderscore[1] ? <TemplateChatEn appDetail={appDetail} variables={variables} inputs={inputs} /> : <TemplateChatZh appDetail={appDetail} variables={variables} inputs={inputs} />
)} )}
</article> </article>
) )

+ 3
- 1
web/app/components/develop/secret-key/secret-key-modal.tsx Vedi File

import Loading from '@/app/components/base/loading' import Loading from '@/app/components/base/loading'
import Confirm from '@/app/components/base/confirm' import Confirm from '@/app/components/base/confirm'
import I18n from '@/context/i18n' import I18n from '@/context/i18n'
import { LanguagesSupported, getModelRuntimeSupported } from '@/utils/language'
import { useAppContext } from '@/context/app-context' import { useAppContext } from '@/context/app-context'


type ISecretKeyModalProps = { type ISecretKeyModalProps = {
const [delKeyID, setDelKeyId] = useState('') const [delKeyID, setDelKeyId] = useState('')


const { locale } = useContext(I18n) const { locale } = useContext(I18n)
const language = getModelRuntimeSupported(locale)


// const [isCopied, setIsCopied] = useState(false) // const [isCopied, setIsCopied] = useState(false)
const [copyValue, setCopyValue] = useState('') const [copyValue, setCopyValue] = useState('')
} }


const formatDate = (timestamp: string) => { const formatDate = (timestamp: string) => {
if (locale === 'en')
if (language === LanguagesSupported[0])
return new Intl.DateTimeFormat('en-US', { year: 'numeric', month: 'long', day: 'numeric' }).format((+timestamp) * 1000) return new Intl.DateTimeFormat('en-US', { year: 'numeric', month: 'long', day: 'numeric' }).format((+timestamp) * 1000)
else else
return new Intl.DateTimeFormat('fr-CA', { year: 'numeric', month: '2-digit', day: '2-digit' }).format((+timestamp) * 1000) return new Intl.DateTimeFormat('fr-CA', { year: 'numeric', month: '2-digit', day: '2-digit' }).format((+timestamp) * 1000)

+ 4
- 2
web/app/components/header/account-about/index.tsx Vedi File

import type { LangGeniusVersionResponse } from '@/models/common' import type { LangGeniusVersionResponse } from '@/models/common'
import { IS_CE_EDITION } from '@/config' import { IS_CE_EDITION } from '@/config'
import I18n from '@/context/i18n' import I18n from '@/context/i18n'
import { LanguagesSupportedUnderscore, getModelRuntimeSupported } from '@/utils/language'
import LogoSite from '@/app/components/base/logo/logo-site' import LogoSite from '@/app/components/base/logo/logo-site'


type IAccountSettingProps = { type IAccountSettingProps = {
}: IAccountSettingProps) { }: IAccountSettingProps) {
const { t } = useTranslation() const { t } = useTranslation()
const { locale } = useContext(I18n) const { locale } = useContext(I18n)
const language = getModelRuntimeSupported(locale)
const isLatest = langeniusVersionInfo.current_version === langeniusVersionInfo.latest_version const isLatest = langeniusVersionInfo.current_version === langeniusVersionInfo.latest_version


return ( return (
IS_CE_EDITION IS_CE_EDITION
? <Link href={'https://github.com/langgenius/dify/blob/main/LICENSE'} target='_blank'>Open Source License</Link> ? <Link href={'https://github.com/langgenius/dify/blob/main/LICENSE'} target='_blank'>Open Source License</Link>
: <> : <>
<Link href={locale === 'en' ? 'https://docs.dify.ai/user-agreement/privacy-policy' : 'https://docs.dify.ai/v/zh-hans/user-agreement/privacy-policy'} target='_blank'>Privacy Policy</Link>,
<Link href={locale === 'en' ? 'https://docs.dify.ai/user-agreement/terms-of-service' : 'https://docs.dify.ai/v/zh-hans/user-agreement/terms-of-service'} target='_blank'>Terms of Service</Link>
<Link href={language !== LanguagesSupportedUnderscore[1] ? 'https://docs.dify.ai/user-agreement/privacy-policy' : 'https://docs.dify.ai/v/zh-hans/user-agreement/privacy-policy'} target='_blank'>Privacy Policy</Link>,
<Link href={language !== LanguagesSupportedUnderscore[1] ? 'https://docs.dify.ai/user-agreement/terms-of-service' : 'https://docs.dify.ai/v/zh-hans/user-agreement/terms-of-service'} target='_blank'>Terms of Service</Link>
</> </>
} }
</div> </div>

+ 3
- 2
web/app/components/header/account-dropdown/index.tsx Vedi File

import { ArrowUpRight, ChevronDown } from '@/app/components/base/icons/src/vender/line/arrows' import { ArrowUpRight, ChevronDown } from '@/app/components/base/icons/src/vender/line/arrows'
import { LogOut01 } from '@/app/components/base/icons/src/vender/line/general' import { LogOut01 } from '@/app/components/base/icons/src/vender/line/general'
import { useModalContext } from '@/context/modal-context' import { useModalContext } from '@/context/modal-context'
import { LanguagesSupportedUnderscore, getModelRuntimeSupported } from '@/utils/language'
export type IAppSelecotr = { export type IAppSelecotr = {
isMobile: boolean isMobile: boolean
} }
const [aboutVisible, setAboutVisible] = useState(false) const [aboutVisible, setAboutVisible] = useState(false)


const { locale } = useContext(I18n) const { locale } = useContext(I18n)
const language = getModelRuntimeSupported(locale)
const { t } = useTranslation() const { t } = useTranslation()
const { userProfile, langeniusVersionInfo } = useAppContext() const { userProfile, langeniusVersionInfo } = useAppContext()
const { setShowAccountSettingModal } = useModalContext() const { setShowAccountSettingModal } = useModalContext()
<Link <Link
className={classNames(itemClassName, 'group justify-between')} className={classNames(itemClassName, 'group justify-between')}
href={ href={
locale === 'en' ? 'https://docs.dify.ai/' : `https://docs.dify.ai/v/${locale.toLowerCase()}/`
language !== LanguagesSupportedUnderscore[1] ? 'https://docs.dify.ai/' : `https://docs.dify.ai/v/${locale.toLowerCase()}/`
} }
target='_blank'> target='_blank'>
<div>{t('common.userProfile.helpCenter')}</div> <div>{t('common.userProfile.helpCenter')}</div>

+ 4
- 3
web/app/components/header/account-setting/members-page/index.tsx Vedi File

import { Plan } from '@/app/components/billing/type' import { Plan } from '@/app/components/billing/type'
import UpgradeBtn from '@/app/components/billing/upgrade-btn' import UpgradeBtn from '@/app/components/billing/upgrade-btn'
import { NUM_INFINITE } from '@/app/components/billing/config' import { NUM_INFINITE } from '@/app/components/billing/config'
import { LanguagesSupportedUnderscore, getModelRuntimeSupported } from '@/utils/language'
dayjs.extend(relativeTime) dayjs.extend(relativeTime)


const MembersPage = () => { const MembersPage = () => {
normal: t('common.members.normal'), normal: t('common.members.normal'),
} }
const { locale } = useContext(I18n) const { locale } = useContext(I18n)
const language = getModelRuntimeSupported(locale)
const { userProfile, currentWorkspace, isCurrentWorkspaceManager } = useAppContext() const { userProfile, currentWorkspace, isCurrentWorkspaceManager } = useAppContext()
const { data, mutate } = useSWR({ url: '/workspaces/current/members' }, fetchMembers) const { data, mutate } = useSWR({ url: '/workspaces/current/members' }, fetchMembers)
const [inviteModalVisible, setInviteModalVisible] = useState(false) const [inviteModalVisible, setInviteModalVisible] = useState(false)
{isNotUnlimitedMemberPlan {isNotUnlimitedMemberPlan
? ( ? (
<div className='flex space-x-1'> <div className='flex space-x-1'>
<div>{t('billing.plansCommon.member')}{locale === 'en' && accounts.length > 1 && 's'}</div>
<div>{t('billing.plansCommon.member')}{language !== LanguagesSupportedUnderscore[1] && accounts.length > 1 && 's'}</div>
<div className='text-gray-700'>{accounts.length}</div> <div className='text-gray-700'>{accounts.length}</div>
<div>/</div> <div>/</div>
<div>{plan.total.teamMembers === NUM_INFINITE ? t('billing.plansCommon.unlimited') : plan.total.teamMembers}</div> <div>{plan.total.teamMembers === NUM_INFINITE ? t('billing.plansCommon.unlimited') : plan.total.teamMembers}</div>
: ( : (
<div className='flex space-x-1'> <div className='flex space-x-1'>
<div>{accounts.length}</div> <div>{accounts.length}</div>
<div>{t('billing.plansCommon.memberAfter')}{locale === 'en' && accounts.length > 1 && 's'}</div>
<div>{t('billing.plansCommon.memberAfter')}{language !== LanguagesSupportedUnderscore[1] && accounts.length > 1 && 's'}</div>
</div> </div>
)} )}
</div> </div>

+ 3
- 1
web/app/components/tools/edit-custom-collection-modal/test-api.tsx Vedi File

import Drawer from '@/app/components/base/drawer-plus' import Drawer from '@/app/components/base/drawer-plus'
import I18n from '@/context/i18n' import I18n from '@/context/i18n'
import { testAPIAvailable } from '@/service/tools' import { testAPIAvailable } from '@/service/tools'
import { getModelRuntimeSupported } from '@/utils/language'


type Props = { type Props = {
customCollection: CustomCollectionBackend customCollection: CustomCollectionBackend
}) => { }) => {
const { t } = useTranslation() const { t } = useTranslation()
const { locale } = useContext(I18n) const { locale } = useContext(I18n)
const language = getModelRuntimeSupported(locale)
const [credentialsModalShow, setCredentialsModalShow] = useState(false) const [credentialsModalShow, setCredentialsModalShow] = useState(false)
const [tempCredential, setTempCredential] = React.useState<Credential>(customCollection.credentials) const [tempCredential, setTempCredential] = React.useState<Credential>(customCollection.credentials)
const [result, setResult] = useState<string>('') const [result, setResult] = useState<string>('')
{parameters.map((item, index) => ( {parameters.map((item, index) => (
<tr key={index} className='border-b last:border-0 border-gray-200'> <tr key={index} className='border-b last:border-0 border-gray-200'>
<td className="py-2 pl-3 pr-2.5"> <td className="py-2 pl-3 pr-2.5">
{item.label[locale === 'en' ? 'en_US' : 'zh_Hans']}
{item.label[language]}
</td> </td>
<td className=""> <td className="">
<input <input

+ 4
- 2
web/app/components/tools/tool-list/header.tsx Vedi File

import { CollectionType, LOC } from '../types' import { CollectionType, LOC } from '../types'
import { Settings01 } from '../../base/icons/src/vender/line/general' import { Settings01 } from '../../base/icons/src/vender/line/general'
import I18n from '@/context/i18n' import I18n from '@/context/i18n'
import { getModelRuntimeSupported } from '@/utils/language'


type Props = { type Props = {
icon: JSX.Element icon: JSX.Element
onShowEditCustomCollection, onShowEditCustomCollection,
}) => { }) => {
const { locale } = useContext(I18n) const { locale } = useContext(I18n)
const language = getModelRuntimeSupported(locale)
const { t } = useTranslation() const { t } = useTranslation()
const isInToolsPage = loc === LOC.tools const isInToolsPage = loc === LOC.tools
const isInDebugPage = !isInToolsPage const isInDebugPage = !isInToolsPage
{icon} {icon}
<div className='ml-3 grow w-0'> <div className='ml-3 grow w-0'>
<div className='flex items-center h-6 space-x-1'> <div className='flex items-center h-6 space-x-1'>
<div className={cn(isInDebugPage && 'truncate', 'text-base font-semibold text-gray-900')}>{collection.label[locale === 'en' ? 'en_US' : 'zh_Hans']}</div>
<div className={cn(isInDebugPage && 'truncate', 'text-base font-semibold text-gray-900')}>{collection.label[language]}</div>
<div className='text-xs font-normal text-gray-500'>·</div> <div className='text-xs font-normal text-gray-500'>·</div>
<div className='text-xs font-normal text-gray-500'>{t('tools.author')}&nbsp;{collection.author}</div> <div className='text-xs font-normal text-gray-500'>{t('tools.author')}&nbsp;{collection.author}</div>
</div> </div>
{collection.description && ( {collection.description && (
<div className={cn('leading-[18px] text-[13px] font-normal text-gray-500')}> <div className={cn('leading-[18px] text-[13px] font-normal text-gray-500')}>
{collection.description[locale === 'en' ? 'en_US' : 'zh_Hans']}
{collection.description[language]}
</div> </div>
)} )}
</div> </div>

+ 4
- 2
web/app/components/tools/tool-list/item.tsx Vedi File

import TooltipPlus from '../../base/tooltip-plus' import TooltipPlus from '../../base/tooltip-plus'
import I18n from '@/context/i18n' import I18n from '@/context/i18n'
import SettingBuiltInTool from '@/app/components/app/configuration/config/agent/agent-tools/setting-built-in-tool' import SettingBuiltInTool from '@/app/components/app/configuration/config/agent/agent-tools/setting-built-in-tool'
import { getModelRuntimeSupported } from '@/utils/language'


type Props = { type Props = {
collection: Collection collection: Collection
}) => { }) => {
const { t } = useTranslation() const { t } = useTranslation()
const { locale } = useContext(I18n) const { locale } = useContext(I18n)
const language = getModelRuntimeSupported(locale)
const isBuiltIn = collection.type === CollectionType.builtIn const isBuiltIn = collection.type === CollectionType.builtIn
const canShowDetail = !isBuiltIn || (isBuiltIn && isInToolsPage) const canShowDetail = !isBuiltIn || (isBuiltIn && isInToolsPage)
const [showDetail, setShowDetail] = useState(false) const [showDetail, setShowDetail] = useState(false)
<div className='flex items-start w-full'> <div className='flex items-start w-full'>
{icon} {icon}
<div className='ml-3 w-0 grow'> <div className='ml-3 w-0 grow'>
<div className={cn('text-base font-semibold text-gray-900 truncate')}>{payload.label[locale === 'en' ? 'en_US' : 'zh_Hans']}</div>
<div className={cn('text-base font-semibold text-gray-900 truncate')}>{payload.label[language]}</div>
<div className={cn('leading-[18px] text-[13px] font-normal text-gray-500')}> <div className={cn('leading-[18px] text-[13px] font-normal text-gray-500')}>
{payload.description[locale === 'en' ? 'en_US' : 'zh_Hans']}
{payload.description[language]}
</div> </div>
</div> </div>
</div> </div>

+ 3
- 2
web/app/components/tools/tool-nav-list/item.tsx Vedi File

import AppIcon from '../../base/app-icon' import AppIcon from '../../base/app-icon'
import type { Collection } from '@/app/components/tools/types' import type { Collection } from '@/app/components/tools/types'
import I18n from '@/context/i18n' import I18n from '@/context/i18n'
import { getModelRuntimeSupported } from '@/utils/language'


type Props = { type Props = {
isCurrent: boolean isCurrent: boolean
onClick, onClick,
}) => { }) => {
const { locale } = useContext(I18n) const { locale } = useContext(I18n)
const language = getModelRuntimeSupported(locale)
return ( return (
<div <div
className={cn(isCurrent && 'bg-white shadow-xs rounded-lg', 'mt-1 flex h-9 items-center px-2 space-x-2 cursor-pointer')} className={cn(isCurrent && 'bg-white shadow-xs rounded-lg', 'mt-1 flex h-9 items-center px-2 space-x-2 cursor-pointer')}
background={payload.icon.background} background={payload.icon.background}
/> />
)} )}
<div className={cn(isCurrent && 'text-primary-600 font-semibold', 'leading-5 text-sm font-normal truncate')}>{payload.label[locale === 'en' ? 'en_US' : 'zh_Hans']}</div>
<div className={cn(isCurrent && 'text-primary-600 font-semibold', 'leading-5 text-sm font-normal truncate')}>{payload.label[language]}</div>


</div> </div>
) )

+ 1
- 4
web/app/components/tools/types.ts Vedi File

export type Tool = { export type Tool = {
name: string name: string
label: TypeWithI18N label: TypeWithI18N
description: {
zh_Hans: string
en_US: string
}
description: any
parameters: ToolParameter[] parameters: ToolParameter[]
} }



+ 6
- 4
web/app/install/installForm.tsx Vedi File

import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import Link from 'next/link' import Link from 'next/link'
import { useRouter } from 'next/navigation' import { useRouter } from 'next/navigation'
import { useContext } from 'use-context-selector'
// import { useContext } from 'use-context-selector'
import Toast from '../components/base/toast' import Toast from '../components/base/toast'
import Loading from '../components/base/loading' import Loading from '../components/base/loading'
import Button from '@/app/components/base/button' import Button from '@/app/components/base/button'
import I18n from '@/context/i18n'
// import I18n from '@/context/i18n'

import { fetchSetupStatus, setup } from '@/service/common' import { fetchSetupStatus, setup } from '@/service/common'
import type { SetupStatusResponse } from '@/models/common' import type { SetupStatusResponse } from '@/models/common'




const InstallForm = () => { const InstallForm = () => {
const { t } = useTranslation() const { t } = useTranslation()
const { locale } = useContext(I18n)
// const { locale } = useContext(I18n)
// const language = getModelRuntimeSupported(locale)
const router = useRouter() const router = useRouter()


const [email, setEmail] = React.useState('') const [email, setEmail] = React.useState('')
<Link <Link
className='text-primary-600' className='text-primary-600'
target={'_blank'} target={'_blank'}
href={`https://docs.dify.ai/${locale === 'en' ? '' : `v/${locale.toLowerCase()}/`}community/open-source`}
href={'https://docs.dify.ai/user-agreement/open-source'}
>{t('login.license.link')}</Link> >{t('login.license.link')}</Link>
</div> </div>
</div> </div>

+ 4
- 3
web/app/signin/normalForm.tsx Vedi File

import { useContext } from 'use-context-selector' import { useContext } from 'use-context-selector'
import Toast from '../components/base/toast' import Toast from '../components/base/toast'
import style from './page.module.css' import style from './page.module.css'
// import Tooltip from '@/app/components/base/tooltip/index'
import { IS_CE_EDITION, apiPrefix } from '@/config' import { IS_CE_EDITION, apiPrefix } from '@/config'
import Button from '@/app/components/base/button' import Button from '@/app/components/base/button'
import { login, oauth } from '@/service/common' import { login, oauth } from '@/service/common'
import I18n from '@/context/i18n' import I18n from '@/context/i18n'
import { LanguagesSupportedUnderscore, getModelRuntimeSupported } from '@/utils/language'


const validEmailReg = /^[\w\.-]+@([\w-]+\.)+[\w-]{2,}$/ const validEmailReg = /^[\w\.-]+@([\w-]+\.)+[\w-]{2,}$/


const { t } = useTranslation() const { t } = useTranslation()
const router = useRouter() const router = useRouter()
const { locale } = useContext(I18n) const { locale } = useContext(I18n)
const language = getModelRuntimeSupported(locale)


const [state, dispatch] = useReducer(reducer, { const [state, dispatch] = useReducer(reducer, {
formValid: false, formValid: false,
<Link <Link
className='text-primary-600' className='text-primary-600'
target={'_blank'} target={'_blank'}
href={locale === 'en' ? 'https://docs.dify.ai/user-agreement/terms-of-service' : 'https://docs.dify.ai/v/zh-hans/user-agreement/terms-of-service'}
href={language !== LanguagesSupportedUnderscore[1] ? 'https://docs.dify.ai/user-agreement/terms-of-service' : 'https://docs.dify.ai/v/zh-hans/user-agreement/terms-of-service'}
>{t('login.tos')}</Link> >{t('login.tos')}</Link>
&nbsp;&&nbsp; &nbsp;&&nbsp;
<Link <Link
className='text-primary-600' className='text-primary-600'
target={'_blank'} target={'_blank'}
href={locale === 'en' ? 'https://docs.dify.ai/user-agreement/privacy-policy' : 'https://docs.dify.ai/v/zh-hans/user-agreement/privacy-policy'}
href={language !== LanguagesSupportedUnderscore[1] ? 'https://docs.dify.ai/user-agreement/privacy-policy' : 'https://docs.dify.ai/v/zh-hans/user-agreement/privacy-policy'}
>{t('login.pp')}</Link> >{t('login.pp')}</Link>
</div> </div>



+ 4
- 4
web/app/signin/oneMoreStep.tsx Vedi File

import Link from 'next/link' import Link from 'next/link'
import useSWR from 'swr' import useSWR from 'swr'
import { useRouter } from 'next/navigation' import { useRouter } from 'next/navigation'
import { useContext } from 'use-context-selector'
// import { useContext } from 'use-context-selector'
import Button from '@/app/components/base/button' import Button from '@/app/components/base/button'
import Tooltip from '@/app/components/base/tooltip/index' import Tooltip from '@/app/components/base/tooltip/index'


import { LanguagesSupported, languages } from '@/utils/language' import { LanguagesSupported, languages } from '@/utils/language'
import { oneMoreStep } from '@/service/common' import { oneMoreStep } from '@/service/common'
import Toast from '@/app/components/base/toast' import Toast from '@/app/components/base/toast'
import I18n from '@/context/i18n'
// import I18n from '@/context/i18n'


type IState = { type IState = {
formState: 'processing' | 'error' | 'success' | 'initial' formState: 'processing' | 'error' | 'success' | 'initial'
const OneMoreStep = () => { const OneMoreStep = () => {
const { t } = useTranslation() const { t } = useTranslation()
const router = useRouter() const router = useRouter()
const { locale } = useContext(I18n)
// const { locale } = useContext(I18n)


const [state, dispatch] = useReducer(reducer, { const [state, dispatch] = useReducer(reducer, {
formState: 'initial', formState: 'initial',
<Link <Link
className='text-primary-600' className='text-primary-600'
target={'_blank'} target={'_blank'}
href={`https://docs.dify.ai/${locale === 'en' ? '' : `v/${locale.toLowerCase()}`}/community/open-source`}
href={'https://docs.dify.ai/user-agreement/open-source'}
>{t('login.license.link')}</Link> >{t('login.license.link')}</Link>
</div> </div>
</div> </div>

+ 1
- 1
web/models/common.ts Vedi File



export type CodeBasedExtensionItem = { export type CodeBasedExtensionItem = {
name: string name: string
label: I18nText
label: any
form_schema: CodeBasedExtensionForm[] form_schema: CodeBasedExtensionForm[]
} }
export type CodeBasedExtension = { export type CodeBasedExtension = {

+ 2
- 0
web/utils/language.ts Vedi File

} }


export const LanguagesSupported = ['en-US', 'zh-Hans', 'pt-BR', 'es-ES', 'fr-FR', 'de-DE', 'ja-JP', 'ko-KR', 'ru-RU', 'it-IT'] export const LanguagesSupported = ['en-US', 'zh-Hans', 'pt-BR', 'es-ES', 'fr-FR', 'de-DE', 'ja-JP', 'ko-KR', 'ru-RU', 'it-IT']
export const LanguagesSupportedUnderscore = ['en_US', 'zh_Hans', 'pt_BR', 'es_ES', 'fr_FR', 'de_DE', 'ja_JP', 'ko_KR', 'ru_RU', 'it_IT']

export const languages = [ export const languages = [
{ {
value: 'en-US', value: 'en-US',

Loading…
Annulla
Salva