refactor: generalize method for getting doc link respecting locale and fix error link paths (#20801)

This commit is contained in:
Bowen Liang
2025-06-13 16:58:43 +08:00
committed by GitHub
parent 3a628bc671
commit f4df759ba6
36 changed files with 149 additions and 136 deletions

View File

@@ -25,9 +25,8 @@ import Loading from '@/app/components/base/loading'
import DatasetDetailContext from '@/context/dataset-detail'
import { DataSourceType } from '@/models/datasets'
import useBreakpoints, { MediaType } from '@/hooks/use-breakpoints'
import { LanguagesSupported } from '@/i18n/language'
import { useStore } from '@/app/components/app/store'
import { getLocaleOnClient } from '@/i18n'
import { useDocLink } from '@/context/i18n'
import { useAppContext } from '@/context/app-context'
import Tooltip from '@/app/components/base/tooltip'
import LinkedAppsPanel from '@/app/components/base/linked-apps-panel'
@@ -45,9 +44,9 @@ type IExtraInfoProps = {
}
const ExtraInfo = ({ isMobile, relatedApps, expand }: IExtraInfoProps) => {
const locale = getLocaleOnClient()
const [isShowTips, { toggle: toggleTips, set: setShowTips }] = useBoolean(!isMobile)
const { t } = useTranslation()
const docLink = useDocLink()
const hasRelatedApps = relatedApps?.data && relatedApps?.data?.length > 0
const relatedAppsTotal = relatedApps?.data?.length || 0
@@ -97,11 +96,7 @@ const ExtraInfo = ({ isMobile, relatedApps, expand }: IExtraInfoProps) => {
<div className='my-2 text-xs text-text-tertiary'>{t('common.datasetMenus.emptyTip')}</div>
<a
className='mt-2 inline-flex cursor-pointer items-center text-xs text-text-accent'
href={
locale === LanguagesSupported[1]
? 'https://docs.dify.ai/zh-hans/guides/knowledge-base/integrate-knowledge-within-application'
: 'https://docs.dify.ai/guides/knowledge-base/integrate-knowledge-within-application'
}
href={docLink('/guides/knowledge-base/integrate-knowledge-within-application')}
target='_blank' rel='noopener noreferrer'
>
<RiBookOpenLine className='mr-1 text-text-accent' />

View File

@@ -1,13 +1,11 @@
'use client'
import type { FC } from 'react'
import React from 'react'
import { useContext } from 'use-context-selector'
import { useTranslation } from 'react-i18next'
import OperationBtn from '@/app/components/app/configuration/base/operation-btn'
import Panel from '@/app/components/app/configuration/base/feature-panel'
import { MessageClockCircle } from '@/app/components/base/icons/src/vender/solid/general'
import I18n from '@/context/i18n'
import { LanguagesSupported } from '@/i18n/language'
import { useDocLink } from '@/context/i18n'
type Props = {
showWarning: boolean
@@ -19,7 +17,7 @@ const HistoryPanel: FC<Props> = ({
onShowEditModal,
}) => {
const { t } = useTranslation()
const { locale } = useContext(I18n)
const docLink = useDocLink()
return (
<Panel
@@ -45,9 +43,8 @@ const HistoryPanel: FC<Props> = ({
{showWarning && (
<div className='flex justify-between rounded-b-xl bg-background-section-burn px-3 py-2 text-xs text-text-secondary'>
<div>{t('appDebug.feature.conversationHistory.tip')}
<a href={`${locale === LanguagesSupported[1]
? 'https://docs.dify.ai/zh-hans/learn-more/extended-reading/prompt-engineering/README'
: 'https://docs.dify.ai/en/features/prompt-engineering'}`}
<a href={docLink('/learn-more/extended-reading/what-is-llmops',
{ 'zh-Hans': '/learn-more/extended-reading/prompt-engineering/README' })}
target='_blank' rel='noopener noreferrer'
className='text-[#155EEF]'>{t('appDebug.feature.conversationHistory.learnMore')}
</a>

View File

@@ -31,6 +31,7 @@ import {
import { ModelTypeEnum } from '@/app/components/header/account-setting/model-provider-page/declarations'
import { fetchMembers } from '@/service/common'
import type { Member } from '@/models/common'
import { useDocLink } from '@/context/i18n'
type SettingsModalProps = {
currentDataset: DataSet
@@ -58,6 +59,7 @@ const SettingsModal: FC<SettingsModalProps> = ({
currentModel: isRerankDefaultModelValid,
} = useModelListAndDefaultModelAndCurrentProviderAndModel(ModelTypeEnum.rerank)
const { t } = useTranslation()
const docLink = useDocLink()
const { notify } = useToastContext()
const ref = useRef(null)
const isExternal = currentDataset.provider === 'external'
@@ -328,7 +330,7 @@ const SettingsModal: FC<SettingsModalProps> = ({
<div>
<div className='system-sm-semibold text-text-secondary'>{t('datasetSettings.form.retrievalSetting.title')}</div>
<div className='text-xs font-normal leading-[18px] text-text-tertiary'>
<a target='_blank' rel='noopener noreferrer' href='https://docs.dify.ai/guides/knowledge-base/create-knowledge-and-upload-documents#id-4-retrieval-settings' className='text-text-accent'>{t('datasetSettings.form.retrievalSetting.learnMore')}</a>
<a target='_blank' rel='noopener noreferrer' href={docLink('/guides/knowledge-base/create-knowledge-and-upload-documents/setting-indexing-methods#setting-the-retrieval-setting')} className='text-text-accent'>{t('datasetSettings.form.retrievalSetting.learnMore')}</a>
{t('datasetSettings.form.retrievalSetting.description')}
</div>
</div>

View File

@@ -2,9 +2,7 @@
import type { FC } from 'react'
import React from 'react'
import { useTranslation } from 'react-i18next'
import { useContext } from 'use-context-selector'
import I18n from '@/context/i18n'
import { LanguagesSupported } from '@/i18n/language'
import { useDocLink } from '@/context/i18n'
type Props = {
onReturnToSimpleMode: () => void
}
@@ -13,7 +11,7 @@ const AdvancedModeWarning: FC<Props> = ({
onReturnToSimpleMode,
}) => {
const { t } = useTranslation()
const { locale } = useContext(I18n)
const docLink = useDocLink()
const [show, setShow] = React.useState(true)
if (!show)
return null
@@ -25,7 +23,7 @@ const AdvancedModeWarning: FC<Props> = ({
<span className='text-gray-700'>{t('appDebug.promptMode.advancedWarning.description')}</span>
<a
className='font-medium text-[#155EEF]'
href={`https://docs.dify.ai/${locale === LanguagesSupported[1] ? '/guides/features/prompt-engineering' : 'features/prompt-engineering'}`}
href={docLink('/guides/features/prompt-engineering')}
target='_blank' rel='noopener noreferrer'
>
{t('appDebug.promptMode.advancedWarning.learnMore')}

View File

@@ -29,6 +29,7 @@ import { NEED_REFRESH_APP_LIST_KEY } from '@/config'
import { getRedirection } from '@/utils/app-redirection'
import FullScreenModal from '@/app/components/base/fullscreen-modal'
import useTheme from '@/hooks/use-theme'
import { useDocLink } from '@/context/i18n'
type CreateAppProps = {
onSuccess: () => void
@@ -303,31 +304,33 @@ function AppTypeCard({ icon, title, description, active, onClick }: AppTypeCardP
function AppPreview({ mode }: { mode: AppMode }) {
const { t } = useTranslation()
const docLink = useDocLink()
const modeToPreviewInfoMap = {
'chat': {
title: t('app.types.chatbot'),
description: t('app.newApp.chatbotUserDescription'),
link: 'https://docs.dify.ai/guides/application-orchestrate/readme',
link: docLink('/guides/application-orchestrate/chatbot-application'),
},
'advanced-chat': {
title: t('app.types.advanced'),
description: t('app.newApp.advancedUserDescription'),
link: 'https://docs.dify.ai/en/guides/workflow/README',
link: docLink('/guides/workflow/readme'),
},
'agent-chat': {
title: t('app.types.agent'),
description: t('app.newApp.agentUserDescription'),
link: 'https://docs.dify.ai/en/guides/application-orchestrate/agent',
link: docLink('/guides/application-orchestrate/agent'),
},
'completion': {
title: t('app.newApp.completeApp'),
description: t('app.newApp.completionUserDescription'),
link: null,
link: docLink('/guides/application-orchestrate/text-generator',
{ 'zh-Hans': '/guides/application-orchestrate/readme' }),
},
'workflow': {
title: t('app.types.workflow'),
description: t('app.newApp.workflowUserDescription'),
link: 'https://docs.dify.ai/en/guides/workflow/README',
link: docLink('/guides/workflow/readme'),
},
}
const previewInfo = modeToPreviewInfoMap[mode]

View File

@@ -3,13 +3,11 @@ import type { FC } from 'react'
import React from 'react'
import { ArrowTopRightOnSquareIcon } from '@heroicons/react/24/outline'
import { useTranslation } from 'react-i18next'
import { useContext } from 'use-context-selector'
import { useDocLink } from '@/context/i18n'
import type { AppMode } from '@/types/app'
import I18n from '@/context/i18n'
import Button from '@/app/components/base/button'
import Modal from '@/app/components/base/modal'
import Tag from '@/app/components/base/tag'
import { LanguagesSupported } from '@/i18n/language'
type IShareLinkProps = {
isShow: boolean
@@ -43,7 +41,7 @@ const CustomizeModal: FC<IShareLinkProps> = ({
mode,
}) => {
const { t } = useTranslation()
const { locale } = useContext(I18n)
const docLink = useDocLink()
const isChatApp = mode === 'chat' || mode === 'advanced-chat'
return <Modal
@@ -101,10 +99,7 @@ const CustomizeModal: FC<IShareLinkProps> = ({
className='mt-2'
onClick={() =>
window.open(
`https://docs.dify.ai/${locale !== LanguagesSupported[1]
? 'user-guide/launching-dify-apps/developing-with-apis'
: `${locale.toLowerCase()}/guides/application-publishing/developing-with-apis`
}`,
docLink('/guides/application-publishing/developing-with-apis'),
'_blank',
)
}

View File

@@ -4,7 +4,6 @@ import React, { useCallback, useEffect, useState } from 'react'
import { RiArrowRightSLine, RiCloseLine } from '@remixicon/react'
import Link from 'next/link'
import { Trans, useTranslation } from 'react-i18next'
import { useContext } from 'use-context-selector'
import { SparklesSoft } from '@/app/components/base/icons/src/public/common'
import Modal from '@/app/components/base/modal'
import ActionButton from '@/app/components/base/action-button'
@@ -19,14 +18,14 @@ import { SimpleSelect } from '@/app/components/base/select'
import type { AppDetailResponse } from '@/models/app'
import type { AppIconType, AppSSO, Language } from '@/types/app'
import { useToastContext } from '@/app/components/base/toast'
import { LanguagesSupported, languages } from '@/i18n/language'
import { languages } from '@/i18n/language'
import Tooltip from '@/app/components/base/tooltip'
import { useProviderContext } from '@/context/provider-context'
import { useModalContext } from '@/context/modal-context'
import type { AppIconSelection } from '@/app/components/base/app-icon-picker'
import AppIconPicker from '@/app/components/base/app-icon-picker'
import I18n from '@/context/i18n'
import cn from '@/utils/classnames'
import { useDocLink } from '@/context/i18n'
export type ISettingsModalProps = {
isChat: boolean
@@ -98,7 +97,7 @@ const SettingsModal: FC<ISettingsModalProps> = ({
const [language, setLanguage] = useState(default_language)
const [saveLoading, setSaveLoading] = useState(false)
const { t } = useTranslation()
const { locale } = useContext(I18n)
const docLink = useDocLink()
const [showAppIconPicker, setShowAppIconPicker] = useState(false)
const [appIcon, setAppIcon] = useState<AppIconSelection>(
@@ -238,7 +237,8 @@ const SettingsModal: FC<ISettingsModalProps> = ({
</div>
<div className='system-xs-regular mt-0.5 text-text-tertiary'>
<span>{t(`${prefixSettings}.modalTip`)}</span>
<Link href={`${locale === LanguagesSupported[1] ? 'https://docs.dify.ai/zh-hans/guides/application-publishing/launch-your-webapp-quickly#she-zhi-ni-de-ai-zhan-dian' : 'https://docs.dify.ai/en/guides/application-publishing/launch-your-webapp-quickly/README'}`} target='_blank' rel='noopener noreferrer' className='text-text-accent'>{t('common.operation.learnMore')}</Link>
<Link href={docLink('/guides/application-publishing/launch-your-webapp-quickly/README')}
target='_blank' rel='noopener noreferrer' className='text-text-accent'>{t('common.operation.learnMore')}</Link>
</div>
</div>
{/* form body */}

View File

@@ -1,6 +1,5 @@
import React from 'react'
import { useTranslation } from 'react-i18next'
import { useContext } from 'use-context-selector'
import { RiCloseLine, RiInformation2Fill } from '@remixicon/react'
import DialogWrapper from '@/app/components/base/features/new-feature-panel/dialog-wrapper'
import { useDefaultModel } from '@/app/components/header/account-setting/model-provider-page/hooks'
@@ -19,8 +18,7 @@ import Moderation from '@/app/components/base/features/new-feature-panel/moderat
import AnnotationReply from '@/app/components/base/features/new-feature-panel/annotation-reply'
import type { PromptVariable } from '@/models/debug'
import type { InputVar } from '@/app/components/workflow/types'
import I18n from '@/context/i18n'
import { LanguagesSupported } from '@/i18n/language'
import { useDocLink } from '@/context/i18n'
type Props = {
show: boolean
@@ -48,7 +46,7 @@ const NewFeaturePanel = ({
onAutoAddPromptVariable,
}: Props) => {
const { t } = useTranslation()
const { locale } = useContext(I18n)
const docLink = useDocLink()
const { data: speech2textDefaultModel } = useDefaultModel(ModelTypeEnum.speech2text)
const { data: text2speechDefaultModel } = useDefaultModel(ModelTypeEnum.tts)
@@ -80,7 +78,7 @@ const NewFeaturePanel = ({
<span>{isChatMode ? t('workflow.common.fileUploadTip') : t('workflow.common.ImageUploadLegacyTip')}</span>
<a
className='text-text-accent'
href={`https://docs.dify.ai/${locale === LanguagesSupported[1] ? 'v/zh-hans/' : ''}guides/workflow/bulletin`}
href={docLink('/guides/workflow/bulletin')}
target='_blank' rel='noopener noreferrer'
>{t('workflow.common.featuresDocLink')}</a>
</div>

View File

@@ -63,6 +63,7 @@ import CustomDialog from '@/app/components/base/dialog'
import { PortalToFollowElem, PortalToFollowElemContent, PortalToFollowElemTrigger } from '@/app/components/base/portal-to-follow-elem'
import { AlertTriangle } from '@/app/components/base/icons/src/vender/solid/alertsAndFeedback'
import { noop } from 'lodash-es'
import { useDocLink } from '@/context/i18n'
const TextLabel: FC<PropsWithChildren> = (props) => {
return <label className='system-sm-semibold text-text-secondary'>{props.children}</label>
@@ -146,6 +147,7 @@ const StepTwo = ({
updateRetrievalMethodCache,
}: StepTwoProps) => {
const { t } = useTranslation()
const docLink = useDocLink()
const { locale } = useContext(I18n)
const media = useBreakpoints()
const isMobile = media === MediaType.mobile
@@ -962,7 +964,9 @@ const StepTwo = ({
<div className={'mb-1'}>
<div className='system-md-semibold mb-0.5 text-text-secondary'>{t('datasetSettings.form.retrievalSetting.title')}</div>
<div className='body-xs-regular text-text-tertiary'>
<a target='_blank' rel='noopener noreferrer' href='https://docs.dify.ai/guides/knowledge-base/create-knowledge-and-upload-documents#id-4-retrieval-settings' className='text-text-accent'>{t('datasetSettings.form.retrievalSetting.learnMore')}</a>
<a target='_blank' rel='noopener noreferrer'
href={docLink('/guides/knowledge-base/create-knowledge-and-upload-documents')}
className='text-text-accent'>{t('datasetSettings.form.retrievalSetting.learnMore')}</a>
{t('datasetSettings.form.retrievalSetting.longDescription')}
</div>
</div>

View File

@@ -4,6 +4,7 @@ import React, { useCallback, useState } from 'react'
import { useTranslation } from 'react-i18next'
import Input from './input'
import Button from '@/app/components/base/button'
import { useDocLink } from '@/context/i18n'
const I18N_PREFIX = 'datasetCreation.stepOne.website'
@@ -17,6 +18,7 @@ const UrlInput: FC<Props> = ({
onRun,
}) => {
const { t } = useTranslation()
const docLink = useDocLink()
const [url, setUrl] = useState('')
const handleUrlChange = useCallback((url: string | number) => {
setUrl(url as string)
@@ -32,7 +34,7 @@ const UrlInput: FC<Props> = ({
<Input
value={url}
onChange={handleUrlChange}
placeholder='https://docs.dify.ai'
placeholder={docLink()}
/>
<Button
variant='primary'

View File

@@ -4,6 +4,7 @@ import React, { useCallback, useState } from 'react'
import { useTranslation } from 'react-i18next'
import Input from './input'
import Button from '@/app/components/base/button'
import { useDocLink } from '@/context/i18n'
const I18N_PREFIX = 'datasetCreation.stepOne.website'
@@ -17,6 +18,7 @@ const UrlInput: FC<Props> = ({
onRun,
}) => {
const { t } = useTranslation()
const docLink = useDocLink()
const [url, setUrl] = useState('')
const handleUrlChange = useCallback((url: string | number) => {
setUrl(url as string)
@@ -32,7 +34,7 @@ const UrlInput: FC<Props> = ({
<Input
value={url}
onChange={handleUrlChange}
placeholder='https://docs.dify.ai'
placeholder={docLink()}
/>
<Button
variant='primary'

View File

@@ -29,8 +29,7 @@ import { useChildSegmentListKey, useSegmentListKey } from '@/service/knowledge/u
import useEditDocumentMetadata from '../metadata/hooks/use-edit-dataset-metadata'
import DatasetMetadataDrawer from '../metadata/metadata-dataset/dataset-metadata-drawer'
import StatusWithAction from '../common/document-status-with-action/status-with-action'
import { LanguagesSupported } from '@/i18n/language'
import { getLocaleOnClient } from '@/i18n'
import { useDocLink } from '@/context/i18n'
const FolderPlusIcon = ({ className }: React.SVGProps<SVGElement>) => {
return <svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg" className={className ?? ''}>
@@ -86,6 +85,7 @@ const DEFAULT_LIMIT = 10
const Documents: FC<IDocumentsProps> = ({ datasetId }) => {
const { t } = useTranslation()
const docLink = useDocLink()
const { plan } = useProviderContext()
const isFreePlan = plan.type === 'sandbox'
const [inputValue, setInputValue] = useState<string>('') // the input value
@@ -100,7 +100,6 @@ const Documents: FC<IDocumentsProps> = ({ datasetId }) => {
const isDataSourceWeb = dataset?.data_source_type === DataSourceType.WEB
const isDataSourceFile = dataset?.data_source_type === DataSourceType.FILE
const embeddingAvailable = !!dataset?.embedding_available
const locale = getLocaleOnClient()
const debouncedSearchValue = useDebounce(searchValue, { wait: 500 })
const { data: documentsRes, isFetching: isListLoading } = useDocumentList({
@@ -262,11 +261,7 @@ const Documents: FC<IDocumentsProps> = ({ datasetId }) => {
<a
className='flex items-center text-text-accent'
target='_blank'
href={
locale === LanguagesSupported[1]
? 'https://docs.dify.ai/zh-hans/guides/knowledge-base/integrate-knowledge-within-application'
: 'https://docs.dify.ai/en/guides/knowledge-base/integrate-knowledge-within-application'
}
href={docLink('/guides/knowledge-base/integrate-knowledge-within-application')}
>
<span>{t('datasetDocuments.list.learnMore')}</span>
<RiExternalLinkLine className='h-3 w-3' />

View File

@@ -5,6 +5,7 @@ import { RiBookOpenLine } from '@remixicon/react'
import type { CreateExternalAPIReq, FormSchema } from '../declarations'
import Input from '@/app/components/base/input'
import cn from '@/utils/classnames'
import { useDocLink } from '@/context/i18n'
type FormProps = {
className?: string
@@ -26,6 +27,7 @@ const Form: FC<FormProps> = React.memo(({
inputClassName,
}) => {
const { t, i18n } = useTranslation()
const docLink = useDocLink()
const [changeKey, setChangeKey] = useState('')
const handleFormChange = (key: string, val: string) => {
@@ -57,7 +59,7 @@ const Form: FC<FormProps> = React.memo(({
</label>
{variable === 'endpoint' && (
<a
href={'https://docs.dify.ai/guides/knowledge-base/external-knowledge-api-documentation' || '/'}
href={docLink('/guides/knowledge-base/external-knowledge-api-documentation') || '/'}
target='_blank'
rel='noopener noreferrer'
className='body-xs-regular flex items-center text-text-accent'

View File

@@ -12,6 +12,7 @@ import ActionButton from '@/app/components/base/action-button'
import Button from '@/app/components/base/button'
import Loading from '@/app/components/base/loading'
import { useModalContext } from '@/context/modal-context'
import { useDocLink } from '@/context/i18n'
type ExternalAPIPanelProps = {
onClose: () => void
@@ -19,6 +20,7 @@ type ExternalAPIPanelProps = {
const ExternalAPIPanel: React.FC<ExternalAPIPanelProps> = ({ onClose }) => {
const { t } = useTranslation()
const docLink = useDocLink()
const { setShowExternalKnowledgeAPIModal } = useModalContext()
const { externalKnowledgeApiList, mutateExternalKnowledgeApis, isLoading } = useExternalKnowledgeApi()
@@ -50,7 +52,8 @@ const ExternalAPIPanel: React.FC<ExternalAPIPanelProps> = ({ onClose }) => {
<div className='flex grow flex-col items-start gap-1'>
<div className='system-xl-semibold self-stretch text-text-primary'>{t('dataset.externalAPIPanelTitle')}</div>
<div className='body-xs-regular self-stretch text-text-tertiary'>{t('dataset.externalAPIPanelDescription')}</div>
<a className='flex cursor-pointer items-center justify-center gap-1 self-stretch' href='https://docs.dify.ai/guides/knowledge-base/external-knowledge-api-documentation' target='_blank'>
<a className='flex cursor-pointer items-center justify-center gap-1 self-stretch'
href={docLink('/guides/knowledge-base/external-knowledge-api-documentation')} target='_blank'>
<RiBookOpenLine className='h-3 w-3 text-text-accent' />
<div className='body-xs-regular grow text-text-accent'>{t('dataset.externalAPIPanelDocumentation')}</div>
</a>

View File

@@ -1,8 +1,10 @@
import { RiBookOpenLine } from '@remixicon/react'
import { useTranslation } from 'react-i18next'
import { useDocLink } from '@/context/i18n'
const InfoPanel = () => {
const { t } = useTranslation()
const docLink = useDocLink()
return (
<div className='flex w-[360px] flex-col items-start pb-2 pr-8 pt-[108px]'>
@@ -16,12 +18,15 @@ const InfoPanel = () => {
</span>
<span className='system-sm-regular text-text-tertiary'>
{t('dataset.connectDatasetIntro.content.front')}
<a className='system-sm-regular ml-1 text-text-accent' href='https://docs.dify.ai/en/guides/knowledge-base/external-knowledge-api' target='_blank' rel="noopener noreferrer">
<a className='system-sm-regular ml-1 text-text-accent' href={docLink('/guides/knowledge-base/external-knowledge-api')} target='_blank' rel="noopener noreferrer">
{t('dataset.connectDatasetIntro.content.link')}
</a>
{t('dataset.connectDatasetIntro.content.end')}
</span>
<a className='system-sm-regular self-stretch text-text-accent' href='https://docs.dify.ai/en/guides/knowledge-base/connect-external-knowledge-base' target='_blank' rel="noopener noreferrer">
<a className='system-sm-regular self-stretch text-text-accent'
href={docLink('/guides/knowledge-base/connect-external-knowledge-base')}
target='_blank'
rel="noopener noreferrer">
{t('dataset.connectDatasetIntro.learnMore')}
</a>
</p>

View File

@@ -11,6 +11,7 @@ import InfoPanel from './InfoPanel'
import type { CreateKnowledgeBaseReq } from './declarations'
import Divider from '@/app/components/base/divider'
import Button from '@/app/components/base/button'
import { useDocLink } from '@/context/i18n'
type ExternalKnowledgeBaseCreateProps = {
onConnect: (formValue: CreateKnowledgeBaseReq) => void
@@ -19,6 +20,7 @@ type ExternalKnowledgeBaseCreateProps = {
const ExternalKnowledgeBaseCreate: React.FC<ExternalKnowledgeBaseCreateProps> = ({ onConnect, loading }) => {
const { t } = useTranslation()
const docLink = useDocLink()
const router = useRouter()
const [formData, setFormData] = useState<CreateKnowledgeBaseReq>({
name: '',
@@ -59,7 +61,7 @@ const ExternalKnowledgeBaseCreate: React.FC<ExternalKnowledgeBaseCreateProps> =
<span>{t('dataset.connectHelper.helper1')}</span>
<span className='system-sm-medium text-text-secondary'>{t('dataset.connectHelper.helper2')}</span>
<span>{t('dataset.connectHelper.helper3')}</span>
<a className='system-sm-regular self-stretch text-text-accent' href='https://docs.dify.ai/en/guides/knowledge-base/connect-external-knowledge-base' target='_blank' rel="noopener noreferrer">
<a className='system-sm-regular self-stretch text-text-accent' href={docLink('/guides/knowledge-base/connect-external-knowledge-base')} target='_blank' rel="noopener noreferrer">
{t('dataset.connectHelper.helper4')}
</a>
<span>{t('dataset.connectHelper.helper5')} </span>

View File

@@ -11,6 +11,7 @@ import EconomicalRetrievalMethodConfig from '@/app/components/datasets/common/ec
import Button from '@/app/components/base/button'
import { isReRankModelSelected } from '@/app/components/datasets/common/check-rerank-model'
import { useModelListAndDefaultModelAndCurrentProviderAndModel } from '@/app/components/header/account-setting/model-provider-page/hooks'
import { useDocLink } from '@/context/i18n'
type Props = {
indexMethod: string
@@ -29,6 +30,7 @@ const ModifyRetrievalModal: FC<Props> = ({
}) => {
const ref = useRef(null)
const { t } = useTranslation()
const docLink = useDocLink()
const [retrievalConfig, setRetrievalConfig] = useState(value)
// useClickAway(() => {
@@ -72,7 +74,7 @@ const ModifyRetrievalModal: FC<Props> = ({
<a
target='_blank'
rel='noopener noreferrer'
href='https://docs.dify.ai/guides/knowledge-base/create-knowledge-and-upload-documents#id-4-retrieval-settings'
href={docLink('/guides/knowledge-base/create-knowledge-and-upload-documents#id-4-retrieval-settings')}
className='text-text-accent'
>
{t('datasetSettings.form.retrievalSetting.learnMore')}

View File

@@ -32,6 +32,7 @@ import { ModelTypeEnum } from '@/app/components/header/account-setting/model-pro
import { fetchMembers } from '@/service/common'
import type { Member } from '@/models/common'
import AlertTriangle from '@/app/components/base/icons/src/vender/solid/alertsAndFeedback/AlertTriangle'
import { useDocLink } from '@/context/i18n'
const rowClass = 'flex'
const labelClass = `
@@ -46,6 +47,7 @@ const getKey = (pageIndex: number, previousPageData: DataSetListResponse) => {
const Form = () => {
const { t } = useTranslation()
const docLink = useDocLink()
const { notify } = useContext(ToastContext)
const { mutate } = useSWRConfig()
const { isCurrentWorkspaceDatasetOperator } = useAppContext()
@@ -308,7 +310,7 @@ const Form = () => {
<div>
<div className='system-sm-semibold text-text-secondary'>{t('datasetSettings.form.retrievalSetting.title')}</div>
<div className='body-xs-regular text-text-tertiary'>
<a target='_blank' rel='noopener noreferrer' href='https://docs.dify.ai/guides/knowledge-base/create-knowledge-and-upload-documents#id-4-retrieval-settings' className='text-text-accent'>{t('datasetSettings.form.retrievalSetting.learnMore')}</a>
<a target='_blank' rel='noopener noreferrer' href={docLink('/guides/knowledge-base/create-knowledge-and-upload-documents#id-4-retrieval-settings')} className='text-text-accent'>{t('datasetSettings.form.retrievalSetting.learnMore')}</a>
{t('datasetSettings.form.retrievalSetting.description')}
</div>
</div>

View File

@@ -23,7 +23,6 @@ import GithubStar from '../github-star'
import Support from './support'
import Compliance from './compliance'
import PremiumBadge from '@/app/components/base/premium-badge'
import { useGetDocLanguage } from '@/context/i18n'
import Avatar from '@/app/components/base/avatar'
import ThemeSwitcher from '@/app/components/base/theme-switcher'
import { logout } from '@/service/common'
@@ -33,6 +32,7 @@ import { useModalContext } from '@/context/modal-context'
import { IS_CLOUD_EDITION } from '@/config'
import cn from '@/utils/classnames'
import { useGlobalPublicStore } from '@/context/global-public-context'
import { useDocLink } from '@/context/i18n'
export default function AppSelector() {
const itemClassName = `
@@ -44,10 +44,10 @@ export default function AppSelector() {
const { systemFeatures } = useGlobalPublicStore()
const { t } = useTranslation()
const docLink = useDocLink()
const { userProfile, langeniusVersionInfo, isCurrentWorkspaceOwner } = useAppContext()
const { isEducationAccount } = useProviderContext()
const { setShowAccountSettingModal } = useModalContext()
const docLanguage = useGetDocLanguage()
const handleLogout = async () => {
await logout({
@@ -133,7 +133,7 @@ export default function AppSelector() {
className={cn(itemClassName, 'group justify-between',
'data-[active]:bg-state-base-hover',
)}
href={`https://docs.dify.ai/${docLanguage}/introduction`}
href={docLink('/introduction')}
target='_blank' rel='noopener noreferrer'>
<RiBookOpenLine className='size-4 shrink-0 text-text-tertiary' />
<div className='system-md-regular grow px-1 text-text-secondary'>{t('common.userProfile.helpCenter')}</div>

View File

@@ -1,6 +1,6 @@
import React, { useMemo } from 'react'
import { useTranslation } from 'react-i18next'
import { useContext } from 'use-context-selector'
import { useDocLink } from '@/context/i18n'
import { useBoolean } from 'ahooks'
import {
RiAddLine,
@@ -20,8 +20,6 @@ import {
useInvalidateEndpointList,
} from '@/service/use-endpoints'
import type { PluginDetail } from '@/app/components/plugins/types'
import { LanguagesSupported } from '@/i18n/language'
import I18n from '@/context/i18n'
import cn from '@/utils/classnames'
type Props = {
@@ -29,7 +27,7 @@ type Props = {
}
const EndpointList = ({ detail }: Props) => {
const { t } = useTranslation()
const { locale } = useContext(I18n)
const docLink = useDocLink()
const pluginUniqueID = detail.plugin_unique_identifier
const declaration = detail.declaration.endpoint
const showTopBorder = detail.declaration.tool
@@ -79,7 +77,7 @@ const EndpointList = ({ detail }: Props) => {
</div>
<div className='system-xs-regular text-text-tertiary'>{t('plugin.detailPanel.endpointsTip')}</div>
<a
href={`https://docs.dify.ai/${locale === LanguagesSupported[1] ? 'v/zh-hans/' : ''}plugins/schema-definition/endpoint`}
href={docLink('/plugins/schema-definition/endpoint')}
target='_blank'
rel='noopener noreferrer'
>

View File

@@ -14,6 +14,7 @@ import EditCustomToolModal from '@/app/components/tools/edit-custom-collection-m
import { createCustomCollection } from '@/service/tools'
import Toast from '@/app/components/base/toast'
import { useAppContext } from '@/context/app-context'
import { useDocLink } from '@/context/i18n'
type Props = {
onRefreshData: () => void
@@ -25,10 +26,11 @@ const Contribute = ({ onRefreshData }: Props) => {
const language = getLanguage(locale)
const { isCurrentWorkspaceManager } = useAppContext()
const docLink = useDocLink()
const linkUrl = useMemo(() => {
if (language.startsWith('zh_'))
return 'https://docs.dify.ai/zh-hans/guides/tools#ru-he-chuang-jian-zi-ding-yi-gong-ju'
return 'https://docs.dify.ai/en/guides/tools#how-to-create-custom-tools'
return docLink('/guides/tools#how-to-create-custom-tools', {
'zh-Hans': '/guides/tools#ru-he-chuang-jian-zi-ding-yi-gong-ju',
})
}, [language])
const [isShowEditCollectionToolModal, setIsShowEditCustomCollectionModal] = useState(false)

View File

@@ -19,9 +19,7 @@ import { useWorkflowStore } from '../../../store'
import { useRenderI18nObject } from '@/hooks/use-i18n'
import type { NodeOutPutVar } from '../../../types'
import type { Node } from 'reactflow'
import { useContext } from 'use-context-selector'
import I18n from '@/context/i18n'
import { LanguagesSupported } from '@/i18n/language'
import { useDocLink } from '@/context/i18n'
export type Strategy = {
agent_strategy_provider_name: string
@@ -52,7 +50,7 @@ type CustomField = ToolSelectorSchema | MultipleToolSelectorSchema
export const AgentStrategy = memo((props: AgentStrategyProps) => {
const { strategy, onStrategyChange, formSchema, formValue, onFormValueChange, nodeOutputVars, availableNodes, nodeId } = props
const { t } = useTranslation()
const { locale } = useContext(I18n)
const docLink = useDocLink()
const defaultModel = useDefaultModel(ModelTypeEnum.textGeneration)
const renderI18nObject = useRenderI18nObject()
const workflowStore = useWorkflowStore()
@@ -223,11 +221,10 @@ export const AgentStrategy = memo((props: AgentStrategyProps) => {
title={t('workflow.nodes.agent.strategy.configureTip')}
description={<div className='text-xs text-text-tertiary'>
{t('workflow.nodes.agent.strategy.configureTipDesc')} <br />
<Link href={
locale === LanguagesSupported[1]
? 'https://docs.dify.ai/zh-hans/guides/workflow/node/agent#xuan-ze-agent-ce-le'
: 'https://docs.dify.ai/en/guides/workflow/node/agent#select-an-agent-strategy'
} className='text-text-accent-secondary' target='_blank'>
<Link href={docLink('/guides/workflow/node/agent#select-an-agent-strategy', {
'zh-Hans': '/guides/workflow/node/agent#xuan-ze-agent-ce-le',
})}
className='text-text-accent-secondary' target='_blank'>
{t('workflow.nodes.agent.learnMore')}
</Link>
</div>}

View File

@@ -5,6 +5,7 @@ import Input from '@/app/components/base/input'
import { VarType } from '@/app/components/workflow/types'
import { CodeLanguage } from '@/app/components/workflow/nodes/code/types'
import CodeEditor from '@/app/components/workflow/nodes/_base/components/editor/code-editor'
import { useDocLink } from '@/context/i18n'
type DefaultValueProps = {
forms: DefaultValueForm[]
@@ -15,6 +16,7 @@ const DefaultValue = ({
onFormChange,
}: DefaultValueProps) => {
const { t } = useTranslation()
const docLink = useDocLink()
const getFormChangeHandler = useCallback(({ key, type }: DefaultValueForm) => {
return (payload: any) => {
let value
@@ -34,7 +36,7 @@ const DefaultValue = ({
{t('workflow.nodes.common.errorHandle.defaultValue.desc')}
&nbsp;
<a
href='https://docs.dify.ai/en/guides/workflow/error-handling/README'
href={docLink('/guides/workflow/error-handling/README')}
target='_blank'
className='text-text-accent'
>

View File

@@ -1,8 +1,10 @@
import { RiMindMap } from '@remixicon/react'
import { useTranslation } from 'react-i18next'
import { useDocLink } from '@/context/i18n'
const FailBranchCard = () => {
const { t } = useTranslation()
const docLink = useDocLink()
return (
<div className='px-4 pt-2'>
@@ -17,7 +19,7 @@ const FailBranchCard = () => {
{t('workflow.nodes.common.errorHandle.failBranch.customizeTip')}
&nbsp;
<a
href='https://docs.dify.ai/guides/workflow/error-handling'
href={docLink('/guides/workflow/error-handling/error-type')}
target='_blank'
className='text-text-accent'
>

View File

@@ -2,12 +2,10 @@
import type { FC } from 'react'
import React from 'react'
import { useTranslation } from 'react-i18next'
import { useContext } from 'use-context-selector'
import VarReferenceVars from './var-reference-vars'
import type { NodeOutPutVar, ValueSelector, Var } from '@/app/components/workflow/types'
import ListEmpty from '@/app/components/base/list-empty'
import { LanguagesSupported } from '@/i18n/language'
import I18n from '@/context/i18n'
import { useDocLink } from '@/context/i18n'
type Props = {
vars: NodeOutPutVar[]
@@ -24,7 +22,7 @@ const VarReferencePopup: FC<Props> = ({
isSupportFileVar = true,
}) => {
const { t } = useTranslation()
const { locale } = useContext(I18n)
const docLink = useDocLink()
// max-h-[300px] overflow-y-auto todo: use portal to handle long list
return (
<div className='space-y-1 rounded-lg border border-components-panel-border bg-components-panel-bg p-1 shadow-lg' style={{
@@ -46,8 +44,10 @@ const VarReferencePopup: FC<Props> = ({
description={<div className='system-xs-regular text-text-tertiary'>
{t('workflow.variableReference.assignedVarsDescription')}
<a target='_blank' rel='noopener noreferrer'
className='text-text-accent-secondary'
href={locale !== LanguagesSupported[1] ? 'https://docs.dify.ai/guides/workflow/variables#conversation-variables' : `https://docs.dify.ai/${locale.toLowerCase()}/guides/workflow/variables#hui-hua-bian-liang`}>{t('workflow.variableReference.conversationVars')}</a>
className='text-text-accent-secondary'
href={docLink('/guides/workflow/variables#conversation-variables', { 'zh-Hans': '/guides/workflow/variables#hui-hua-bian-liang' })}>
{t('workflow.variableReference.conversationVars')}
</a>
</div>}
/>
))

View File

@@ -1,14 +1,12 @@
import { useMemo } from 'react'
import { useGetLanguage } from '@/context/i18n'
import { useDocLink, useGetLanguage } from '@/context/i18n'
import { BlockEnum } from '@/app/components/workflow/types'
export const useNodeHelpLink = (nodeType: BlockEnum) => {
const language = useGetLanguage()
const docLink = useDocLink()
const prefixLink = useMemo(() => {
if (language === 'zh_Hans')
return 'https://docs.dify.ai/zh-hans/guides/workflow/node/'
return 'https://docs.dify.ai/en/guides/workflow/node/'
return docLink('/guides/workflow/node/')
}, [language])
const linkMap = useMemo(() => {
if (language === 'zh_Hans') {

View File

@@ -21,8 +21,8 @@ import { MittProvider, VisualEditorContextProvider, useMittContext } from './vis
import ErrorMessage from './error-message'
import { useVisualEditorStore } from './visual-editor/store'
import Toast from '@/app/components/base/toast'
import { useGetDocLanguage } from '@/context/i18n'
import { JSON_SCHEMA_MAX_DEPTH } from '@/config'
import { useDocLink } from '@/context/i18n'
type JsonSchemaConfigProps = {
defaultSchema?: SchemaRoot
@@ -53,7 +53,7 @@ const JsonSchemaConfig: FC<JsonSchemaConfigProps> = ({
onClose,
}) => {
const { t } = useTranslation()
const docLanguage = useGetDocLanguage()
const docLink = useDocLink()
const [currentTab, setCurrentTab] = useState(SchemaView.VisualEditor)
const [jsonSchema, setJsonSchema] = useState(defaultSchema || DEFAULT_SCHEMA)
const [json, setJson] = useState(JSON.stringify(jsonSchema, null, 2))
@@ -252,7 +252,7 @@ const JsonSchemaConfig: FC<JsonSchemaConfigProps> = ({
<div className='flex items-center gap-x-2 p-6 pt-5'>
<a
className='flex grow items-center gap-x-1 text-text-accent'
href={`https://docs.dify.ai/${docLanguage}/guides/workflow/structured-outputs`}
href={docLink('/guides/workflow/structured-outputs')}
target='_blank'
rel='noopener noreferrer'
>

View File

@@ -3,7 +3,6 @@ import {
useCallback,
useState,
} from 'react'
import { useContext } from 'use-context-selector'
import {
useStoreApi,
} from 'reactflow'
@@ -22,13 +21,12 @@ import type {
import { findUsedVarNodes, updateNodeVars } from '@/app/components/workflow/nodes/_base/components/variable/utils'
import { useNodesSyncDraft } from '@/app/components/workflow/hooks/use-nodes-sync-draft'
import { BlockEnum } from '@/app/components/workflow/types'
import I18n from '@/context/i18n'
import { LanguagesSupported } from '@/i18n/language'
import { useDocLink } from '@/context/i18n'
import cn from '@/utils/classnames'
const ChatVariablePanel = () => {
const { t } = useTranslation()
const { locale } = useContext(I18n)
const docLink = useDocLink()
const store = useStoreApi()
const setShowChatVariablePanel = useStore(s => s.setShowChatVariablePanel)
const varList = useStore(s => s.conversationVariables) as ConversationVariable[]
@@ -139,8 +137,11 @@ const ChatVariablePanel = () => {
<div className='system-2xs-medium-uppercase inline-block rounded-[5px] border border-divider-deep px-[5px] py-[3px] text-text-tertiary'>TIPS</div>
<div className='system-sm-regular mb-4 mt-1 text-text-secondary'>
{t('workflow.chatVariable.panelDescription')}
<a target='_blank' rel='noopener noreferrer' className='text-text-accent' href={locale !== LanguagesSupported[1] ? 'https://docs.dify.ai/guides/workflow/variables#conversation-variables' : `https://docs.dify.ai/${locale.toLowerCase()}/guides/workflow/variables#hui-hua-bian-liang`}>{t('workflow.chatVariable.docLink')}</a>
</div>
<a target='_blank' rel='noopener noreferrer' className='text-text-accent'
href={docLink('/guides/workflow/variables#conversation-variables', { 'zh-Hans': '/guides/workflow/variables#hui-hua-bian-liang' })}>
{t('workflow.chatVariable.docLink')}
</a>
</div>
<div className='flex items-center gap-2'>
<div className='radius-lg flex flex-col border border-workflow-block-border bg-workflow-block-bg p-3 pb-4 shadow-md'>
<BubbleX className='mb-1 h-4 w-4 shrink-0 text-util-colors-teal-teal-700' />

View File

@@ -28,6 +28,7 @@ import type {
} from '@/types/workflow'
import ErrorHandleTip from '@/app/components/workflow/nodes/_base/components/error-handle/error-handle-tip'
import { hasRetryNode } from '@/app/components/workflow/utils'
import { useDocLink } from '@/context/i18n'
type Props = {
className?: string
@@ -65,6 +66,7 @@ const NodePanel: FC<Props> = ({
doSetCollapseState(state)
}, [hideProcessDetail])
const { t } = useTranslation()
const docLink = useDocLink()
const getTime = (time: number) => {
if (time < 1)
@@ -195,7 +197,7 @@ const NodePanel: FC<Props> = ({
<StatusContainer status='stopped'>
{nodeInfo.error}
<a
href='https://docs.dify.ai/guides/workflow/error-handling/error-type'
href={docLink('/guides/workflow/error-handling/error-type')}
target='_blank'
className='text-text-accent'
>

View File

@@ -4,6 +4,7 @@ import { useTranslation } from 'react-i18next'
import cn from '@/utils/classnames'
import Indicator from '@/app/components/header/indicator'
import StatusContainer from '@/app/components/workflow/run/status-container'
import { useDocLink } from '@/context/i18n'
type ResultProps = {
status: string
@@ -21,6 +22,7 @@ const StatusPanel: FC<ResultProps> = ({
exceptionCounts,
}) => {
const { t } = useTranslation()
const docLink = useDocLink()
return (
<StatusContainer status={status}>
@@ -134,7 +136,7 @@ const StatusPanel: FC<ResultProps> = ({
<div className='system-xs-medium text-text-warning'>
{error}
<a
href='https://docs.dify.ai/guides/workflow/error-handling/error-type'
href={docLink('/guides/workflow/error-handling/error-type')}
target='_blank'
className='text-text-accent'
>

View File

@@ -1,7 +1,6 @@
'use client'
import {
useMemo,
useState,
} from 'react'
import { useTranslation } from 'react-i18next'
@@ -23,13 +22,11 @@ import {
import { useProviderContext } from '@/context/provider-context'
import { useToastContext } from '@/app/components/base/toast'
import { EDUCATION_VERIFYING_LOCALSTORAGE_ITEM } from '@/app/education-apply/constants'
import { getLocaleOnClient } from '@/i18n'
import { noop } from 'lodash-es'
import DifyLogo from '../components/base/logo/dify-logo'
import { useDocLink } from '@/context/i18n'
const EducationApplyAge = () => {
const { t } = useTranslation()
const locale = getLocaleOnClient()
const [schoolName, setSchoolName] = useState('')
const [role, setRole] = useState('Student')
const [ageChecked, setAgeChecked] = useState(false)
@@ -43,14 +40,7 @@ const EducationApplyAge = () => {
const updateEducationStatus = useInvalidateEducationStatus()
const { notify } = useToastContext()
const router = useRouter()
const docLink = useMemo(() => {
if (locale === 'zh-Hans')
return 'https://docs.dify.ai/zh-hans/getting-started/dify-for-education'
if (locale === 'ja-JP')
return 'https://docs.dify.ai/ja-jp/getting-started/dify-for-education'
return 'https://docs.dify.ai/getting-started/dify-for-education'
}, [locale])
const docLink = useDocLink()
const handleModalConfirm = () => {
setShowModal(undefined)
@@ -167,7 +157,7 @@ const EducationApplyAge = () => {
<div className='mb-4 mt-5 h-[1px] bg-gradient-to-r from-[rgba(16,24,40,0.08)]'></div>
<a
className='system-xs-regular flex items-center text-text-accent'
href={docLink}
href={docLink('/getting-started/dify-for-education')}
target='_blank'
>
{t('education.learn')}

View File

@@ -1,11 +1,11 @@
import React, { useEffect, useMemo, useRef, useState } from 'react'
import React, { useEffect, useRef, useState } from 'react'
import { createPortal } from 'react-dom'
import { useTranslation } from 'react-i18next'
import {
RiExternalLinkLine,
} from '@remixicon/react'
import Button from '@/app/components/base/button'
import { getLocaleOnClient } from '@/i18n'
import { useDocLink } from '@/context/i18n'
export type IConfirm = {
className?: string
@@ -30,20 +30,13 @@ function Confirm({
email,
}: IConfirm) {
const { t } = useTranslation()
const locale = getLocaleOnClient()
const docLink = useDocLink()
const dialogRef = useRef<HTMLDivElement>(null)
const [isVisible, setIsVisible] = useState(isShow)
const docLink = useMemo(() => {
if (locale === 'zh-Hans')
return 'https://docs.dify.ai/zh-hans/getting-started/dify-for-education'
if (locale === 'ja-JP')
return 'https://docs.dify.ai/ja-jp/getting-started/dify-for-education'
return 'https://docs.dify.ai/getting-started/dify-for-education'
}, [locale])
const eduDocLink = docLink('/getting-started/dify-for-education')
const handleClick = () => {
window.open(docLink, '_blank', 'noopener,noreferrer')
window.open(eduDocLink, '_blank', 'noopener,noreferrer')
}
useEffect(() => {
@@ -106,7 +99,7 @@ function Confirm({
<div className='flex items-center gap-1'>
{showLink && (
<>
<a onClick={handleClick} href={docLink} target='_blank' className='system-xs-regular cursor-pointer text-text-accent'>{t('education.learn')}</a>
<a onClick={handleClick} href={eduDocLink} target='_blank' className='system-xs-regular cursor-pointer text-text-accent'>{t('education.learn')}</a>
<RiExternalLinkLine className='h-3 w-3 text-text-accent' />
</>
)}

View File

@@ -17,6 +17,7 @@ import Button from '@/app/components/base/button'
import { fetchInitValidateStatus, fetchSetupStatus, setup } from '@/service/common'
import type { InitValidateStatusResponse, SetupStatusResponse } from '@/models/common'
import useDocumentTitle from '@/hooks/use-document-title'
import { useDocLink } from '@/context/i18n'
const validPassword = /^(?=.*[a-zA-Z])(?=.*\d).{8,}$/
@@ -36,6 +37,7 @@ type AccountFormValues = z.infer<typeof accountFormSchema>
const InstallForm = () => {
useDocumentTitle('')
const { t } = useTranslation()
const docLink = useDocLink()
const router = useRouter()
const [showPassword, setShowPassword] = React.useState(false)
const [loading, setLoading] = React.useState(true)
@@ -174,7 +176,7 @@ const InstallForm = () => {
<Link
className='text-text-accent'
target='_blank' rel='noopener noreferrer'
href={'https://docs.dify.ai/user-agreement/open-source'}
href={docLink('/policies/open-source')}
>{t('login.license.link')}</Link>
</div>
</div>

View File

@@ -1,5 +1,6 @@
'use client'
import { useTranslation } from 'react-i18next'
import { useDocLink } from '@/context/i18n'
import { useCallback, useState } from 'react'
import Link from 'next/link'
import { useContext } from 'use-context-selector'
@@ -18,10 +19,11 @@ import Toast from '@/app/components/base/toast'
export default function InviteSettingsPage() {
const { t } = useTranslation()
const docLink = useDocLink()
const router = useRouter()
const searchParams = useSearchParams()
const token = decodeURIComponent(searchParams.get('invite_token') as string)
const { locale, setLocaleOnClient } = useContext(I18n)
const { setLocaleOnClient } = useContext(I18n)
const [name, setName] = useState('')
const [language, setLanguage] = useState(LanguagesSupported[0])
const [timezone, setTimezone] = useState(Intl.DateTimeFormat().resolvedOptions().timeZone || 'America/Los_Angeles')
@@ -147,7 +149,7 @@ export default function InviteSettingsPage() {
<Link
className='system-xs-medium text-text-accent-secondary'
target='_blank' rel='noopener noreferrer'
href={`https://docs.dify.ai/${language !== LanguagesSupported[1] ? 'user-agreement' : `v/${locale.toLowerCase()}/policies`}/open-source`}
href={docLink('/policies/open-source')}
>{t('login.license.link')}</Link>
</div>
</div>

View File

@@ -12,6 +12,7 @@ import { timezones } from '@/utils/timezone'
import { LanguagesSupported, languages } from '@/i18n/language'
import { oneMoreStep } from '@/service/common'
import Toast from '@/app/components/base/toast'
import { useDocLink } from '@/context/i18n'
type IState = {
formState: 'processing' | 'error' | 'success' | 'initial'
@@ -51,6 +52,7 @@ const reducer: Reducer<IState, IAction> = (state: IState, action: IAction) => {
const OneMoreStep = () => {
const { t } = useTranslation()
const docLink = useDocLink()
const router = useRouter()
const searchParams = useSearchParams()
@@ -164,7 +166,7 @@ const OneMoreStep = () => {
<Link
className='system-xs-medium text-text-accent-secondary'
target='_blank' rel='noopener noreferrer'
href={'https://docs.dify.ai/en/policies/agreement/README'}
href={docLink('/policies/agreement/README')}
>{t('login.license.link')}</Link>
</div>
</div>

View File

@@ -35,4 +35,17 @@ export const useGetPricingPageLanguage = () => {
return getPricingPageLanguage(locale)
}
const defaultDocBaseUrl = 'https://docs.dify.ai'
export const useDocLink = (baseUrl?: string): ((path?: string, pathMap?: { [index: string]: string }) => string) => {
let baseDocUrl = baseUrl || defaultDocBaseUrl
baseDocUrl = (baseDocUrl.endsWith('/')) ? baseDocUrl.slice(0, -1) : baseDocUrl
const { locale } = useI18N()
const docLanguage = getDocLanguage(locale)
return (path?: string, pathMap?: { [index: string]: string }): string => {
const pathUrl = path || ''
let targetPath = (pathMap) ? pathMap[locale] || pathUrl : pathUrl
targetPath = (targetPath.startsWith('/')) ? targetPath.slice(0, -1) : targetPath
return `${baseDocUrl}/${docLanguage}/${targetPath}`
}
}
export default I18NContext