mirror of
https://github.com/langgenius/dify.git
synced 2026-07-16 01:48:40 +08:00
117 lines
4.1 KiB
TypeScript
117 lines
4.1 KiB
TypeScript
'use client'
|
|
import type { ComponentType } from 'react'
|
|
import type { App, AppSSO } from '@/types/app'
|
|
import { cn } from '@langgenius/dify-ui/cn'
|
|
import { useMemo } from 'react'
|
|
import { useLocale } from '@/context/i18n'
|
|
import useTheme from '@/hooks/use-theme'
|
|
import { getDocLanguage } from '@/i18n-config/language'
|
|
import { AppModeEnum, Theme } from '@/types/app'
|
|
import { useDocToc } from './hooks/use-doc-toc'
|
|
import TemplateEn from './template/template.en.mdx'
|
|
import TemplateJa from './template/template.ja.mdx'
|
|
import TemplateZh from './template/template.zh.mdx'
|
|
import TemplateAdvancedChatEn from './template/template_advanced_chat.en.mdx'
|
|
import TemplateAdvancedChatJa from './template/template_advanced_chat.ja.mdx'
|
|
import TemplateAdvancedChatZh from './template/template_advanced_chat.zh.mdx'
|
|
import TemplateChatEn from './template/template_chat.en.mdx'
|
|
import TemplateChatJa from './template/template_chat.ja.mdx'
|
|
import TemplateChatZh from './template/template_chat.zh.mdx'
|
|
import TemplateWorkflowEn from './template/template_workflow.en.mdx'
|
|
import TemplateWorkflowJa from './template/template_workflow.ja.mdx'
|
|
import TemplateWorkflowZh from './template/template_workflow.zh.mdx'
|
|
import TocPanel from './toc-panel'
|
|
|
|
type AppDetail = App & Partial<AppSSO>
|
|
type PromptVariable = { key: string; name: string }
|
|
|
|
type IDocProps = {
|
|
appDetail: AppDetail
|
|
}
|
|
|
|
// Shared props shape for all MDX template components
|
|
type TemplateProps = {
|
|
appDetail: AppDetail
|
|
variables: PromptVariable[]
|
|
inputs: Record<string, string>
|
|
}
|
|
|
|
// Lookup table: [appMode][docLanguage] → template component
|
|
// MDX components accept arbitrary props at runtime but expose a narrow static type,
|
|
// so we assert the map type to allow passing TemplateProps when rendering.
|
|
const TEMPLATE_MAP = {
|
|
[AppModeEnum.CHAT]: { zh: TemplateChatZh, ja: TemplateChatJa, en: TemplateChatEn },
|
|
[AppModeEnum.AGENT_CHAT]: { zh: TemplateChatZh, ja: TemplateChatJa, en: TemplateChatEn },
|
|
[AppModeEnum.ADVANCED_CHAT]: {
|
|
zh: TemplateAdvancedChatZh,
|
|
ja: TemplateAdvancedChatJa,
|
|
en: TemplateAdvancedChatEn,
|
|
},
|
|
[AppModeEnum.WORKFLOW]: {
|
|
zh: TemplateWorkflowZh,
|
|
ja: TemplateWorkflowJa,
|
|
en: TemplateWorkflowEn,
|
|
},
|
|
[AppModeEnum.COMPLETION]: { zh: TemplateZh, ja: TemplateJa, en: TemplateEn },
|
|
} as Record<string, Record<string, ComponentType<TemplateProps>>>
|
|
|
|
const resolveTemplate = (
|
|
mode: string | undefined,
|
|
locale: string,
|
|
): ComponentType<TemplateProps> | null => {
|
|
if (!mode) return null
|
|
const langTemplates = TEMPLATE_MAP[mode]
|
|
if (!langTemplates) return null
|
|
const docLang = getDocLanguage(locale)
|
|
return langTemplates[docLang] ?? langTemplates.en ?? null
|
|
}
|
|
|
|
const Doc = ({ appDetail }: IDocProps) => {
|
|
const locale = useLocale()
|
|
const { theme } = useTheme()
|
|
const { toc, isTocExpanded, setIsTocExpanded, activeSection, handleTocClick } = useDocToc({
|
|
appDetail,
|
|
locale,
|
|
})
|
|
|
|
// model_config.configs.prompt_variables exists in the raw API response but is not modeled in ModelConfig type
|
|
const variables: PromptVariable[] =
|
|
(
|
|
appDetail?.model_config as unknown as
|
|
| Record<string, Record<string, PromptVariable[]>>
|
|
| undefined
|
|
)?.configs?.prompt_variables ?? []
|
|
const inputs = variables.reduce<Record<string, string>>((res, variable) => {
|
|
res[variable.key] = variable.name || ''
|
|
return res
|
|
}, {})
|
|
|
|
const TemplateComponent = useMemo(
|
|
() => resolveTemplate(appDetail?.mode, locale),
|
|
[appDetail?.mode, locale],
|
|
)
|
|
|
|
return (
|
|
<div className="flex">
|
|
<div
|
|
className={`fixed top-32 right-20 z-10 transition-all duration-150 ease-out ${isTocExpanded ? 'w-[280px]' : 'w-11'}`}
|
|
>
|
|
<TocPanel
|
|
toc={toc}
|
|
activeSection={activeSection}
|
|
isTocExpanded={isTocExpanded}
|
|
onToggle={setIsTocExpanded}
|
|
onItemClick={handleTocClick}
|
|
/>
|
|
</div>
|
|
<article className={cn('prose-xl prose', theme === Theme.dark && 'prose-invert')}>
|
|
{TemplateComponent && (
|
|
<TemplateComponent appDetail={appDetail} variables={variables} inputs={inputs} />
|
|
)}
|
|
</article>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
export default Doc
|