mirror of
https://github.com/langgenius/dify.git
synced 2026-06-08 09:27:39 +08:00
chore: split logs and annotations page
This commit is contained in:
@ -67,7 +67,7 @@ const AppDetailLayout: FC<IAppDetailLayoutProps> = (props) => {
|
||||
const res = appDetailRes
|
||||
// redirection
|
||||
const canIEditApp = isCurrentWorkspaceEditor
|
||||
if (!canIEditApp && (pathname.endsWith('configuration') || pathname.endsWith('workflow') || pathname.endsWith('logs'))) {
|
||||
if (!canIEditApp && (pathname.endsWith('configuration') || pathname.endsWith('workflow') || pathname.endsWith('logs') || pathname.endsWith('annotations'))) {
|
||||
router.replace(`/app/${appId}/overview`)
|
||||
return
|
||||
}
|
||||
|
||||
@ -0,0 +1,93 @@
|
||||
import { render, screen } from '@testing-library/react'
|
||||
import AppDetailSection from '../app-detail-section'
|
||||
|
||||
let mockAppMode = 'chat'
|
||||
let mockIsCurrentWorkspaceEditor = true
|
||||
|
||||
vi.mock('@/app/components/app/store', () => ({
|
||||
useStore: (selector: (state: Record<string, unknown>) => unknown) => selector({
|
||||
appDetail: {
|
||||
id: 'app-1',
|
||||
name: 'Test App',
|
||||
mode: mockAppMode,
|
||||
icon: '🤖',
|
||||
icon_type: 'emoji',
|
||||
icon_background: '#fff',
|
||||
},
|
||||
}),
|
||||
}))
|
||||
|
||||
vi.mock('@/context/app-context', () => ({
|
||||
useAppContext: () => ({
|
||||
isCurrentWorkspaceEditor: mockIsCurrentWorkspaceEditor,
|
||||
}),
|
||||
}))
|
||||
|
||||
vi.mock('@/next/navigation', () => ({
|
||||
usePathname: () => '/app/app-1/logs',
|
||||
}))
|
||||
|
||||
vi.mock('../app-info', () => ({
|
||||
AppInfoView: () => <div data-testid="app-info" />,
|
||||
}))
|
||||
|
||||
vi.mock('../app-info/use-app-info-actions', () => ({
|
||||
useAppInfoActions: () => ({}),
|
||||
}))
|
||||
|
||||
vi.mock('../../base/divider', () => ({
|
||||
default: () => <hr />,
|
||||
}))
|
||||
|
||||
vi.mock('../nav-link', () => ({
|
||||
default: ({ name, href }: { name: string, href: string }) => (
|
||||
<a href={href}>{name}</a>
|
||||
),
|
||||
}))
|
||||
|
||||
describe('AppDetailSection', () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks()
|
||||
mockAppMode = 'chat'
|
||||
mockIsCurrentWorkspaceEditor = true
|
||||
})
|
||||
|
||||
// Rendering behavior for app detail navigation entries.
|
||||
describe('Rendering', () => {
|
||||
it('should split logs and annotations into separate navigation links for chat apps', () => {
|
||||
// Arrange
|
||||
mockAppMode = 'chat'
|
||||
|
||||
// Act
|
||||
render(<AppDetailSection />)
|
||||
|
||||
// Assert
|
||||
expect(screen.getByRole('link', { name: 'common.appMenus.logs' })).toHaveAttribute('href', '/app/app-1/logs')
|
||||
expect(screen.getByRole('link', { name: 'common.appMenus.annotations' })).toHaveAttribute('href', '/app/app-1/annotations')
|
||||
})
|
||||
|
||||
it('should only render logs navigation for workflow apps', () => {
|
||||
// Arrange
|
||||
mockAppMode = 'workflow'
|
||||
|
||||
// Act
|
||||
render(<AppDetailSection />)
|
||||
|
||||
// Assert
|
||||
expect(screen.getByRole('link', { name: 'common.appMenus.logs' })).toHaveAttribute('href', '/app/app-1/logs')
|
||||
expect(screen.queryByRole('link', { name: 'common.appMenus.annotations' })).not.toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('should only render logs navigation for completion apps', () => {
|
||||
// Arrange
|
||||
mockAppMode = 'completion'
|
||||
|
||||
// Act
|
||||
render(<AppDetailSection />)
|
||||
|
||||
// Assert
|
||||
expect(screen.getByRole('link', { name: 'common.appMenus.logs' })).toHaveAttribute('href', '/app/app-1/logs')
|
||||
expect(screen.queryByRole('link', { name: 'common.appMenus.annotations' })).not.toBeInTheDocument()
|
||||
})
|
||||
})
|
||||
})
|
||||
@ -6,6 +6,8 @@ import {
|
||||
RiDashboard2Line,
|
||||
RiFileList3Fill,
|
||||
RiFileList3Line,
|
||||
RiStickyNoteFill,
|
||||
RiStickyNoteLine,
|
||||
RiTerminalBoxFill,
|
||||
RiTerminalBoxLine,
|
||||
RiTerminalWindowFill,
|
||||
@ -44,6 +46,7 @@ const AppDetailSection = () => {
|
||||
|
||||
const appId = appDetail.id
|
||||
const isWorkflowApp = appDetail.mode === AppModeEnum.WORKFLOW || appDetail.mode === AppModeEnum.ADVANCED_CHAT
|
||||
const supportsAnnotations = appDetail.mode !== AppModeEnum.WORKFLOW && appDetail.mode !== AppModeEnum.COMPLETION
|
||||
|
||||
return [
|
||||
...(isCurrentWorkspaceEditor
|
||||
@ -63,13 +66,18 @@ const AppDetailSection = () => {
|
||||
},
|
||||
...(isCurrentWorkspaceEditor
|
||||
? [{
|
||||
name: appDetail.mode !== AppModeEnum.WORKFLOW
|
||||
? t('appMenus.logAndAnn', { ns: 'common' })
|
||||
: t('appMenus.logs', { ns: 'common' }),
|
||||
name: t('appMenus.logs', { ns: 'common' }),
|
||||
href: `/app/${appId}/logs`,
|
||||
icon: RiFileList3Line,
|
||||
selectedIcon: RiFileList3Fill,
|
||||
}]
|
||||
}, ...(supportsAnnotations
|
||||
? [{
|
||||
name: t('appMenus.annotations', { ns: 'common' }),
|
||||
href: `/app/${appId}/annotations`,
|
||||
icon: RiStickyNoteLine,
|
||||
selectedIcon: RiStickyNoteFill,
|
||||
}]
|
||||
: [])]
|
||||
: []
|
||||
),
|
||||
{
|
||||
|
||||
@ -211,7 +211,7 @@ describe('NavLink Animation and Layout Issues', () => {
|
||||
expect(linkElement).toHaveClass('text-text-accent-light-mode-only')
|
||||
})
|
||||
|
||||
it('should use pathname when rendered outside the app detail route segment', () => {
|
||||
it('should not mark logs active on the annotations pathname', () => {
|
||||
render(
|
||||
<NavLink
|
||||
{...mockProps}
|
||||
@ -220,6 +220,19 @@ describe('NavLink Animation and Layout Issues', () => {
|
||||
/>,
|
||||
)
|
||||
|
||||
const linkElement = screen.getByRole('link', { name: 'Orchestrate' })
|
||||
expect(linkElement).not.toHaveClass('bg-components-menu-item-bg-active')
|
||||
})
|
||||
|
||||
it('should use pathname to mark annotations active when rendered outside the app detail route segment', () => {
|
||||
render(
|
||||
<NavLink
|
||||
{...mockProps}
|
||||
href="/app/123/annotations"
|
||||
pathname="/app/123/annotations"
|
||||
/>,
|
||||
)
|
||||
|
||||
const linkElement = screen.getByRole('link', { name: 'Orchestrate' })
|
||||
expect(linkElement).toHaveClass('bg-components-menu-item-bg-active')
|
||||
})
|
||||
|
||||
@ -33,14 +33,7 @@ const NavLink = ({
|
||||
pathname,
|
||||
}: NavLinkProps) => {
|
||||
const segment = useSelectedLayoutSegment()
|
||||
const formattedSegment = (() => {
|
||||
let res = pathname ? pathname.toLowerCase().split('/').filter(Boolean).pop() : segment?.toLowerCase()
|
||||
// logs and annotations use the same nav
|
||||
if (res === 'annotations')
|
||||
res = 'logs'
|
||||
|
||||
return res
|
||||
})()
|
||||
const formattedSegment = pathname ? pathname.toLowerCase().split('/').filter(Boolean).pop() : segment?.toLowerCase()
|
||||
const isActive = href.toLowerCase().split('/')?.pop() === formattedSegment
|
||||
const NavIcon = isActive ? iconMap.selected : iconMap.normal
|
||||
|
||||
|
||||
@ -1,18 +1,10 @@
|
||||
import type { App, AppIconType } from '@/types/app'
|
||||
import { render, screen } from '@testing-library/react'
|
||||
import userEvent from '@testing-library/user-event'
|
||||
import { useStore as useAppStore } from '@/app/components/app/store'
|
||||
import { PageType } from '@/app/components/base/features/new-feature-panel/annotation-reply/type'
|
||||
import { AppModeEnum } from '@/types/app'
|
||||
import LogAnnotation from '../index'
|
||||
|
||||
const mockRouterPush = vi.fn()
|
||||
vi.mock('@/next/navigation', () => ({
|
||||
useRouter: () => ({
|
||||
push: mockRouterPush,
|
||||
}),
|
||||
}))
|
||||
|
||||
vi.mock('@/app/components/app/annotation', () => ({
|
||||
default: ({ appDetail }: { appDetail: App }) => (
|
||||
<section aria-label="Annotation log">{appDetail.id}</section>
|
||||
@ -80,7 +72,7 @@ describe('LogAnnotation', () => {
|
||||
expect(screen.getByRole('status')).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('should render log and annotation tabs for non-completion apps', () => {
|
||||
it('should render log content without the old page tabs', () => {
|
||||
// Arrange
|
||||
useAppStore.setState({ appDetail: createMockApp({ mode: AppModeEnum.CHAT }) })
|
||||
|
||||
@ -88,11 +80,12 @@ describe('LogAnnotation', () => {
|
||||
render(<LogAnnotation pageType={PageType.log} />)
|
||||
|
||||
// Assert
|
||||
expect(screen.getByText('appLog.title')).toBeInTheDocument()
|
||||
expect(screen.getByText('appAnnotation.title')).toBeInTheDocument()
|
||||
expect(screen.getByRole('region', { name: 'App log' })).toBeInTheDocument()
|
||||
expect(screen.queryByText('appLog.title')).not.toBeInTheDocument()
|
||||
expect(screen.queryByText('appAnnotation.title')).not.toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('should render only log tab for completion apps', () => {
|
||||
it('should render completion logs without the old page tabs', () => {
|
||||
// Arrange
|
||||
useAppStore.setState({ appDetail: createMockApp({ mode: AppModeEnum.COMPLETION }) })
|
||||
|
||||
@ -100,7 +93,8 @@ describe('LogAnnotation', () => {
|
||||
render(<LogAnnotation pageType={PageType.log} />)
|
||||
|
||||
// Assert
|
||||
expect(screen.getByText('appLog.title')).toBeInTheDocument()
|
||||
expect(screen.getByRole('region', { name: 'App log' })).toBeInTheDocument()
|
||||
expect(screen.queryByText('appLog.title')).not.toBeInTheDocument()
|
||||
expect(screen.queryByText('appAnnotation.title')).not.toBeInTheDocument()
|
||||
})
|
||||
|
||||
@ -143,31 +137,4 @@ describe('LogAnnotation', () => {
|
||||
expect(screen.queryByRole('region', { name: 'App log' })).not.toBeInTheDocument()
|
||||
})
|
||||
})
|
||||
|
||||
// User interaction behavior
|
||||
describe('User Interactions', () => {
|
||||
it('should navigate to annotations when switching from log tab', async () => {
|
||||
// Arrange
|
||||
const user = userEvent.setup()
|
||||
|
||||
// Act
|
||||
render(<LogAnnotation pageType={PageType.log} />)
|
||||
await user.click(screen.getByText('appAnnotation.title'))
|
||||
|
||||
// Assert
|
||||
expect(mockRouterPush).toHaveBeenCalledWith('/app/app-123/annotations')
|
||||
})
|
||||
|
||||
it('should navigate to logs when switching from annotation tab', async () => {
|
||||
// Arrange
|
||||
const user = userEvent.setup()
|
||||
|
||||
// Act
|
||||
render(<LogAnnotation pageType={PageType.annotation} />)
|
||||
await user.click(screen.getByText('appLog.title'))
|
||||
|
||||
// Assert
|
||||
expect(mockRouterPush).toHaveBeenCalledWith('/app/app-123/logs')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@ -1,17 +1,12 @@
|
||||
'use client'
|
||||
import type { FC } from 'react'
|
||||
import { cn } from '@langgenius/dify-ui/cn'
|
||||
import * as React from 'react'
|
||||
import { useMemo } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import Annotation from '@/app/components/app/annotation'
|
||||
import Log from '@/app/components/app/log'
|
||||
import { useStore as useAppStore } from '@/app/components/app/store'
|
||||
import WorkflowLog from '@/app/components/app/workflow-log'
|
||||
import { PageType } from '@/app/components/base/features/new-feature-panel/annotation-reply/type'
|
||||
import Loading from '@/app/components/base/loading'
|
||||
import TabSlider from '@/app/components/base/tab-slider-plain'
|
||||
import { useRouter } from '@/next/navigation'
|
||||
import { AppModeEnum } from '@/types/app'
|
||||
|
||||
type Props = {
|
||||
@ -21,19 +16,8 @@ type Props = {
|
||||
const LogAnnotation: FC<Props> = ({
|
||||
pageType,
|
||||
}) => {
|
||||
const { t } = useTranslation()
|
||||
const router = useRouter()
|
||||
const appDetail = useAppStore(state => state.appDetail)
|
||||
|
||||
const options = useMemo(() => {
|
||||
if (appDetail?.mode === AppModeEnum.COMPLETION)
|
||||
return [{ value: PageType.log, text: t('title', { ns: 'appLog' }) }]
|
||||
return [
|
||||
{ value: PageType.log, text: t('title', { ns: 'appLog' }) },
|
||||
{ value: PageType.annotation, text: t('title', { ns: 'appAnnotation' }) },
|
||||
]
|
||||
}, [appDetail?.mode, t])
|
||||
|
||||
if (!appDetail) {
|
||||
return (
|
||||
<div className="flex h-full items-center justify-center bg-background-body">
|
||||
@ -44,17 +28,7 @@ const LogAnnotation: FC<Props> = ({
|
||||
|
||||
return (
|
||||
<div className="flex h-full flex-col px-6 pt-3">
|
||||
{appDetail.mode !== AppModeEnum.WORKFLOW && (
|
||||
<TabSlider
|
||||
className="shrink-0"
|
||||
value={pageType}
|
||||
onChange={(value) => {
|
||||
router.push(`/app/${appDetail.id}/${value === PageType.log ? 'logs' : 'annotations'}`)
|
||||
}}
|
||||
options={options}
|
||||
/>
|
||||
)}
|
||||
<div className={cn('h-0 grow', appDetail.mode !== AppModeEnum.WORKFLOW && 'mt-3')}>
|
||||
<div className="h-0 grow">
|
||||
{pageType === PageType.log && appDetail.mode !== AppModeEnum.WORKFLOW && (<Log appDetail={appDetail} />)}
|
||||
{pageType === PageType.annotation && (<Annotation appDetail={appDetail} />)}
|
||||
{pageType === PageType.log && appDetail.mode === AppModeEnum.WORKFLOW && (<WorkflowLog appDetail={appDetail} />)}
|
||||
|
||||
@ -98,9 +98,9 @@
|
||||
"apiBasedExtension.title": "توفر ملحقات API إدارة مركزية لواجهة برمجة التطبيقات، مما يبسط التكوين لسهولة الاستخدام عبر تطبيقات Dify.",
|
||||
"apiBasedExtension.type": "النوع",
|
||||
"apiBasedExtensionPage.description": "وسّع قدرات وحدات Dify عبر API — أضف إشرافًا مخصصًا على المحتوى أو أدوات بيانات خارجية إلى تطبيقاتك.",
|
||||
"appMenus.annotations": "التعليقات التوضيحية",
|
||||
"appMenus.apiAccess": "وصول API",
|
||||
"appMenus.apiAccessTip": "يمكن الوصول إلى قاعدة المعرفة هذه عبر واجهة برمجة تطبيقات الخدمة",
|
||||
"appMenus.logAndAnn": "السجلات والتعليقات التوضيحية",
|
||||
"appMenus.logs": "السجلات",
|
||||
"appMenus.overview": "المراقبة",
|
||||
"appMenus.promptEng": "تنسيق",
|
||||
|
||||
@ -98,9 +98,9 @@
|
||||
"apiBasedExtension.title": "API-Erweiterungen bieten zentralisiertes API-Management und vereinfachen die Konfiguration für eine einfache Verwendung in Difys Anwendungen.",
|
||||
"apiBasedExtension.type": "Typ",
|
||||
"apiBasedExtensionPage.description": "Erweitere die Modulfunktionen von Dify per API — füge deinen Apps benutzerdefinierte Inhaltsmoderation oder externe Datentools hinzu.",
|
||||
"appMenus.annotations": "Anmerkungen",
|
||||
"appMenus.apiAccess": "API-Zugriff",
|
||||
"appMenus.apiAccessTip": "Diese Wissensdatenbank ist über die Service-API zugänglich",
|
||||
"appMenus.logAndAnn": "Protokolle & Ank.",
|
||||
"appMenus.logs": "Baumstämme",
|
||||
"appMenus.overview": "Übersicht",
|
||||
"appMenus.promptEng": "Orchestrieren",
|
||||
|
||||
@ -98,9 +98,9 @@
|
||||
"apiBasedExtension.title": "API Extensions provide centralized API management, simplifying configuration for easy use across Dify's applications.",
|
||||
"apiBasedExtension.type": "Type",
|
||||
"apiBasedExtensionPage.description": "Extend Dify's module capabilities via API — add custom content moderation or external data tools to your apps.",
|
||||
"appMenus.annotations": "Annotations",
|
||||
"appMenus.apiAccess": "API Access",
|
||||
"appMenus.apiAccessTip": "This knowledge base is accessible via the Service API",
|
||||
"appMenus.logAndAnn": "Logs & Annotations",
|
||||
"appMenus.logs": "Logs",
|
||||
"appMenus.overview": "Monitoring",
|
||||
"appMenus.promptEng": "Orchestrate",
|
||||
|
||||
@ -98,9 +98,9 @@
|
||||
"apiBasedExtension.title": "Las extensiones basadas en API proporcionan una gestión centralizada de API, simplificando la configuración para su fácil uso en las aplicaciones de Dify.",
|
||||
"apiBasedExtension.type": "Tipo",
|
||||
"apiBasedExtensionPage.description": "Amplía las capacidades de los módulos de Dify mediante API: añade moderación de contenido personalizada o herramientas de datos externas a tus apps.",
|
||||
"appMenus.annotations": "Anotaciones",
|
||||
"appMenus.apiAccess": "Acceso API",
|
||||
"appMenus.apiAccessTip": "Esta base de conocimiento es accesible a través de la API de servicio",
|
||||
"appMenus.logAndAnn": "Registros y Anuncios",
|
||||
"appMenus.logs": "Registros",
|
||||
"appMenus.overview": "Monitoreo",
|
||||
"appMenus.promptEng": "Orquestar",
|
||||
|
||||
@ -98,9 +98,9 @@
|
||||
"apiBasedExtension.title": "افزونههای مبتنی بر API مدیریت متمرکز API را فراهم میکنند و پیکربندی را برای استفاده آسان در برنامههای Dify ساده میکنند.",
|
||||
"apiBasedExtension.type": "نوع",
|
||||
"apiBasedExtensionPage.description": "قابلیتهای ماژولهای Dify را از طریق API گسترش دهید — بازبینی محتوای سفارشی یا ابزارهای داده خارجی را به برنامههای خود اضافه کنید.",
|
||||
"appMenus.annotations": "یادداشتها",
|
||||
"appMenus.apiAccess": "دسترسی API",
|
||||
"appMenus.apiAccessTip": "این پایگاه دانش از طریق API سرویس قابل دسترسی است",
|
||||
"appMenus.logAndAnn": "گزارشها و اعلانات",
|
||||
"appMenus.logs": "گزارشها",
|
||||
"appMenus.overview": "نظارت",
|
||||
"appMenus.promptEng": "هماهنگسازی",
|
||||
|
||||
@ -98,9 +98,9 @@
|
||||
"apiBasedExtension.title": "Les extensions API fournissent une gestion centralisée des API, simplifiant la configuration pour une utilisation facile à travers les applications de Dify.",
|
||||
"apiBasedExtension.type": "Tapez",
|
||||
"apiBasedExtensionPage.description": "Étendez les capacités des modules de Dify via API — ajoutez une modération de contenu personnalisée ou des outils de données externes à vos apps.",
|
||||
"appMenus.annotations": "Annotations",
|
||||
"appMenus.apiAccess": "Accès API",
|
||||
"appMenus.apiAccessTip": "Cette base de connaissances est accessible via l'API de service",
|
||||
"appMenus.logAndAnn": "Journaux & Annonces.",
|
||||
"appMenus.logs": "Journaux",
|
||||
"appMenus.overview": "Surveillance",
|
||||
"appMenus.promptEng": "Orchestrer",
|
||||
|
||||
@ -98,9 +98,9 @@
|
||||
"apiBasedExtension.title": "एपीआई एक्सटेंशन केंद्रीकृत एपीआई प्रबंधन प्रदान करते हैं, जो Dify के अनुप्रयोगों में आसान उपयोग के लिए कॉन्फ़िगरेशन को सरल बनाते हैं।",
|
||||
"apiBasedExtension.type": "प्रकार",
|
||||
"apiBasedExtensionPage.description": "API के ज़रिये Dify की मॉड्यूल क्षमताओं को बढ़ाएँ — अपने ऐप्स में कस्टम कंटेंट मॉडरेशन या बाहरी डेटा टूल जोड़ें।",
|
||||
"appMenus.annotations": "एनोटेशन",
|
||||
"appMenus.apiAccess": "API एक्सेस",
|
||||
"appMenus.apiAccessTip": "यह ज्ञान आधार सेवा API के माध्यम से सुलभ है",
|
||||
"appMenus.logAndAnn": "लॉग्स और घोषणाएँ",
|
||||
"appMenus.logs": "लॉग्स",
|
||||
"appMenus.overview": "निगरानी",
|
||||
"appMenus.promptEng": "समन्वय करें",
|
||||
|
||||
@ -98,9 +98,9 @@
|
||||
"apiBasedExtension.title": "Ekstensi API menyediakan manajemen API terpusat, menyederhanakan konfigurasi agar mudah digunakan di seluruh aplikasi Dify.",
|
||||
"apiBasedExtension.type": "Jenis",
|
||||
"apiBasedExtensionPage.description": "Perluas kemampuan modul Dify melalui API — tambahkan moderasi konten khusus atau alat data eksternal ke aplikasi Anda.",
|
||||
"appMenus.annotations": "Anotasi",
|
||||
"appMenus.apiAccess": "Akses API",
|
||||
"appMenus.apiAccessTip": "Basis pengetahuan ini dapat diakses melalui API layanan",
|
||||
"appMenus.logAndAnn": "Log & Anotasi",
|
||||
"appMenus.logs": "Log",
|
||||
"appMenus.overview": "Pemantauan",
|
||||
"appMenus.promptEng": "Mengatur",
|
||||
|
||||
@ -98,9 +98,9 @@
|
||||
"apiBasedExtension.title": "Le estensioni API forniscono una gestione centralizzata delle API, semplificando la configurazione per un facile utilizzo nelle applicazioni di Dify.",
|
||||
"apiBasedExtension.type": "Tipo",
|
||||
"apiBasedExtensionPage.description": "Estendi le capacità dei moduli di Dify tramite API — aggiungi moderazione dei contenuti personalizzata o strumenti dati esterni alle tue app.",
|
||||
"appMenus.annotations": "Annotazioni",
|
||||
"appMenus.apiAccess": "Accesso API",
|
||||
"appMenus.apiAccessTip": "Questa base di conoscenza è accessibile tramite l'API del servizio",
|
||||
"appMenus.logAndAnn": "Log & Ann.",
|
||||
"appMenus.logs": "Log",
|
||||
"appMenus.overview": "Monitoraggio",
|
||||
"appMenus.promptEng": "Orchestrazione",
|
||||
|
||||
@ -98,9 +98,9 @@
|
||||
"apiBasedExtension.title": "API 拡張機能は、Dify のアプリケーション全体での簡単な使用のための設定を簡素化し、集中的な API 管理を提供します。",
|
||||
"apiBasedExtension.type": "タイプ",
|
||||
"apiBasedExtensionPage.description": "API を通じて Dify のモジュール機能を拡張——カスタムのコンテンツモデレーションや外部データツールをアプリに追加できます。",
|
||||
"appMenus.annotations": "注釈",
|
||||
"appMenus.apiAccess": "API アクセス",
|
||||
"appMenus.apiAccessTip": "このナレッジベースはサービスAPIを介してアクセス可能です",
|
||||
"appMenus.logAndAnn": "ログ&注釈",
|
||||
"appMenus.logs": "ログ",
|
||||
"appMenus.overview": "監視",
|
||||
"appMenus.promptEng": "オーケストレート",
|
||||
|
||||
@ -98,9 +98,9 @@
|
||||
"apiBasedExtension.title": "API 기반 확장은 Dify 애플리케이션 전체에서 간편한 사용을 위한 설정을 단순화하고 집중적인 API 관리를 제공합니다.",
|
||||
"apiBasedExtension.type": "유형",
|
||||
"apiBasedExtensionPage.description": "API를 통해 Dify의 모듈 기능을 확장하고, 앱에 맞춤형 콘텐츠 검수 또는 외부 데이터 도구를 추가하세요.",
|
||||
"appMenus.annotations": "어노테이션",
|
||||
"appMenus.apiAccess": "API 액세스",
|
||||
"appMenus.apiAccessTip": "이 지식 베이스는 서비스 API를 통해 액세스할 수 있습니다",
|
||||
"appMenus.logAndAnn": "로그 및 어노테이션",
|
||||
"appMenus.logs": "로그",
|
||||
"appMenus.overview": "모니터링",
|
||||
"appMenus.promptEng": "오케스트레이트",
|
||||
|
||||
@ -98,9 +98,9 @@
|
||||
"apiBasedExtension.title": "API extensions provide centralized API management, simplifying configuration for easy use across Dify's applications.",
|
||||
"apiBasedExtension.type": "Type",
|
||||
"apiBasedExtensionPage.description": "Breid de modulemogelijkheden van Dify uit via API — voeg aangepaste contentmoderatie of externe datatools toe aan je apps.",
|
||||
"appMenus.annotations": "Annotations",
|
||||
"appMenus.apiAccess": "API Access",
|
||||
"appMenus.apiAccessTip": "This knowledge base is accessible via the Service API",
|
||||
"appMenus.logAndAnn": "Logs & Annotations",
|
||||
"appMenus.logs": "Logs",
|
||||
"appMenus.overview": "Monitoring",
|
||||
"appMenus.promptEng": "Orchestrate",
|
||||
|
||||
@ -98,9 +98,9 @@
|
||||
"apiBasedExtension.title": "Rozszerzenia oparte na interfejsie API zapewniają scentralizowane zarządzanie interfejsami API, upraszczając konfigurację dla łatwego użytkowania w aplikacjach Dify.",
|
||||
"apiBasedExtension.type": "Typ",
|
||||
"apiBasedExtensionPage.description": "Rozszerz możliwości modułów Dify przez API — dodaj do aplikacji niestandardową moderację treści lub zewnętrzne narzędzia danych.",
|
||||
"appMenus.annotations": "Adnotacje",
|
||||
"appMenus.apiAccess": "Dostęp API",
|
||||
"appMenus.apiAccessTip": "Ta baza wiedzy jest dostępna przez API usługi",
|
||||
"appMenus.logAndAnn": "Logi i ogł.",
|
||||
"appMenus.logs": "Logi",
|
||||
"appMenus.overview": "Monitorowanie",
|
||||
"appMenus.promptEng": "Orkiestracja",
|
||||
|
||||
@ -98,9 +98,9 @@
|
||||
"apiBasedExtension.title": "As extensões de API fornecem gerenciamento centralizado de API, simplificando a configuração para uso fácil em todos os aplicativos da Dify.",
|
||||
"apiBasedExtension.type": "Tipo",
|
||||
"apiBasedExtensionPage.description": "Amplie os recursos dos módulos do Dify via API — adicione moderação de conteúdo personalizada ou ferramentas de dados externas aos seus apps.",
|
||||
"appMenus.annotations": "Anotações",
|
||||
"appMenus.apiAccess": "Acesso à API",
|
||||
"appMenus.apiAccessTip": "Esta base de conhecimento é acessível via API de serviço",
|
||||
"appMenus.logAndAnn": "Logs e Anúncios",
|
||||
"appMenus.logs": "Logs",
|
||||
"appMenus.overview": "Monitoramento",
|
||||
"appMenus.promptEng": "Orquestrar",
|
||||
|
||||
@ -98,9 +98,9 @@
|
||||
"apiBasedExtension.title": "Extensiile bazate pe API oferă o gestionare centralizată a API-urilor, simplificând configurația pentru o utilizare ușoară în aplicațiile Dify.",
|
||||
"apiBasedExtension.type": "Tip",
|
||||
"apiBasedExtensionPage.description": "Extinde capabilitățile modulelor Dify prin API — adaugă în aplicații moderare de conținut personalizată sau instrumente externe de date.",
|
||||
"appMenus.annotations": "Anotări",
|
||||
"appMenus.apiAccess": "Acces API",
|
||||
"appMenus.apiAccessTip": "Această bază de cunoștințe este accesibilă prin API-ul serviciului",
|
||||
"appMenus.logAndAnn": "Jurnale și Ann.",
|
||||
"appMenus.logs": "Jurnale",
|
||||
"appMenus.overview": "Monitorizare",
|
||||
"appMenus.promptEng": "Orchestrare",
|
||||
|
||||
@ -98,9 +98,9 @@
|
||||
"apiBasedExtension.title": "API-расширения обеспечивают централизованное управление API, упрощая настройку для удобного использования в приложениях Dify.",
|
||||
"apiBasedExtension.type": "Тип",
|
||||
"apiBasedExtensionPage.description": "Расширяйте возможности модулей Dify через API — добавляйте в приложения собственную модерацию контента или внешние инструменты данных.",
|
||||
"appMenus.annotations": "Аннотации",
|
||||
"appMenus.apiAccess": "Доступ к API",
|
||||
"appMenus.apiAccessTip": "Эта база знаний доступна через API сервиса",
|
||||
"appMenus.logAndAnn": "Журналы и аннотации",
|
||||
"appMenus.logs": "Журналы",
|
||||
"appMenus.overview": "Мониторинг",
|
||||
"appMenus.promptEng": "Оркестрация",
|
||||
|
||||
@ -98,9 +98,9 @@
|
||||
"apiBasedExtension.title": "Razširitve API zagotavljajo centralizirano upravljanje API, kar poenostavlja konfiguracijo za enostavno uporabo v aplikacijah Dify.",
|
||||
"apiBasedExtension.type": "Vrsta",
|
||||
"apiBasedExtensionPage.description": "Razširite zmožnosti modulov Dify prek API-ja — v aplikacije dodajte prilagojeno moderiranje vsebine ali zunanja podatkovna orodja.",
|
||||
"appMenus.annotations": "Opombe",
|
||||
"appMenus.apiAccess": "Dostop do API-ja",
|
||||
"appMenus.apiAccessTip": "Ta baza znanja je dostopna prek API storitve",
|
||||
"appMenus.logAndAnn": "Dnevniki & Ann.",
|
||||
"appMenus.logs": "Dnevniki",
|
||||
"appMenus.overview": "Spremljanje",
|
||||
"appMenus.promptEng": "Orkester",
|
||||
|
||||
@ -98,9 +98,9 @@
|
||||
"apiBasedExtension.title": "ส่วนขยาย API ให้การจัดการ API แบบรวมศูนย์ ทําให้การกําหนดค่าง่ายขึ้นเพื่อให้ใช้งานได้ง่ายในแอปพลิเคชันของ Dify",
|
||||
"apiBasedExtension.type": "ประเภท",
|
||||
"apiBasedExtensionPage.description": "ขยายความสามารถของโมดูล Dify ผ่าน API — เพิ่มการตรวจสอบเนื้อหาแบบกำหนดเองหรือเครื่องมือข้อมูลภายนอกให้แอปของคุณ",
|
||||
"appMenus.annotations": "คำ อธิบาย",
|
||||
"appMenus.apiAccess": "การเข้าถึง API",
|
||||
"appMenus.apiAccessTip": "ฐานความรู้นี้สามารถเข้าถึงได้ผ่าน API บริการ",
|
||||
"appMenus.logAndAnn": "ล็อก & แอน.",
|
||||
"appMenus.logs": "บันทึก",
|
||||
"appMenus.overview": "ตรวจ สอบ",
|
||||
"appMenus.promptEng": "ออเคสตร้า",
|
||||
|
||||
@ -98,9 +98,9 @@
|
||||
"apiBasedExtension.title": "API uzantıları merkezi API yönetimi sağlar, Dify'nin uygulamaları arasında kolay kullanım için yapılandırmayı basitleştirir.",
|
||||
"apiBasedExtension.type": "Tür",
|
||||
"apiBasedExtensionPage.description": "API ile Dify modül yeteneklerini genişletin — uygulamalarınıza özel içerik denetimi veya harici veri araçları ekleyin.",
|
||||
"appMenus.annotations": "Ek Açıklamalar",
|
||||
"appMenus.apiAccess": "API Erişimi",
|
||||
"appMenus.apiAccessTip": "Bu bilgi tabanına Servis API üzerinden erişilebilir",
|
||||
"appMenus.logAndAnn": "Günlükler & Anlamlandırmalar",
|
||||
"appMenus.logs": "Günlükler",
|
||||
"appMenus.overview": "İzleme",
|
||||
"appMenus.promptEng": "Düzenle",
|
||||
|
||||
@ -98,9 +98,9 @@
|
||||
"apiBasedExtension.title": "API-розширення забезпечують централізоване керування API, спрощуючи конфігурацію для зручного використання в різних програмах Dify.",
|
||||
"apiBasedExtension.type": "Тип",
|
||||
"apiBasedExtensionPage.description": "Розширюйте можливості модулів Dify через API — додавайте до застосунків власну модерацію контенту або зовнішні інструменти даних.",
|
||||
"appMenus.annotations": "Анотації",
|
||||
"appMenus.apiAccess": "Доступ до API",
|
||||
"appMenus.apiAccessTip": "Ця база знань доступна через API сервісу",
|
||||
"appMenus.logAndAnn": "Журнали та Повідомлення.",
|
||||
"appMenus.logs": "Журнали",
|
||||
"appMenus.overview": "Моніторинг",
|
||||
"appMenus.promptEng": "Налаштування",
|
||||
|
||||
@ -98,9 +98,9 @@
|
||||
"apiBasedExtension.title": "Các tiện ích API cung cấp quản lý API tập trung, giúp cấu hình dễ dàng sử dụng trên các ứng dụng của Dify.",
|
||||
"apiBasedExtension.type": "Loại",
|
||||
"apiBasedExtensionPage.description": "Mở rộng khả năng mô-đun của Dify qua API — thêm kiểm duyệt nội dung tùy chỉnh hoặc công cụ dữ liệu bên ngoài vào ứng dụng của bạn.",
|
||||
"appMenus.annotations": "Chú thích",
|
||||
"appMenus.apiAccess": "Truy cập API",
|
||||
"appMenus.apiAccessTip": "Cơ sở kiến thức này có thể truy cập qua API dịch vụ",
|
||||
"appMenus.logAndAnn": "Nhật ký & Thông báo",
|
||||
"appMenus.logs": "Nhật ký",
|
||||
"appMenus.overview": "Giám sát",
|
||||
"appMenus.promptEng": "Orchestrate",
|
||||
|
||||
@ -98,9 +98,9 @@
|
||||
"apiBasedExtension.title": "API 扩展提供了一个集中式的 API 管理,在此统一添加 API 配置后,方便在 Dify 上的各类应用中直接使用。",
|
||||
"apiBasedExtension.type": "类型",
|
||||
"apiBasedExtensionPage.description": "通过 API 扩展 Dify 的模块能力——为应用接入自定义内容审核或外部数据工具。",
|
||||
"appMenus.annotations": "标注",
|
||||
"appMenus.apiAccess": "访问 API",
|
||||
"appMenus.apiAccessTip": "此知识库可通过服务 API 访问",
|
||||
"appMenus.logAndAnn": "日志与标注",
|
||||
"appMenus.logs": "日志",
|
||||
"appMenus.overview": "监测",
|
||||
"appMenus.promptEng": "编排",
|
||||
|
||||
@ -98,9 +98,9 @@
|
||||
"apiBasedExtension.title": "API 擴充套件提供了一個集中式的 API 管理,在此統一新增 API 配置後,方便在 Dify 上的各類應用中直接使用。",
|
||||
"apiBasedExtension.type": "型別",
|
||||
"apiBasedExtensionPage.description": "透過 API 擴充 Dify 的模組能力,為應用新增自訂內容審核或外部資料工具。",
|
||||
"appMenus.annotations": "標註",
|
||||
"appMenus.apiAccess": "訪問 API",
|
||||
"appMenus.apiAccessTip": "此知識庫可透過服務 API 訪問",
|
||||
"appMenus.logAndAnn": "日誌與標註",
|
||||
"appMenus.logs": "日誌",
|
||||
"appMenus.overview": "監控",
|
||||
"appMenus.promptEng": "編排",
|
||||
|
||||
Reference in New Issue
Block a user