| import DatasetDetailContext from '@/context/dataset-detail' | import DatasetDetailContext from '@/context/dataset-detail' | ||||
| import { DataSourceType } from '@/models/datasets' | import { DataSourceType } from '@/models/datasets' | ||||
| import useBreakpoints, { MediaType } from '@/hooks/use-breakpoints' | import useBreakpoints, { MediaType } from '@/hooks/use-breakpoints' | ||||
| import { LanguagesSupported } from '@/i18n/language' | |||||
| import { useStore } from '@/app/components/app/store' | import { useStore } from '@/app/components/app/store' | ||||
| import { getLocaleOnClient } from '@/i18n' | |||||
| import { useDocLink } from '@/context/i18n' | |||||
| import { useAppContext } from '@/context/app-context' | import { useAppContext } from '@/context/app-context' | ||||
| import Tooltip from '@/app/components/base/tooltip' | import Tooltip from '@/app/components/base/tooltip' | ||||
| import LinkedAppsPanel from '@/app/components/base/linked-apps-panel' | import LinkedAppsPanel from '@/app/components/base/linked-apps-panel' | ||||
| } | } | ||||
| const ExtraInfo = ({ isMobile, relatedApps, expand }: IExtraInfoProps) => { | const ExtraInfo = ({ isMobile, relatedApps, expand }: IExtraInfoProps) => { | ||||
| const locale = getLocaleOnClient() | |||||
| const [isShowTips, { toggle: toggleTips, set: setShowTips }] = useBoolean(!isMobile) | const [isShowTips, { toggle: toggleTips, set: setShowTips }] = useBoolean(!isMobile) | ||||
| const { t } = useTranslation() | const { t } = useTranslation() | ||||
| const docLink = useDocLink() | |||||
| const hasRelatedApps = relatedApps?.data && relatedApps?.data?.length > 0 | const hasRelatedApps = relatedApps?.data && relatedApps?.data?.length > 0 | ||||
| const relatedAppsTotal = relatedApps?.data?.length || 0 | const relatedAppsTotal = relatedApps?.data?.length || 0 | ||||
| <div className='my-2 text-xs text-text-tertiary'>{t('common.datasetMenus.emptyTip')}</div> | <div className='my-2 text-xs text-text-tertiary'>{t('common.datasetMenus.emptyTip')}</div> | ||||
| <a | <a | ||||
| className='mt-2 inline-flex cursor-pointer items-center text-xs text-text-accent' | 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' | target='_blank' rel='noopener noreferrer' | ||||
| > | > | ||||
| <RiBookOpenLine className='mr-1 text-text-accent' /> | <RiBookOpenLine className='mr-1 text-text-accent' /> |
| 'use client' | 'use client' | ||||
| import type { FC } from 'react' | import type { FC } from 'react' | ||||
| import React from 'react' | import React from 'react' | ||||
| import { useContext } from 'use-context-selector' | |||||
| import { useTranslation } from 'react-i18next' | import { useTranslation } from 'react-i18next' | ||||
| import OperationBtn from '@/app/components/app/configuration/base/operation-btn' | import OperationBtn from '@/app/components/app/configuration/base/operation-btn' | ||||
| import Panel from '@/app/components/app/configuration/base/feature-panel' | import Panel from '@/app/components/app/configuration/base/feature-panel' | ||||
| import { MessageClockCircle } from '@/app/components/base/icons/src/vender/solid/general' | 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 = { | type Props = { | ||||
| showWarning: boolean | showWarning: boolean | ||||
| onShowEditModal, | onShowEditModal, | ||||
| }) => { | }) => { | ||||
| const { t } = useTranslation() | const { t } = useTranslation() | ||||
| const { locale } = useContext(I18n) | |||||
| const docLink = useDocLink() | |||||
| return ( | return ( | ||||
| <Panel | <Panel | ||||
| {showWarning && ( | {showWarning && ( | ||||
| <div className='flex justify-between rounded-b-xl bg-background-section-burn px-3 py-2 text-xs text-text-secondary'> | <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')} | <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' | target='_blank' rel='noopener noreferrer' | ||||
| className='text-[#155EEF]'>{t('appDebug.feature.conversationHistory.learnMore')} | className='text-[#155EEF]'>{t('appDebug.feature.conversationHistory.learnMore')} | ||||
| </a> | </a> |
| import { ModelTypeEnum } from '@/app/components/header/account-setting/model-provider-page/declarations' | import { ModelTypeEnum } from '@/app/components/header/account-setting/model-provider-page/declarations' | ||||
| import { fetchMembers } from '@/service/common' | import { fetchMembers } from '@/service/common' | ||||
| import type { Member } from '@/models/common' | import type { Member } from '@/models/common' | ||||
| import { useDocLink } from '@/context/i18n' | |||||
| type SettingsModalProps = { | type SettingsModalProps = { | ||||
| currentDataset: DataSet | currentDataset: DataSet | ||||
| currentModel: isRerankDefaultModelValid, | currentModel: isRerankDefaultModelValid, | ||||
| } = useModelListAndDefaultModelAndCurrentProviderAndModel(ModelTypeEnum.rerank) | } = useModelListAndDefaultModelAndCurrentProviderAndModel(ModelTypeEnum.rerank) | ||||
| const { t } = useTranslation() | const { t } = useTranslation() | ||||
| const docLink = useDocLink() | |||||
| const { notify } = useToastContext() | const { notify } = useToastContext() | ||||
| const ref = useRef(null) | const ref = useRef(null) | ||||
| const isExternal = currentDataset.provider === 'external' | const isExternal = currentDataset.provider === 'external' | ||||
| <div> | <div> | ||||
| <div className='system-sm-semibold text-text-secondary'>{t('datasetSettings.form.retrievalSetting.title')}</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'> | <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')} | {t('datasetSettings.form.retrievalSetting.description')} | ||||
| </div> | </div> | ||||
| </div> | </div> |
| import type { FC } from 'react' | import type { FC } from 'react' | ||||
| import React from 'react' | import React from 'react' | ||||
| import { useTranslation } from 'react-i18next' | 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 = { | type Props = { | ||||
| onReturnToSimpleMode: () => void | onReturnToSimpleMode: () => void | ||||
| } | } | ||||
| onReturnToSimpleMode, | onReturnToSimpleMode, | ||||
| }) => { | }) => { | ||||
| const { t } = useTranslation() | const { t } = useTranslation() | ||||
| const { locale } = useContext(I18n) | |||||
| const docLink = useDocLink() | |||||
| const [show, setShow] = React.useState(true) | const [show, setShow] = React.useState(true) | ||||
| if (!show) | if (!show) | ||||
| return null | return null | ||||
| <span className='text-gray-700'>{t('appDebug.promptMode.advancedWarning.description')}</span> | <span className='text-gray-700'>{t('appDebug.promptMode.advancedWarning.description')}</span> | ||||
| <a | <a | ||||
| className='font-medium text-[#155EEF]' | 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' | target='_blank' rel='noopener noreferrer' | ||||
| > | > | ||||
| {t('appDebug.promptMode.advancedWarning.learnMore')} | {t('appDebug.promptMode.advancedWarning.learnMore')} |
| import { getRedirection } from '@/utils/app-redirection' | import { getRedirection } from '@/utils/app-redirection' | ||||
| import FullScreenModal from '@/app/components/base/fullscreen-modal' | import FullScreenModal from '@/app/components/base/fullscreen-modal' | ||||
| import useTheme from '@/hooks/use-theme' | import useTheme from '@/hooks/use-theme' | ||||
| import { useDocLink } from '@/context/i18n' | |||||
| type CreateAppProps = { | type CreateAppProps = { | ||||
| onSuccess: () => void | onSuccess: () => void | ||||
| function AppPreview({ mode }: { mode: AppMode }) { | function AppPreview({ mode }: { mode: AppMode }) { | ||||
| const { t } = useTranslation() | const { t } = useTranslation() | ||||
| const docLink = useDocLink() | |||||
| const modeToPreviewInfoMap = { | const modeToPreviewInfoMap = { | ||||
| 'chat': { | 'chat': { | ||||
| title: t('app.types.chatbot'), | title: t('app.types.chatbot'), | ||||
| description: t('app.newApp.chatbotUserDescription'), | description: t('app.newApp.chatbotUserDescription'), | ||||
| link: 'https://docs.dify.ai/guides/application-orchestrate/readme', | |||||
| link: docLink('/guides/application-orchestrate/chatbot-application'), | |||||
| }, | }, | ||||
| 'advanced-chat': { | 'advanced-chat': { | ||||
| title: t('app.types.advanced'), | title: t('app.types.advanced'), | ||||
| description: t('app.newApp.advancedUserDescription'), | description: t('app.newApp.advancedUserDescription'), | ||||
| link: 'https://docs.dify.ai/en/guides/workflow/README', | |||||
| link: docLink('/guides/workflow/readme'), | |||||
| }, | }, | ||||
| 'agent-chat': { | 'agent-chat': { | ||||
| title: t('app.types.agent'), | title: t('app.types.agent'), | ||||
| description: t('app.newApp.agentUserDescription'), | description: t('app.newApp.agentUserDescription'), | ||||
| link: 'https://docs.dify.ai/en/guides/application-orchestrate/agent', | |||||
| link: docLink('/guides/application-orchestrate/agent'), | |||||
| }, | }, | ||||
| 'completion': { | 'completion': { | ||||
| title: t('app.newApp.completeApp'), | title: t('app.newApp.completeApp'), | ||||
| description: t('app.newApp.completionUserDescription'), | description: t('app.newApp.completionUserDescription'), | ||||
| link: null, | |||||
| link: docLink('/guides/application-orchestrate/text-generator', | |||||
| { 'zh-Hans': '/guides/application-orchestrate/readme' }), | |||||
| }, | }, | ||||
| 'workflow': { | 'workflow': { | ||||
| title: t('app.types.workflow'), | title: t('app.types.workflow'), | ||||
| description: t('app.newApp.workflowUserDescription'), | description: t('app.newApp.workflowUserDescription'), | ||||
| link: 'https://docs.dify.ai/en/guides/workflow/README', | |||||
| link: docLink('/guides/workflow/readme'), | |||||
| }, | }, | ||||
| } | } | ||||
| const previewInfo = modeToPreviewInfoMap[mode] | const previewInfo = modeToPreviewInfoMap[mode] |
| import React from 'react' | import React from 'react' | ||||
| import { ArrowTopRightOnSquareIcon } from '@heroicons/react/24/outline' | import { ArrowTopRightOnSquareIcon } from '@heroicons/react/24/outline' | ||||
| import { useTranslation } from 'react-i18next' | import { useTranslation } from 'react-i18next' | ||||
| import { useContext } from 'use-context-selector' | |||||
| import { useDocLink } from '@/context/i18n' | |||||
| import type { AppMode } from '@/types/app' | import type { AppMode } from '@/types/app' | ||||
| import I18n from '@/context/i18n' | |||||
| 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 { LanguagesSupported } from '@/i18n/language' | |||||
| type IShareLinkProps = { | type IShareLinkProps = { | ||||
| isShow: boolean | isShow: boolean | ||||
| mode, | mode, | ||||
| }) => { | }) => { | ||||
| const { t } = useTranslation() | const { t } = useTranslation() | ||||
| const { locale } = useContext(I18n) | |||||
| const docLink = useDocLink() | |||||
| const isChatApp = mode === 'chat' || mode === 'advanced-chat' | const isChatApp = mode === 'chat' || mode === 'advanced-chat' | ||||
| return <Modal | return <Modal | ||||
| className='mt-2' | className='mt-2' | ||||
| onClick={() => | onClick={() => | ||||
| window.open( | 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', | '_blank', | ||||
| ) | ) | ||||
| } | } |
| import { RiArrowRightSLine, RiCloseLine } from '@remixicon/react' | import { RiArrowRightSLine, RiCloseLine } from '@remixicon/react' | ||||
| import Link from 'next/link' | import Link from 'next/link' | ||||
| import { Trans, useTranslation } from 'react-i18next' | import { Trans, useTranslation } from 'react-i18next' | ||||
| import { useContext } from 'use-context-selector' | |||||
| import { SparklesSoft } from '@/app/components/base/icons/src/public/common' | import { SparklesSoft } from '@/app/components/base/icons/src/public/common' | ||||
| import Modal from '@/app/components/base/modal' | import Modal from '@/app/components/base/modal' | ||||
| import ActionButton from '@/app/components/base/action-button' | import ActionButton from '@/app/components/base/action-button' | ||||
| import type { AppDetailResponse } from '@/models/app' | import type { AppDetailResponse } from '@/models/app' | ||||
| import type { AppIconType, AppSSO, Language } from '@/types/app' | import type { AppIconType, AppSSO, Language } from '@/types/app' | ||||
| import { useToastContext } from '@/app/components/base/toast' | 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 Tooltip from '@/app/components/base/tooltip' | ||||
| import { useProviderContext } from '@/context/provider-context' | import { useProviderContext } from '@/context/provider-context' | ||||
| import { useModalContext } from '@/context/modal-context' | import { useModalContext } from '@/context/modal-context' | ||||
| import type { AppIconSelection } from '@/app/components/base/app-icon-picker' | import type { AppIconSelection } from '@/app/components/base/app-icon-picker' | ||||
| import AppIconPicker 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 cn from '@/utils/classnames' | ||||
| import { useDocLink } from '@/context/i18n' | |||||
| export type ISettingsModalProps = { | export type ISettingsModalProps = { | ||||
| isChat: boolean | isChat: boolean | ||||
| const [language, setLanguage] = useState(default_language) | const [language, setLanguage] = useState(default_language) | ||||
| const [saveLoading, setSaveLoading] = useState(false) | const [saveLoading, setSaveLoading] = useState(false) | ||||
| const { t } = useTranslation() | const { t } = useTranslation() | ||||
| const { locale } = useContext(I18n) | |||||
| const docLink = useDocLink() | |||||
| const [showAppIconPicker, setShowAppIconPicker] = useState(false) | const [showAppIconPicker, setShowAppIconPicker] = useState(false) | ||||
| const [appIcon, setAppIcon] = useState<AppIconSelection>( | const [appIcon, setAppIcon] = useState<AppIconSelection>( | ||||
| </div> | </div> | ||||
| <div className='system-xs-regular mt-0.5 text-text-tertiary'> | <div className='system-xs-regular mt-0.5 text-text-tertiary'> | ||||
| <span>{t(`${prefixSettings}.modalTip`)}</span> | <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> | ||||
| </div> | </div> | ||||
| {/* form body */} | {/* form body */} |
| import React from 'react' | import React from 'react' | ||||
| import { useTranslation } from 'react-i18next' | import { useTranslation } from 'react-i18next' | ||||
| import { useContext } from 'use-context-selector' | |||||
| import { RiCloseLine, RiInformation2Fill } from '@remixicon/react' | import { RiCloseLine, RiInformation2Fill } from '@remixicon/react' | ||||
| import DialogWrapper from '@/app/components/base/features/new-feature-panel/dialog-wrapper' | import DialogWrapper from '@/app/components/base/features/new-feature-panel/dialog-wrapper' | ||||
| import { useDefaultModel } from '@/app/components/header/account-setting/model-provider-page/hooks' | import { useDefaultModel } from '@/app/components/header/account-setting/model-provider-page/hooks' | ||||
| import AnnotationReply from '@/app/components/base/features/new-feature-panel/annotation-reply' | import AnnotationReply from '@/app/components/base/features/new-feature-panel/annotation-reply' | ||||
| import type { PromptVariable } from '@/models/debug' | import type { PromptVariable } from '@/models/debug' | ||||
| import type { InputVar } from '@/app/components/workflow/types' | 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 = { | type Props = { | ||||
| show: boolean | show: boolean | ||||
| onAutoAddPromptVariable, | onAutoAddPromptVariable, | ||||
| }: Props) => { | }: Props) => { | ||||
| const { t } = useTranslation() | const { t } = useTranslation() | ||||
| const { locale } = useContext(I18n) | |||||
| const docLink = useDocLink() | |||||
| const { data: speech2textDefaultModel } = useDefaultModel(ModelTypeEnum.speech2text) | const { data: speech2textDefaultModel } = useDefaultModel(ModelTypeEnum.speech2text) | ||||
| const { data: text2speechDefaultModel } = useDefaultModel(ModelTypeEnum.tts) | const { data: text2speechDefaultModel } = useDefaultModel(ModelTypeEnum.tts) | ||||
| <span>{isChatMode ? t('workflow.common.fileUploadTip') : t('workflow.common.ImageUploadLegacyTip')}</span> | <span>{isChatMode ? t('workflow.common.fileUploadTip') : t('workflow.common.ImageUploadLegacyTip')}</span> | ||||
| <a | <a | ||||
| className='text-text-accent' | 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' | target='_blank' rel='noopener noreferrer' | ||||
| >{t('workflow.common.featuresDocLink')}</a> | >{t('workflow.common.featuresDocLink')}</a> | ||||
| </div> | </div> |
| import { PortalToFollowElem, PortalToFollowElemContent, PortalToFollowElemTrigger } from '@/app/components/base/portal-to-follow-elem' | import { PortalToFollowElem, PortalToFollowElemContent, PortalToFollowElemTrigger } from '@/app/components/base/portal-to-follow-elem' | ||||
| import { AlertTriangle } from '@/app/components/base/icons/src/vender/solid/alertsAndFeedback' | import { AlertTriangle } from '@/app/components/base/icons/src/vender/solid/alertsAndFeedback' | ||||
| import { noop } from 'lodash-es' | import { noop } from 'lodash-es' | ||||
| import { useDocLink } from '@/context/i18n' | |||||
| const TextLabel: FC<PropsWithChildren> = (props) => { | const TextLabel: FC<PropsWithChildren> = (props) => { | ||||
| return <label className='system-sm-semibold text-text-secondary'>{props.children}</label> | return <label className='system-sm-semibold text-text-secondary'>{props.children}</label> | ||||
| updateRetrievalMethodCache, | updateRetrievalMethodCache, | ||||
| }: StepTwoProps) => { | }: StepTwoProps) => { | ||||
| const { t } = useTranslation() | const { t } = useTranslation() | ||||
| const docLink = useDocLink() | |||||
| const { locale } = useContext(I18n) | const { locale } = useContext(I18n) | ||||
| const media = useBreakpoints() | const media = useBreakpoints() | ||||
| const isMobile = media === MediaType.mobile | const isMobile = media === MediaType.mobile | ||||
| <div className={'mb-1'}> | <div className={'mb-1'}> | ||||
| <div className='system-md-semibold mb-0.5 text-text-secondary'>{t('datasetSettings.form.retrievalSetting.title')}</div> | <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'> | <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')} | {t('datasetSettings.form.retrievalSetting.longDescription')} | ||||
| </div> | </div> | ||||
| </div> | </div> |
| import { useTranslation } from 'react-i18next' | import { useTranslation } from 'react-i18next' | ||||
| import Input from './input' | import Input from './input' | ||||
| import Button from '@/app/components/base/button' | import Button from '@/app/components/base/button' | ||||
| import { useDocLink } from '@/context/i18n' | |||||
| const I18N_PREFIX = 'datasetCreation.stepOne.website' | const I18N_PREFIX = 'datasetCreation.stepOne.website' | ||||
| onRun, | onRun, | ||||
| }) => { | }) => { | ||||
| const { t } = useTranslation() | const { t } = useTranslation() | ||||
| const docLink = useDocLink() | |||||
| const [url, setUrl] = useState('') | const [url, setUrl] = useState('') | ||||
| const handleUrlChange = useCallback((url: string | number) => { | const handleUrlChange = useCallback((url: string | number) => { | ||||
| setUrl(url as string) | setUrl(url as string) | ||||
| <Input | <Input | ||||
| value={url} | value={url} | ||||
| onChange={handleUrlChange} | onChange={handleUrlChange} | ||||
| placeholder='https://docs.dify.ai' | |||||
| placeholder={docLink()} | |||||
| /> | /> | ||||
| <Button | <Button | ||||
| variant='primary' | variant='primary' |
| import { useTranslation } from 'react-i18next' | import { useTranslation } from 'react-i18next' | ||||
| import Input from './input' | import Input from './input' | ||||
| import Button from '@/app/components/base/button' | import Button from '@/app/components/base/button' | ||||
| import { useDocLink } from '@/context/i18n' | |||||
| const I18N_PREFIX = 'datasetCreation.stepOne.website' | const I18N_PREFIX = 'datasetCreation.stepOne.website' | ||||
| onRun, | onRun, | ||||
| }) => { | }) => { | ||||
| const { t } = useTranslation() | const { t } = useTranslation() | ||||
| const docLink = useDocLink() | |||||
| const [url, setUrl] = useState('') | const [url, setUrl] = useState('') | ||||
| const handleUrlChange = useCallback((url: string | number) => { | const handleUrlChange = useCallback((url: string | number) => { | ||||
| setUrl(url as string) | setUrl(url as string) | ||||
| <Input | <Input | ||||
| value={url} | value={url} | ||||
| onChange={handleUrlChange} | onChange={handleUrlChange} | ||||
| placeholder='https://docs.dify.ai' | |||||
| placeholder={docLink()} | |||||
| /> | /> | ||||
| <Button | <Button | ||||
| variant='primary' | variant='primary' |
| import useEditDocumentMetadata from '../metadata/hooks/use-edit-dataset-metadata' | import useEditDocumentMetadata from '../metadata/hooks/use-edit-dataset-metadata' | ||||
| import DatasetMetadataDrawer from '../metadata/metadata-dataset/dataset-metadata-drawer' | import DatasetMetadataDrawer from '../metadata/metadata-dataset/dataset-metadata-drawer' | ||||
| import StatusWithAction from '../common/document-status-with-action/status-with-action' | 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>) => { | 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 ?? ''}> | return <svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg" className={className ?? ''}> | ||||
| const Documents: FC<IDocumentsProps> = ({ datasetId }) => { | const Documents: FC<IDocumentsProps> = ({ datasetId }) => { | ||||
| const { t } = useTranslation() | const { t } = useTranslation() | ||||
| const docLink = useDocLink() | |||||
| const { plan } = useProviderContext() | const { plan } = useProviderContext() | ||||
| const isFreePlan = plan.type === 'sandbox' | const isFreePlan = plan.type === 'sandbox' | ||||
| const [inputValue, setInputValue] = useState<string>('') // the input value | const [inputValue, setInputValue] = useState<string>('') // the input value | ||||
| const isDataSourceWeb = dataset?.data_source_type === DataSourceType.WEB | const isDataSourceWeb = dataset?.data_source_type === DataSourceType.WEB | ||||
| const isDataSourceFile = dataset?.data_source_type === DataSourceType.FILE | const isDataSourceFile = dataset?.data_source_type === DataSourceType.FILE | ||||
| const embeddingAvailable = !!dataset?.embedding_available | const embeddingAvailable = !!dataset?.embedding_available | ||||
| const locale = getLocaleOnClient() | |||||
| const debouncedSearchValue = useDebounce(searchValue, { wait: 500 }) | const debouncedSearchValue = useDebounce(searchValue, { wait: 500 }) | ||||
| const { data: documentsRes, isFetching: isListLoading } = useDocumentList({ | const { data: documentsRes, isFetching: isListLoading } = useDocumentList({ | ||||
| <a | <a | ||||
| className='flex items-center text-text-accent' | className='flex items-center text-text-accent' | ||||
| target='_blank' | 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> | <span>{t('datasetDocuments.list.learnMore')}</span> | ||||
| <RiExternalLinkLine className='h-3 w-3' /> | <RiExternalLinkLine className='h-3 w-3' /> |
| import type { CreateExternalAPIReq, FormSchema } from '../declarations' | import type { CreateExternalAPIReq, FormSchema } from '../declarations' | ||||
| import Input from '@/app/components/base/input' | import Input from '@/app/components/base/input' | ||||
| import cn from '@/utils/classnames' | import cn from '@/utils/classnames' | ||||
| import { useDocLink } from '@/context/i18n' | |||||
| type FormProps = { | type FormProps = { | ||||
| className?: string | className?: string | ||||
| inputClassName, | inputClassName, | ||||
| }) => { | }) => { | ||||
| const { t, i18n } = useTranslation() | const { t, i18n } = useTranslation() | ||||
| const docLink = useDocLink() | |||||
| const [changeKey, setChangeKey] = useState('') | const [changeKey, setChangeKey] = useState('') | ||||
| const handleFormChange = (key: string, val: string) => { | const handleFormChange = (key: string, val: string) => { | ||||
| </label> | </label> | ||||
| {variable === 'endpoint' && ( | {variable === 'endpoint' && ( | ||||
| <a | <a | ||||
| href={'https://docs.dify.ai/guides/knowledge-base/external-knowledge-api-documentation' || '/'} | |||||
| href={docLink('/guides/knowledge-base/external-knowledge-api-documentation') || '/'} | |||||
| target='_blank' | target='_blank' | ||||
| rel='noopener noreferrer' | rel='noopener noreferrer' | ||||
| className='body-xs-regular flex items-center text-text-accent' | className='body-xs-regular flex items-center text-text-accent' |
| 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 { useModalContext } from '@/context/modal-context' | import { useModalContext } from '@/context/modal-context' | ||||
| import { useDocLink } from '@/context/i18n' | |||||
| type ExternalAPIPanelProps = { | type ExternalAPIPanelProps = { | ||||
| onClose: () => void | onClose: () => void | ||||
| const ExternalAPIPanel: React.FC<ExternalAPIPanelProps> = ({ onClose }) => { | const ExternalAPIPanel: React.FC<ExternalAPIPanelProps> = ({ onClose }) => { | ||||
| const { t } = useTranslation() | const { t } = useTranslation() | ||||
| const docLink = useDocLink() | |||||
| const { setShowExternalKnowledgeAPIModal } = useModalContext() | const { setShowExternalKnowledgeAPIModal } = useModalContext() | ||||
| const { externalKnowledgeApiList, mutateExternalKnowledgeApis, isLoading } = useExternalKnowledgeApi() | const { externalKnowledgeApiList, mutateExternalKnowledgeApis, isLoading } = useExternalKnowledgeApi() | ||||
| <div className='flex grow flex-col items-start gap-1'> | <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='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> | <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' /> | <RiBookOpenLine className='h-3 w-3 text-text-accent' /> | ||||
| <div className='body-xs-regular grow text-text-accent'>{t('dataset.externalAPIPanelDocumentation')}</div> | <div className='body-xs-regular grow text-text-accent'>{t('dataset.externalAPIPanelDocumentation')}</div> | ||||
| </a> | </a> |
| import { RiBookOpenLine } from '@remixicon/react' | import { RiBookOpenLine } from '@remixicon/react' | ||||
| import { useTranslation } from 'react-i18next' | import { useTranslation } from 'react-i18next' | ||||
| import { useDocLink } from '@/context/i18n' | |||||
| const InfoPanel = () => { | const InfoPanel = () => { | ||||
| const { t } = useTranslation() | const { t } = useTranslation() | ||||
| const docLink = useDocLink() | |||||
| return ( | return ( | ||||
| <div className='flex w-[360px] flex-col items-start pb-2 pr-8 pt-[108px]'> | <div className='flex w-[360px] flex-col items-start pb-2 pr-8 pt-[108px]'> | ||||
| </span> | </span> | ||||
| <span className='system-sm-regular text-text-tertiary'> | <span className='system-sm-regular text-text-tertiary'> | ||||
| {t('dataset.connectDatasetIntro.content.front')} | {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')} | {t('dataset.connectDatasetIntro.content.link')} | ||||
| </a> | </a> | ||||
| {t('dataset.connectDatasetIntro.content.end')} | {t('dataset.connectDatasetIntro.content.end')} | ||||
| </span> | </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')} | {t('dataset.connectDatasetIntro.learnMore')} | ||||
| </a> | </a> | ||||
| </p> | </p> |
| import type { CreateKnowledgeBaseReq } from './declarations' | import type { CreateKnowledgeBaseReq } from './declarations' | ||||
| import Divider from '@/app/components/base/divider' | import Divider from '@/app/components/base/divider' | ||||
| import Button from '@/app/components/base/button' | import Button from '@/app/components/base/button' | ||||
| import { useDocLink } from '@/context/i18n' | |||||
| type ExternalKnowledgeBaseCreateProps = { | type ExternalKnowledgeBaseCreateProps = { | ||||
| onConnect: (formValue: CreateKnowledgeBaseReq) => void | onConnect: (formValue: CreateKnowledgeBaseReq) => void | ||||
| const ExternalKnowledgeBaseCreate: React.FC<ExternalKnowledgeBaseCreateProps> = ({ onConnect, loading }) => { | const ExternalKnowledgeBaseCreate: React.FC<ExternalKnowledgeBaseCreateProps> = ({ onConnect, loading }) => { | ||||
| const { t } = useTranslation() | const { t } = useTranslation() | ||||
| const docLink = useDocLink() | |||||
| const router = useRouter() | const router = useRouter() | ||||
| const [formData, setFormData] = useState<CreateKnowledgeBaseReq>({ | const [formData, setFormData] = useState<CreateKnowledgeBaseReq>({ | ||||
| name: '', | name: '', | ||||
| <span>{t('dataset.connectHelper.helper1')}</span> | <span>{t('dataset.connectHelper.helper1')}</span> | ||||
| <span className='system-sm-medium text-text-secondary'>{t('dataset.connectHelper.helper2')}</span> | <span className='system-sm-medium text-text-secondary'>{t('dataset.connectHelper.helper2')}</span> | ||||
| <span>{t('dataset.connectHelper.helper3')}</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')} | {t('dataset.connectHelper.helper4')} | ||||
| </a> | </a> | ||||
| <span>{t('dataset.connectHelper.helper5')} </span> | <span>{t('dataset.connectHelper.helper5')} </span> |
| import Button from '@/app/components/base/button' | import Button from '@/app/components/base/button' | ||||
| import { isReRankModelSelected } from '@/app/components/datasets/common/check-rerank-model' | import { isReRankModelSelected } from '@/app/components/datasets/common/check-rerank-model' | ||||
| 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 { useDocLink } from '@/context/i18n' | |||||
| type Props = { | type Props = { | ||||
| indexMethod: string | indexMethod: string | ||||
| }) => { | }) => { | ||||
| const ref = useRef(null) | const ref = useRef(null) | ||||
| const { t } = useTranslation() | const { t } = useTranslation() | ||||
| const docLink = useDocLink() | |||||
| const [retrievalConfig, setRetrievalConfig] = useState(value) | const [retrievalConfig, setRetrievalConfig] = useState(value) | ||||
| // useClickAway(() => { | // useClickAway(() => { | ||||
| <a | <a | ||||
| target='_blank' | target='_blank' | ||||
| rel='noopener noreferrer' | 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' | className='text-text-accent' | ||||
| > | > | ||||
| {t('datasetSettings.form.retrievalSetting.learnMore')} | {t('datasetSettings.form.retrievalSetting.learnMore')} |
| import { fetchMembers } from '@/service/common' | import { fetchMembers } from '@/service/common' | ||||
| import type { Member } from '@/models/common' | import type { Member } from '@/models/common' | ||||
| import AlertTriangle from '@/app/components/base/icons/src/vender/solid/alertsAndFeedback/AlertTriangle' | import AlertTriangle from '@/app/components/base/icons/src/vender/solid/alertsAndFeedback/AlertTriangle' | ||||
| import { useDocLink } from '@/context/i18n' | |||||
| const rowClass = 'flex' | const rowClass = 'flex' | ||||
| const labelClass = ` | const labelClass = ` | ||||
| const Form = () => { | const Form = () => { | ||||
| const { t } = useTranslation() | const { t } = useTranslation() | ||||
| const docLink = useDocLink() | |||||
| const { notify } = useContext(ToastContext) | const { notify } = useContext(ToastContext) | ||||
| const { mutate } = useSWRConfig() | const { mutate } = useSWRConfig() | ||||
| const { isCurrentWorkspaceDatasetOperator } = useAppContext() | const { isCurrentWorkspaceDatasetOperator } = useAppContext() | ||||
| <div> | <div> | ||||
| <div className='system-sm-semibold text-text-secondary'>{t('datasetSettings.form.retrievalSetting.title')}</div> | <div className='system-sm-semibold text-text-secondary'>{t('datasetSettings.form.retrievalSetting.title')}</div> | ||||
| <div className='body-xs-regular text-text-tertiary'> | <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')} | {t('datasetSettings.form.retrievalSetting.description')} | ||||
| </div> | </div> | ||||
| </div> | </div> |
| import Support from './support' | import Support from './support' | ||||
| import Compliance from './compliance' | import Compliance from './compliance' | ||||
| import PremiumBadge from '@/app/components/base/premium-badge' | import PremiumBadge from '@/app/components/base/premium-badge' | ||||
| import { useGetDocLanguage } from '@/context/i18n' | |||||
| import Avatar from '@/app/components/base/avatar' | import Avatar from '@/app/components/base/avatar' | ||||
| import ThemeSwitcher from '@/app/components/base/theme-switcher' | import ThemeSwitcher from '@/app/components/base/theme-switcher' | ||||
| import { logout } from '@/service/common' | import { logout } from '@/service/common' | ||||
| import { IS_CLOUD_EDITION } from '@/config' | import { IS_CLOUD_EDITION } from '@/config' | ||||
| import cn from '@/utils/classnames' | import cn from '@/utils/classnames' | ||||
| import { useGlobalPublicStore } from '@/context/global-public-context' | import { useGlobalPublicStore } from '@/context/global-public-context' | ||||
| import { useDocLink } from '@/context/i18n' | |||||
| export default function AppSelector() { | export default function AppSelector() { | ||||
| const itemClassName = ` | const itemClassName = ` | ||||
| const { systemFeatures } = useGlobalPublicStore() | const { systemFeatures } = useGlobalPublicStore() | ||||
| const { t } = useTranslation() | const { t } = useTranslation() | ||||
| const docLink = useDocLink() | |||||
| const { userProfile, langeniusVersionInfo, isCurrentWorkspaceOwner } = useAppContext() | const { userProfile, langeniusVersionInfo, isCurrentWorkspaceOwner } = useAppContext() | ||||
| const { isEducationAccount } = useProviderContext() | const { isEducationAccount } = useProviderContext() | ||||
| const { setShowAccountSettingModal } = useModalContext() | const { setShowAccountSettingModal } = useModalContext() | ||||
| const docLanguage = useGetDocLanguage() | |||||
| const handleLogout = async () => { | const handleLogout = async () => { | ||||
| await logout({ | await logout({ | ||||
| className={cn(itemClassName, 'group justify-between', | className={cn(itemClassName, 'group justify-between', | ||||
| 'data-[active]:bg-state-base-hover', | 'data-[active]:bg-state-base-hover', | ||||
| )} | )} | ||||
| href={`https://docs.dify.ai/${docLanguage}/introduction`} | |||||
| href={docLink('/introduction')} | |||||
| target='_blank' rel='noopener noreferrer'> | target='_blank' rel='noopener noreferrer'> | ||||
| <RiBookOpenLine className='size-4 shrink-0 text-text-tertiary' /> | <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> | <div className='system-md-regular grow px-1 text-text-secondary'>{t('common.userProfile.helpCenter')}</div> |
| import React, { useMemo } from 'react' | import React, { useMemo } from 'react' | ||||
| import { useTranslation } from 'react-i18next' | import { useTranslation } from 'react-i18next' | ||||
| import { useContext } from 'use-context-selector' | |||||
| import { useDocLink } from '@/context/i18n' | |||||
| import { useBoolean } from 'ahooks' | import { useBoolean } from 'ahooks' | ||||
| import { | import { | ||||
| RiAddLine, | RiAddLine, | ||||
| useInvalidateEndpointList, | useInvalidateEndpointList, | ||||
| } from '@/service/use-endpoints' | } from '@/service/use-endpoints' | ||||
| import type { PluginDetail } from '@/app/components/plugins/types' | import type { PluginDetail } from '@/app/components/plugins/types' | ||||
| import { LanguagesSupported } from '@/i18n/language' | |||||
| import I18n from '@/context/i18n' | |||||
| import cn from '@/utils/classnames' | import cn from '@/utils/classnames' | ||||
| type Props = { | type Props = { | ||||
| } | } | ||||
| const EndpointList = ({ detail }: Props) => { | const EndpointList = ({ detail }: Props) => { | ||||
| const { t } = useTranslation() | const { t } = useTranslation() | ||||
| const { locale } = useContext(I18n) | |||||
| const docLink = useDocLink() | |||||
| const pluginUniqueID = detail.plugin_unique_identifier | const pluginUniqueID = detail.plugin_unique_identifier | ||||
| const declaration = detail.declaration.endpoint | const declaration = detail.declaration.endpoint | ||||
| const showTopBorder = detail.declaration.tool | const showTopBorder = detail.declaration.tool | ||||
| </div> | </div> | ||||
| <div className='system-xs-regular text-text-tertiary'>{t('plugin.detailPanel.endpointsTip')}</div> | <div className='system-xs-regular text-text-tertiary'>{t('plugin.detailPanel.endpointsTip')}</div> | ||||
| <a | <a | ||||
| href={`https://docs.dify.ai/${locale === LanguagesSupported[1] ? 'v/zh-hans/' : ''}plugins/schema-definition/endpoint`} | |||||
| href={docLink('/plugins/schema-definition/endpoint')} | |||||
| target='_blank' | target='_blank' | ||||
| rel='noopener noreferrer' | rel='noopener noreferrer' | ||||
| > | > |
| import { createCustomCollection } from '@/service/tools' | import { createCustomCollection } from '@/service/tools' | ||||
| import Toast from '@/app/components/base/toast' | import Toast from '@/app/components/base/toast' | ||||
| import { useAppContext } from '@/context/app-context' | import { useAppContext } from '@/context/app-context' | ||||
| import { useDocLink } from '@/context/i18n' | |||||
| type Props = { | type Props = { | ||||
| onRefreshData: () => void | onRefreshData: () => void | ||||
| const language = getLanguage(locale) | const language = getLanguage(locale) | ||||
| const { isCurrentWorkspaceManager } = useAppContext() | const { isCurrentWorkspaceManager } = useAppContext() | ||||
| const docLink = useDocLink() | |||||
| const linkUrl = useMemo(() => { | 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]) | }, [language]) | ||||
| const [isShowEditCollectionToolModal, setIsShowEditCustomCollectionModal] = useState(false) | const [isShowEditCollectionToolModal, setIsShowEditCustomCollectionModal] = useState(false) |
| import { useRenderI18nObject } from '@/hooks/use-i18n' | import { useRenderI18nObject } from '@/hooks/use-i18n' | ||||
| import type { NodeOutPutVar } from '../../../types' | import type { NodeOutPutVar } from '../../../types' | ||||
| import type { Node } from 'reactflow' | 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 = { | export type Strategy = { | ||||
| agent_strategy_provider_name: string | agent_strategy_provider_name: string | ||||
| export const AgentStrategy = memo((props: AgentStrategyProps) => { | export const AgentStrategy = memo((props: AgentStrategyProps) => { | ||||
| const { strategy, onStrategyChange, formSchema, formValue, onFormValueChange, nodeOutputVars, availableNodes, nodeId } = props | const { strategy, onStrategyChange, formSchema, formValue, onFormValueChange, nodeOutputVars, availableNodes, nodeId } = props | ||||
| const { t } = useTranslation() | const { t } = useTranslation() | ||||
| const { locale } = useContext(I18n) | |||||
| const docLink = useDocLink() | |||||
| const defaultModel = useDefaultModel(ModelTypeEnum.textGeneration) | const defaultModel = useDefaultModel(ModelTypeEnum.textGeneration) | ||||
| const renderI18nObject = useRenderI18nObject() | const renderI18nObject = useRenderI18nObject() | ||||
| const workflowStore = useWorkflowStore() | const workflowStore = useWorkflowStore() | ||||
| title={t('workflow.nodes.agent.strategy.configureTip')} | title={t('workflow.nodes.agent.strategy.configureTip')} | ||||
| description={<div className='text-xs text-text-tertiary'> | description={<div className='text-xs text-text-tertiary'> | ||||
| {t('workflow.nodes.agent.strategy.configureTipDesc')} <br /> | {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')} | {t('workflow.nodes.agent.learnMore')} | ||||
| </Link> | </Link> | ||||
| </div>} | </div>} |
| import { VarType } from '@/app/components/workflow/types' | import { VarType } from '@/app/components/workflow/types' | ||||
| import { CodeLanguage } from '@/app/components/workflow/nodes/code/types' | import { CodeLanguage } from '@/app/components/workflow/nodes/code/types' | ||||
| import CodeEditor from '@/app/components/workflow/nodes/_base/components/editor/code-editor' | import CodeEditor from '@/app/components/workflow/nodes/_base/components/editor/code-editor' | ||||
| import { useDocLink } from '@/context/i18n' | |||||
| type DefaultValueProps = { | type DefaultValueProps = { | ||||
| forms: DefaultValueForm[] | forms: DefaultValueForm[] | ||||
| onFormChange, | onFormChange, | ||||
| }: DefaultValueProps) => { | }: DefaultValueProps) => { | ||||
| const { t } = useTranslation() | const { t } = useTranslation() | ||||
| const docLink = useDocLink() | |||||
| const getFormChangeHandler = useCallback(({ key, type }: DefaultValueForm) => { | const getFormChangeHandler = useCallback(({ key, type }: DefaultValueForm) => { | ||||
| return (payload: any) => { | return (payload: any) => { | ||||
| let value | let value | ||||
| {t('workflow.nodes.common.errorHandle.defaultValue.desc')} | {t('workflow.nodes.common.errorHandle.defaultValue.desc')} | ||||
| | | ||||
| <a | <a | ||||
| href='https://docs.dify.ai/en/guides/workflow/error-handling/README' | |||||
| href={docLink('/guides/workflow/error-handling/README')} | |||||
| target='_blank' | target='_blank' | ||||
| className='text-text-accent' | className='text-text-accent' | ||||
| > | > |
| import { RiMindMap } from '@remixicon/react' | import { RiMindMap } from '@remixicon/react' | ||||
| import { useTranslation } from 'react-i18next' | import { useTranslation } from 'react-i18next' | ||||
| import { useDocLink } from '@/context/i18n' | |||||
| const FailBranchCard = () => { | const FailBranchCard = () => { | ||||
| const { t } = useTranslation() | const { t } = useTranslation() | ||||
| const docLink = useDocLink() | |||||
| return ( | return ( | ||||
| <div className='px-4 pt-2'> | <div className='px-4 pt-2'> | ||||
| {t('workflow.nodes.common.errorHandle.failBranch.customizeTip')} | {t('workflow.nodes.common.errorHandle.failBranch.customizeTip')} | ||||
| | | ||||
| <a | <a | ||||
| href='https://docs.dify.ai/guides/workflow/error-handling' | |||||
| href={docLink('/guides/workflow/error-handling/error-type')} | |||||
| target='_blank' | target='_blank' | ||||
| className='text-text-accent' | className='text-text-accent' | ||||
| > | > |
| import type { FC } from 'react' | import type { FC } from 'react' | ||||
| import React from 'react' | import React from 'react' | ||||
| import { useTranslation } from 'react-i18next' | import { useTranslation } from 'react-i18next' | ||||
| import { useContext } from 'use-context-selector' | |||||
| import VarReferenceVars from './var-reference-vars' | import VarReferenceVars from './var-reference-vars' | ||||
| import type { NodeOutPutVar, ValueSelector, Var } from '@/app/components/workflow/types' | import type { NodeOutPutVar, ValueSelector, Var } from '@/app/components/workflow/types' | ||||
| import ListEmpty from '@/app/components/base/list-empty' | 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 = { | type Props = { | ||||
| vars: NodeOutPutVar[] | vars: NodeOutPutVar[] | ||||
| isSupportFileVar = true, | isSupportFileVar = true, | ||||
| }) => { | }) => { | ||||
| const { t } = useTranslation() | const { t } = useTranslation() | ||||
| const { locale } = useContext(I18n) | |||||
| const docLink = useDocLink() | |||||
| // max-h-[300px] overflow-y-auto todo: use portal to handle long list | // max-h-[300px] overflow-y-auto todo: use portal to handle long list | ||||
| return ( | return ( | ||||
| <div className='space-y-1 rounded-lg border border-components-panel-border bg-components-panel-bg p-1 shadow-lg' style={{ | <div className='space-y-1 rounded-lg border border-components-panel-border bg-components-panel-bg p-1 shadow-lg' style={{ | ||||
| description={<div className='system-xs-regular text-text-tertiary'> | description={<div className='system-xs-regular text-text-tertiary'> | ||||
| {t('workflow.variableReference.assignedVarsDescription')} | {t('workflow.variableReference.assignedVarsDescription')} | ||||
| <a target='_blank' rel='noopener noreferrer' | <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>} | </div>} | ||||
| /> | /> | ||||
| )) | )) |
| import { useMemo } from 'react' | import { useMemo } from 'react' | ||||
| import { useGetLanguage } from '@/context/i18n' | |||||
| import { useDocLink, useGetLanguage } from '@/context/i18n' | |||||
| import { BlockEnum } from '@/app/components/workflow/types' | import { BlockEnum } from '@/app/components/workflow/types' | ||||
| export const useNodeHelpLink = (nodeType: BlockEnum) => { | export const useNodeHelpLink = (nodeType: BlockEnum) => { | ||||
| const language = useGetLanguage() | const language = useGetLanguage() | ||||
| const docLink = useDocLink() | |||||
| const prefixLink = useMemo(() => { | 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]) | }, [language]) | ||||
| const linkMap = useMemo(() => { | const linkMap = useMemo(() => { | ||||
| if (language === 'zh_Hans') { | if (language === 'zh_Hans') { |
| import ErrorMessage from './error-message' | import ErrorMessage from './error-message' | ||||
| import { useVisualEditorStore } from './visual-editor/store' | import { useVisualEditorStore } from './visual-editor/store' | ||||
| import Toast from '@/app/components/base/toast' | import Toast from '@/app/components/base/toast' | ||||
| import { useGetDocLanguage } from '@/context/i18n' | |||||
| import { JSON_SCHEMA_MAX_DEPTH } from '@/config' | import { JSON_SCHEMA_MAX_DEPTH } from '@/config' | ||||
| import { useDocLink } from '@/context/i18n' | |||||
| type JsonSchemaConfigProps = { | type JsonSchemaConfigProps = { | ||||
| defaultSchema?: SchemaRoot | defaultSchema?: SchemaRoot | ||||
| onClose, | onClose, | ||||
| }) => { | }) => { | ||||
| const { t } = useTranslation() | const { t } = useTranslation() | ||||
| const docLanguage = useGetDocLanguage() | |||||
| const docLink = useDocLink() | |||||
| const [currentTab, setCurrentTab] = useState(SchemaView.VisualEditor) | const [currentTab, setCurrentTab] = useState(SchemaView.VisualEditor) | ||||
| const [jsonSchema, setJsonSchema] = useState(defaultSchema || DEFAULT_SCHEMA) | const [jsonSchema, setJsonSchema] = useState(defaultSchema || DEFAULT_SCHEMA) | ||||
| const [json, setJson] = useState(JSON.stringify(jsonSchema, null, 2)) | const [json, setJson] = useState(JSON.stringify(jsonSchema, null, 2)) | ||||
| <div className='flex items-center gap-x-2 p-6 pt-5'> | <div className='flex items-center gap-x-2 p-6 pt-5'> | ||||
| <a | <a | ||||
| className='flex grow items-center gap-x-1 text-text-accent' | 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' | target='_blank' | ||||
| rel='noopener noreferrer' | rel='noopener noreferrer' | ||||
| > | > |
| useCallback, | useCallback, | ||||
| useState, | useState, | ||||
| } from 'react' | } from 'react' | ||||
| import { useContext } from 'use-context-selector' | |||||
| import { | import { | ||||
| useStoreApi, | useStoreApi, | ||||
| } from 'reactflow' | } from 'reactflow' | ||||
| import { findUsedVarNodes, updateNodeVars } from '@/app/components/workflow/nodes/_base/components/variable/utils' | import { findUsedVarNodes, updateNodeVars } from '@/app/components/workflow/nodes/_base/components/variable/utils' | ||||
| import { useNodesSyncDraft } from '@/app/components/workflow/hooks/use-nodes-sync-draft' | import { useNodesSyncDraft } from '@/app/components/workflow/hooks/use-nodes-sync-draft' | ||||
| import { BlockEnum } from '@/app/components/workflow/types' | 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' | import cn from '@/utils/classnames' | ||||
| const ChatVariablePanel = () => { | const ChatVariablePanel = () => { | ||||
| const { t } = useTranslation() | const { t } = useTranslation() | ||||
| const { locale } = useContext(I18n) | |||||
| const docLink = useDocLink() | |||||
| const store = useStoreApi() | const store = useStoreApi() | ||||
| const setShowChatVariablePanel = useStore(s => s.setShowChatVariablePanel) | const setShowChatVariablePanel = useStore(s => s.setShowChatVariablePanel) | ||||
| const varList = useStore(s => s.conversationVariables) as ConversationVariable[] | const varList = useStore(s => s.conversationVariables) as ConversationVariable[] | ||||
| <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-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'> | <div className='system-sm-regular mb-4 mt-1 text-text-secondary'> | ||||
| {t('workflow.chatVariable.panelDescription')} | {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='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'> | <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' /> | <BubbleX className='mb-1 h-4 w-4 shrink-0 text-util-colors-teal-teal-700' /> |
| } from '@/types/workflow' | } from '@/types/workflow' | ||||
| import ErrorHandleTip from '@/app/components/workflow/nodes/_base/components/error-handle/error-handle-tip' | import ErrorHandleTip from '@/app/components/workflow/nodes/_base/components/error-handle/error-handle-tip' | ||||
| import { hasRetryNode } from '@/app/components/workflow/utils' | import { hasRetryNode } from '@/app/components/workflow/utils' | ||||
| import { useDocLink } from '@/context/i18n' | |||||
| type Props = { | type Props = { | ||||
| className?: string | className?: string | ||||
| doSetCollapseState(state) | doSetCollapseState(state) | ||||
| }, [hideProcessDetail]) | }, [hideProcessDetail]) | ||||
| const { t } = useTranslation() | const { t } = useTranslation() | ||||
| const docLink = useDocLink() | |||||
| const getTime = (time: number) => { | const getTime = (time: number) => { | ||||
| if (time < 1) | if (time < 1) | ||||
| <StatusContainer status='stopped'> | <StatusContainer status='stopped'> | ||||
| {nodeInfo.error} | {nodeInfo.error} | ||||
| <a | <a | ||||
| href='https://docs.dify.ai/guides/workflow/error-handling/error-type' | |||||
| href={docLink('/guides/workflow/error-handling/error-type')} | |||||
| target='_blank' | target='_blank' | ||||
| className='text-text-accent' | className='text-text-accent' | ||||
| > | > |
| import cn from '@/utils/classnames' | import cn from '@/utils/classnames' | ||||
| import Indicator from '@/app/components/header/indicator' | import Indicator from '@/app/components/header/indicator' | ||||
| import StatusContainer from '@/app/components/workflow/run/status-container' | import StatusContainer from '@/app/components/workflow/run/status-container' | ||||
| import { useDocLink } from '@/context/i18n' | |||||
| type ResultProps = { | type ResultProps = { | ||||
| status: string | status: string | ||||
| exceptionCounts, | exceptionCounts, | ||||
| }) => { | }) => { | ||||
| const { t } = useTranslation() | const { t } = useTranslation() | ||||
| const docLink = useDocLink() | |||||
| return ( | return ( | ||||
| <StatusContainer status={status}> | <StatusContainer status={status}> | ||||
| <div className='system-xs-medium text-text-warning'> | <div className='system-xs-medium text-text-warning'> | ||||
| {error} | {error} | ||||
| <a | <a | ||||
| href='https://docs.dify.ai/guides/workflow/error-handling/error-type' | |||||
| href={docLink('/guides/workflow/error-handling/error-type')} | |||||
| target='_blank' | target='_blank' | ||||
| className='text-text-accent' | className='text-text-accent' | ||||
| > | > |
| 'use client' | 'use client' | ||||
| import { | import { | ||||
| useMemo, | |||||
| useState, | useState, | ||||
| } from 'react' | } from 'react' | ||||
| import { useTranslation } from 'react-i18next' | import { useTranslation } from 'react-i18next' | ||||
| import { useProviderContext } from '@/context/provider-context' | import { useProviderContext } from '@/context/provider-context' | ||||
| import { useToastContext } from '@/app/components/base/toast' | import { useToastContext } from '@/app/components/base/toast' | ||||
| import { EDUCATION_VERIFYING_LOCALSTORAGE_ITEM } from '@/app/education-apply/constants' | import { EDUCATION_VERIFYING_LOCALSTORAGE_ITEM } from '@/app/education-apply/constants' | ||||
| import { getLocaleOnClient } from '@/i18n' | |||||
| import { noop } from 'lodash-es' | import { noop } from 'lodash-es' | ||||
| import DifyLogo from '../components/base/logo/dify-logo' | import DifyLogo from '../components/base/logo/dify-logo' | ||||
| import { useDocLink } from '@/context/i18n' | |||||
| const EducationApplyAge = () => { | const EducationApplyAge = () => { | ||||
| const { t } = useTranslation() | const { t } = useTranslation() | ||||
| const locale = getLocaleOnClient() | |||||
| const [schoolName, setSchoolName] = useState('') | const [schoolName, setSchoolName] = useState('') | ||||
| const [role, setRole] = useState('Student') | const [role, setRole] = useState('Student') | ||||
| const [ageChecked, setAgeChecked] = useState(false) | const [ageChecked, setAgeChecked] = useState(false) | ||||
| const updateEducationStatus = useInvalidateEducationStatus() | const updateEducationStatus = useInvalidateEducationStatus() | ||||
| const { notify } = useToastContext() | const { notify } = useToastContext() | ||||
| const router = useRouter() | 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 = () => { | const handleModalConfirm = () => { | ||||
| setShowModal(undefined) | setShowModal(undefined) | ||||
| <div className='mb-4 mt-5 h-[1px] bg-gradient-to-r from-[rgba(16,24,40,0.08)]'></div> | <div className='mb-4 mt-5 h-[1px] bg-gradient-to-r from-[rgba(16,24,40,0.08)]'></div> | ||||
| <a | <a | ||||
| className='system-xs-regular flex items-center text-text-accent' | className='system-xs-regular flex items-center text-text-accent' | ||||
| href={docLink} | |||||
| href={docLink('/getting-started/dify-for-education')} | |||||
| target='_blank' | target='_blank' | ||||
| > | > | ||||
| {t('education.learn')} | {t('education.learn')} |
| import React, { useEffect, useMemo, useRef, useState } from 'react' | |||||
| import React, { useEffect, useRef, useState } from 'react' | |||||
| import { createPortal } from 'react-dom' | import { createPortal } from 'react-dom' | ||||
| import { useTranslation } from 'react-i18next' | import { useTranslation } from 'react-i18next' | ||||
| import { | import { | ||||
| RiExternalLinkLine, | RiExternalLinkLine, | ||||
| } from '@remixicon/react' | } from '@remixicon/react' | ||||
| import Button from '@/app/components/base/button' | import Button from '@/app/components/base/button' | ||||
| import { getLocaleOnClient } from '@/i18n' | |||||
| import { useDocLink } from '@/context/i18n' | |||||
| export type IConfirm = { | export type IConfirm = { | ||||
| className?: string | className?: string | ||||
| email, | email, | ||||
| }: IConfirm) { | }: IConfirm) { | ||||
| const { t } = useTranslation() | const { t } = useTranslation() | ||||
| const locale = getLocaleOnClient() | |||||
| const docLink = useDocLink() | |||||
| const dialogRef = useRef<HTMLDivElement>(null) | const dialogRef = useRef<HTMLDivElement>(null) | ||||
| const [isVisible, setIsVisible] = useState(isShow) | 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 = () => { | const handleClick = () => { | ||||
| window.open(docLink, '_blank', 'noopener,noreferrer') | |||||
| window.open(eduDocLink, '_blank', 'noopener,noreferrer') | |||||
| } | } | ||||
| useEffect(() => { | useEffect(() => { | ||||
| <div className='flex items-center gap-1'> | <div className='flex items-center gap-1'> | ||||
| {showLink && ( | {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' /> | <RiExternalLinkLine className='h-3 w-3 text-text-accent' /> | ||||
| </> | </> | ||||
| )} | )} |
| import { fetchInitValidateStatus, fetchSetupStatus, setup } from '@/service/common' | import { fetchInitValidateStatus, fetchSetupStatus, setup } from '@/service/common' | ||||
| import type { InitValidateStatusResponse, SetupStatusResponse } from '@/models/common' | import type { InitValidateStatusResponse, SetupStatusResponse } from '@/models/common' | ||||
| import useDocumentTitle from '@/hooks/use-document-title' | import useDocumentTitle from '@/hooks/use-document-title' | ||||
| import { useDocLink } from '@/context/i18n' | |||||
| const validPassword = /^(?=.*[a-zA-Z])(?=.*\d).{8,}$/ | const validPassword = /^(?=.*[a-zA-Z])(?=.*\d).{8,}$/ | ||||
| const InstallForm = () => { | const InstallForm = () => { | ||||
| useDocumentTitle('') | useDocumentTitle('') | ||||
| const { t } = useTranslation() | const { t } = useTranslation() | ||||
| const docLink = useDocLink() | |||||
| const router = useRouter() | const router = useRouter() | ||||
| const [showPassword, setShowPassword] = React.useState(false) | const [showPassword, setShowPassword] = React.useState(false) | ||||
| const [loading, setLoading] = React.useState(true) | const [loading, setLoading] = React.useState(true) | ||||
| <Link | <Link | ||||
| className='text-text-accent' | className='text-text-accent' | ||||
| target='_blank' rel='noopener noreferrer' | target='_blank' rel='noopener noreferrer' | ||||
| href={'https://docs.dify.ai/user-agreement/open-source'} | |||||
| href={docLink('/policies/open-source')} | |||||
| >{t('login.license.link')}</Link> | >{t('login.license.link')}</Link> | ||||
| </div> | </div> | ||||
| </div> | </div> |
| 'use client' | 'use client' | ||||
| import { useTranslation } from 'react-i18next' | import { useTranslation } from 'react-i18next' | ||||
| import { useDocLink } from '@/context/i18n' | |||||
| import { useCallback, useState } from 'react' | import { useCallback, useState } from 'react' | ||||
| import Link from 'next/link' | import Link from 'next/link' | ||||
| import { useContext } from 'use-context-selector' | import { useContext } from 'use-context-selector' | ||||
| export default function InviteSettingsPage() { | export default function InviteSettingsPage() { | ||||
| const { t } = useTranslation() | const { t } = useTranslation() | ||||
| const docLink = useDocLink() | |||||
| const router = useRouter() | const router = useRouter() | ||||
| const searchParams = useSearchParams() | const searchParams = useSearchParams() | ||||
| const token = decodeURIComponent(searchParams.get('invite_token') as string) | const token = decodeURIComponent(searchParams.get('invite_token') as string) | ||||
| const { locale, setLocaleOnClient } = useContext(I18n) | |||||
| const { setLocaleOnClient } = useContext(I18n) | |||||
| const [name, setName] = useState('') | const [name, setName] = useState('') | ||||
| const [language, setLanguage] = useState(LanguagesSupported[0]) | const [language, setLanguage] = useState(LanguagesSupported[0]) | ||||
| const [timezone, setTimezone] = useState(Intl.DateTimeFormat().resolvedOptions().timeZone || 'America/Los_Angeles') | const [timezone, setTimezone] = useState(Intl.DateTimeFormat().resolvedOptions().timeZone || 'America/Los_Angeles') | ||||
| <Link | <Link | ||||
| className='system-xs-medium text-text-accent-secondary' | className='system-xs-medium text-text-accent-secondary' | ||||
| target='_blank' rel='noopener noreferrer' | 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> | >{t('login.license.link')}</Link> | ||||
| </div> | </div> | ||||
| </div> | </div> |
| import { LanguagesSupported, languages } from '@/i18n/language' | import { LanguagesSupported, languages } from '@/i18n/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 { useDocLink } 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 docLink = useDocLink() | |||||
| const router = useRouter() | const router = useRouter() | ||||
| const searchParams = useSearchParams() | const searchParams = useSearchParams() | ||||
| <Link | <Link | ||||
| className='system-xs-medium text-text-accent-secondary' | className='system-xs-medium text-text-accent-secondary' | ||||
| target='_blank' rel='noopener noreferrer' | target='_blank' rel='noopener noreferrer' | ||||
| href={'https://docs.dify.ai/en/policies/agreement/README'} | |||||
| href={docLink('/policies/agreement/README')} | |||||
| >{t('login.license.link')}</Link> | >{t('login.license.link')}</Link> | ||||
| </div> | </div> | ||||
| </div> | </div> |
| return getPricingPageLanguage(locale) | 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 | export default I18NContext |