chore: AI analysis page

pull/18563/head
keting lu 1 year ago
parent 788f86221d
commit ea9278e29c

@ -0,0 +1,12 @@
'use client'
import WorkflowRunContainer from '@/app/components/runOnce'
const Page = () => {
return (
<div className="w-full h-full overflow-x-auto">
<WorkflowRunContainer />
</div>
)
}
export default Page

@ -0,0 +1,41 @@
'use client'
import React, { useEffect, useState } from 'react'
import TextGeneration from '@/app/components/runOnce/text-generation'
import Loading from '@/app/components/base/loading'
import { useStore as useAppStore } from '@/app/components/app/store'
import { fetchInstalledAppList } from '@/service/explore'
import type { InstalledApp } from '@/models/explore'
import useSWR from 'swr'
import { fetchApiKeysList } from '@/service/apps'
const TextGenerationApp = ({ installedApp }) => {
const { data: apiKeysList } = useSWR({ url: `/apps/${installedApp.app.id}/api-keys`, params: {} }, fetchApiKeysList)
return apiKeysList?.data?.length > 0 && <TextGeneration isWorkflow isInstalledApp installedAppInfo={installedApp} apiKey={apiKeysList.data[0].token} runOnce/>
}
const WorkflowRunContainer = () => {
const appDetail = useAppStore(state => state.appDetail)!
const [installedApp, setInstalledApp] = useState<InstalledApp>()
const getAppInfo = async () => {
const { installed_apps }: any = await fetchInstalledAppList(appDetail.id) || {}
setInstalledApp(installed_apps?.length > 0 ? installed_apps[0] : null)
}
useEffect(() => {
getAppInfo()
}, [appDetail.id])
if (!installedApp) {
return (
<div className='flex h-full items-center'>
<Loading type='area' />
</div>
)
}
return (
<div className='h-full py-2 pl-0 pr-2 sm:p-2'>
{installedApp.app.mode === 'workflow' && (
<TextGenerationApp installedApp={installedApp}/>
)}
</div>
)
}
export default React.memo(WorkflowRunContainer)

@ -0,0 +1,506 @@
'use client'
import type { FC } from 'react'
import React, { useCallback, useEffect, useRef, useState } from 'react'
import { useTranslation } from 'react-i18next'
import {
RiErrorWarningFill,
} from '@remixicon/react'
import { useBoolean, useClickAway } from 'ahooks'
import { XMarkIcon } from '@heroicons/react/24/outline'
import { usePathname, useRouter, useSearchParams } from 'next/navigation'
import Button from '../../base/button'
import { checkOrSetAccessToken } from '../utils'
import s from './style.module.css'
import ResDownload from './run-batch/res-download'
import cn from '@/utils/classnames'
import useBreakpoints, { MediaType } from '@/hooks/use-breakpoints'
import { fetchSavedMessage as doFetchSavedMessage, fetchAppInfo, fetchAppParams, removeMessage, saveMessage } from '@/service/share'
import type { SiteInfo } from '@/models/share'
import type {
MoreLikeThisConfig,
PromptConfig,
SavedMessage,
TextToSpeechConfig,
} from '@/models/debug'
import { changeLanguage } from '@/i18n/i18next-config'
import Loading from '@/app/components/base/loading'
import { userInputsFormToPromptVariables } from '@/utils/model-config'
import Res from '@/app/components/runOnce/text-generation/result'
import type { InstalledApp } from '@/models/explore'
import Toast from '@/app/components/base/toast'
import type { VisionFile, VisionSettings } from '@/types/app'
import { Resolution, TransferMethod } from '@/types/app'
import { useAppFavicon } from '@/hooks/use-app-favicon'
const GROUP_SIZE = 5 // to avoid RPM(Request per minute) limit. The group task finished then the next group.
enum TaskStatus {
pending = 'pending',
running = 'running',
completed = 'completed',
failed = 'failed',
}
type TaskParam = {
inputs: Record<string, any>
}
type Task = {
id: number
status: TaskStatus
params: TaskParam
}
export type IMainProps = {
isInstalledApp?: boolean
installedAppInfo?: InstalledApp
isWorkflow?: boolean
apiKey: string
}
const TextGeneration: FC<IMainProps> = ({
isInstalledApp = false,
installedAppInfo,
isWorkflow = false,
apiKey,
}) => {
const { notify } = Toast
const { t } = useTranslation()
const media = useBreakpoints()
const isPC = media === MediaType.pc
const isTablet = media === MediaType.tablet
const isMobile = media === MediaType.mobile
const searchParams = useSearchParams()
const mode = searchParams.get('mode') || 'create'
const [currentTab, setCurrentTab] = useState<string>(
['create', 'batch'].includes(mode) ? mode : 'create',
)
const router = useRouter()
const pathname = usePathname()
const [queryInputs, setQueryInputs] = useState<any>(null)
// Notice this situation isCallBatchAPI but not in batch tab
const [isCallBatchAPI, setIsCallBatchAPI] = useState(false)
const isInBatchTab = currentTab === 'batch'
const [inputs, doSetInputs] = useState<Record<string, any>>({})
const inputsRef = useRef(inputs)
const setInputs = useCallback((newInputs: Record<string, any>) => {
doSetInputs(newInputs)
inputsRef.current = newInputs
}, [])
const [appId, setAppId] = useState<string>('')
const [siteInfo, setSiteInfo] = useState<SiteInfo | null>(null)
const [canReplaceLogo, setCanReplaceLogo] = useState<boolean>(false)
const [promptConfig, setPromptConfig] = useState<PromptConfig | null>(null)
const [moreLikeThisConfig, setMoreLikeThisConfig]
= useState<MoreLikeThisConfig | null>(null)
const [textToSpeechConfig, setTextToSpeechConfig]
= useState<TextToSpeechConfig | null>(null)
// save message
const [savedMessages, setSavedMessages] = useState<SavedMessage[]>([])
const fetchSavedMessage = async () => {
const res: any = await doFetchSavedMessage(
isInstalledApp,
installedAppInfo?.id,
)
setSavedMessages(res.data)
}
const handleSaveMessage = async (messageId: string) => {
await saveMessage(messageId, isInstalledApp, installedAppInfo?.id)
notify({ type: 'success', message: t('common.api.saved') })
fetchSavedMessage()
}
const handleRemoveSavedMessage = async (messageId: string) => {
await removeMessage(messageId, isInstalledApp, installedAppInfo?.id)
notify({ type: 'success', message: t('common.api.remove') })
fetchSavedMessage()
}
// send message task
const [controlSend, setControlSend] = useState(0)
const [controlStopResponding, setControlStopResponding] = useState(0)
const [visionConfig, setVisionConfig] = useState<VisionSettings>({
enabled: false,
number_limits: 2,
detail: Resolution.low,
transfer_methods: [TransferMethod.local_file],
})
const [completionFiles, setCompletionFiles] = useState<VisionFile[]>([])
const handleSend = () => {
setIsCallBatchAPI(false)
setControlSend(Date.now())
// eslint-disable-next-line ts/no-use-before-define
setAllTaskList([]) // clear batch task running status
// eslint-disable-next-line ts/no-use-before-define
showResSidebar()
}
useEffect(() => {
const params = new URLSearchParams(searchParams)
if (params.has('mode')) {
params.delete('mode')
router.replace(`${pathname}?${params.toString()}`)
}
const queryInputs = Object.fromEntries(searchParams.entries())
if (queryInputs) {
setQueryInputs(queryInputs)
setInputs(queryInputs)
// router.replace(pathname)
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [])
useEffect(() => {
if (
queryInputs
&& typeof queryInputs === 'object'
&& Object.keys(queryInputs).length > 0
)
handleSend()
}, [queryInputs])
const [controlRetry, setControlRetry] = useState(0)
const handleRetryAllFailedTask = () => {
setControlRetry(Date.now())
}
const [allTaskList, doSetAllTaskList] = useState<Task[]>([])
const allTaskListRef = useRef<Task[]>([])
const getLatestTaskList = () => allTaskListRef.current
const setAllTaskList = (taskList: Task[]) => {
doSetAllTaskList(taskList)
allTaskListRef.current = taskList
}
const pendingTaskList = allTaskList.filter(
task => task.status === TaskStatus.pending,
)
const noPendingTask = pendingTaskList.length === 0
const showTaskList = allTaskList.filter(
task => task.status !== TaskStatus.pending,
)
const [currGroupNum, doSetCurrGroupNum] = useState(0)
const currGroupNumRef = useRef(0)
const setCurrGroupNum = (num: number) => {
doSetCurrGroupNum(num)
currGroupNumRef.current = num
}
const getCurrGroupNum = () => {
return currGroupNumRef.current
}
const allSuccessTaskList = allTaskList.filter(
task => task.status === TaskStatus.completed,
)
const allFailedTaskList = allTaskList.filter(
task => task.status === TaskStatus.failed,
)
const allTasksFinished = allTaskList.every(
task => task.status === TaskStatus.completed,
)
const allTasksRun = allTaskList.every(task =>
[TaskStatus.completed, TaskStatus.failed].includes(task.status),
)
const [batchCompletionRes, doSetBatchCompletionRes] = useState<
Record<string, string>
>({})
const batchCompletionResRef = useRef<Record<string, string>>({})
const setBatchCompletionRes = (res: Record<string, string>) => {
doSetBatchCompletionRes(res)
batchCompletionResRef.current = res
}
const getBatchCompletionRes = () => batchCompletionResRef.current
const exportRes = allTaskList.map((task) => {
const batchCompletionResLatest = getBatchCompletionRes()
const res: Record<string, string> = {}
const { inputs } = task.params
promptConfig?.prompt_variables.forEach((v) => {
res[v.name] = inputs[v.key]
})
let result = batchCompletionResLatest[task.id]
// task might return multiple fields, should marshal object to string
if (typeof batchCompletionResLatest[task.id] === 'object')
result = JSON.stringify(result)
res[t('share.generation.completionResult')] = result
return res
})
const handleCompleted = (
completionRes: string,
taskId?: number,
isSuccess?: boolean,
) => {
const allTaskListLatest = getLatestTaskList()
const batchCompletionResLatest = getBatchCompletionRes()
const pendingTaskList = allTaskListLatest.filter(
task => task.status === TaskStatus.pending,
)
const runTasksCount
= 1
+ allTaskListLatest.filter(task =>
[TaskStatus.completed, TaskStatus.failed].includes(task.status),
).length
const needToAddNextGroupTask
= getCurrGroupNum() !== runTasksCount
&& pendingTaskList.length > 0
&& (runTasksCount % GROUP_SIZE === 0
|| allTaskListLatest.length - runTasksCount < GROUP_SIZE)
// avoid add many task at the same time
if (needToAddNextGroupTask) setCurrGroupNum(runTasksCount)
const nextPendingTaskIds = needToAddNextGroupTask
? pendingTaskList.slice(0, GROUP_SIZE).map(item => item.id)
: []
const newAllTaskList = allTaskListLatest.map((item) => {
if (item.id === taskId) {
return {
...item,
status: isSuccess ? TaskStatus.completed : TaskStatus.failed,
}
}
if (needToAddNextGroupTask && nextPendingTaskIds.includes(item.id)) {
return {
...item,
status: TaskStatus.running,
}
}
return item
})
setAllTaskList(newAllTaskList)
if (taskId) {
setBatchCompletionRes({
...batchCompletionResLatest,
[`${taskId}`]: completionRes,
})
}
}
const fetchInitData = async () => {
if (!isInstalledApp) await checkOrSetAccessToken()
return Promise.all([
isInstalledApp
? {
app_id: installedAppInfo?.id,
site: {
title: installedAppInfo?.app.name,
prompt_public: false,
copyright: '',
icon: installedAppInfo?.app.icon,
icon_background: installedAppInfo?.app.icon_background,
},
plan: 'basic',
}
: fetchAppInfo(),
fetchAppParams(isInstalledApp, installedAppInfo?.id),
!isWorkflow ? fetchSavedMessage() : {},
])
}
useEffect(() => {
(async () => {
const [appData, appParams]: any = await fetchInitData()
const { app_id: appId, site: siteInfo, can_replace_logo } = appData
setAppId(appId)
setSiteInfo(siteInfo as SiteInfo)
setCanReplaceLogo(can_replace_logo)
changeLanguage(siteInfo.default_language)
const {
user_input_form,
more_like_this,
file_upload,
text_to_speech,
}: any = appParams
setVisionConfig({
// legacy of image upload compatible
...file_upload,
transfer_methods:
file_upload.allowed_file_upload_methods
|| file_upload.allowed_upload_methods,
// legacy of image upload compatible
image_file_size_limit:
appParams?.system_parameters?.image_file_size_limit,
fileUploadConfig: appParams?.system_parameters,
})
const prompt_variables = userInputsFormToPromptVariables(user_input_form)
setPromptConfig({
prompt_template: '', // placeholder for future
prompt_variables,
} as PromptConfig)
setMoreLikeThisConfig(more_like_this)
setTextToSpeechConfig(text_to_speech)
})()
}, [])
// Can Use metadata(https://beta.nextjs.org/docs/api-reference/metadata) to set title. But it only works in server side client.
useEffect(() => {
if (siteInfo?.title) {
if (canReplaceLogo) document.title = `${siteInfo.title}`
else document.title = `${siteInfo.title} - Powered by Dify`
}
}, [siteInfo?.title, canReplaceLogo])
useAppFavicon({
enable: !isInstalledApp,
icon_type: siteInfo?.icon_type,
icon: siteInfo?.icon,
icon_background: siteInfo?.icon_background,
icon_url: siteInfo?.icon_url,
})
const [
isShowResSidebar,
{ setTrue: doShowResSidebar, setFalse: hideResSidebar },
] = useBoolean(false)
const showResSidebar = () => {
// fix: useClickAway hideResSidebar will close sidebar
setTimeout(() => {
doShowResSidebar()
}, 0)
}
const resRef = useRef<HTMLDivElement>(null)
useClickAway(() => {
hideResSidebar()
}, resRef)
const renderRes = (task?: Task) => (
<Res
key={task?.id}
isWorkflow={isWorkflow}
isCallBatchAPI={isCallBatchAPI}
isPC={isPC}
isMobile={isMobile}
isInstalledApp={isInstalledApp}
installedAppInfo={installedAppInfo}
isError={task?.status === TaskStatus.failed}
promptConfig={promptConfig}
moreLikeThisEnabled={!!moreLikeThisConfig?.enabled}
inputs={isCallBatchAPI ? (task as Task).params.inputs : inputs}
controlSend={controlSend}
controlRetry={task?.status === TaskStatus.failed ? controlRetry : 0}
controlStopResponding={controlStopResponding}
onShowRes={showResSidebar}
handleSaveMessage={handleSaveMessage}
taskId={task?.id}
onCompleted={handleCompleted}
visionConfig={visionConfig}
completionFiles={completionFiles}
isShowTextToSpeech={!!textToSpeechConfig?.enabled}
siteInfo={siteInfo}
apiKey={apiKey}
/>
)
const renderBatchRes = () => {
return showTaskList.map(task => renderRes(task))
}
const resWrapClassNames = (() => {
if (isPC) return 'grow h-full'
if (!isShowResSidebar) return 'none'
return cn('fixed z-50 inset-0', isTablet ? 'pl-[128px]' : 'pl-6')
})()
const renderResWrap = (
<div
ref={resRef}
className={cn(
'flex flex-col h-full shrink-0',
isPC ? 'px-5 py-4' : 'bg-gray-50',
isTablet && 'p-6',
isMobile && 'p-4',
)}
>
<>
<div className="flex items-center justify-between shrink-0">
<div className="flex items-center space-x-3">
<div className={s.starIcon}></div>
<div className="text-lg font-semibold text-gray-800">
{t('share.generation.title')}
</div>
</div>
<div className="flex items-center space-x-2">
{allFailedTaskList.length > 0 && (
<div className="flex items-center">
<RiErrorWarningFill className="w-4 h-4 text-[#D92D20]" />
<div className="ml-1 text-[#D92D20]">
{t('share.generation.batchFailed.info', {
num: allFailedTaskList.length,
})}
</div>
<Button
variant="primary"
className="ml-2"
onClick={handleRetryAllFailedTask}
>
{t('share.generation.batchFailed.retry')}
</Button>
<div className="mx-3 w-[1px] h-3.5 bg-gray-200"></div>
</div>
)}
{allSuccessTaskList.length > 0 && (
<ResDownload isMobile={isMobile} values={exportRes} />
)}
{!isPC && (
<div
className="flex items-center justify-center cursor-pointer"
onClick={hideResSidebar}
>
<XMarkIcon className="w-4 h-4 text-gray-800" />
</div>
)}
</div>
</div>
<div className="overflow-hidden grow">
{!isCallBatchAPI ? renderRes() : renderBatchRes()}
{!noPendingTask && (
<div className="mt-4">
<Loading type="area" />
</div>
)}
</div>
</>
</div>
)
if (!appId || !siteInfo || !promptConfig) {
return (
<div className="flex items-center h-screen">
<Loading type="app" />
</div>
)
}
return (
<>
<div
className={cn(
isPC && 'flex',
isInstalledApp ? s.installedApp : 'h-screen',
// 'bg-gray-50',
)}
>
{/* Left */}
{/* Result */}
<div
className={resWrapClassNames}
style={{
background:
!isPC && isShowResSidebar ? 'rgba(35, 56, 118, 0.2)' : 'none',
}}
>
{renderResWrap}
</div>
</div>
</>
)
}
export default TextGeneration

@ -0,0 +1,496 @@
'use client'
import type { FC } from 'react'
import React, { useEffect, useRef, useState } from 'react'
import { useBoolean } from 'ahooks'
import { t } from 'i18next'
import produce from 'immer'
import cn from '@/utils/classnames'
import NoData from '@/app/components/share/text-generation/no-data'
import Toast from '@/app/components/base/toast'
import { sendWorkflowRun, updateFeedback } from '@/service/share'
import type { FeedbackType } from '@/app/components/base/chat/chat/type'
import Loading from '@/app/components/base/loading'
import type { PromptConfig } from '@/models/debug'
import type { InstalledApp } from '@/models/explore'
import type { ModerationService } from '@/models/common'
import { TransferMethod, type VisionFile, type VisionSettings } from '@/types/app'
import { NodeRunningStatus, WorkflowRunningStatus } from '@/app/components/workflow/types'
import type { WorkflowProcess } from '@/app/components/base/chat/types'
import { sleep } from '@/utils'
import type { SiteInfo } from '@/models/share'
import { TEXT_GENERATION_TIMEOUT_MS } from '@/config'
import {
getFilesInLogs,
} from '@/app/components/base/file-uploader/utils'
import TracingPanel from '@/app/components/workflow/run/tracing-panel'
import { useStore } from '@/app/components/app/store'
import CodeEditor from '@/app/components/workflow/nodes/_base/components/editor/code-editor'
import { CodeLanguage } from '@/app/components/workflow/nodes/code/types'
import { throttle } from 'lodash-es'
export type IResultProps = {
isWorkflow: boolean
isCallBatchAPI: boolean
isPC: boolean
isMobile: boolean
isInstalledApp: boolean
installedAppInfo?: InstalledApp
isError: boolean
isShowTextToSpeech: boolean
promptConfig: PromptConfig | null
moreLikeThisEnabled: boolean
inputs: Record<string, any>
controlSend?: number
controlRetry?: number
controlStopResponding?: number
onShowRes: () => void
handleSaveMessage: (messageId: string) => void
taskId?: number
onCompleted: (completionRes: string, taskId?: number, success?: boolean) => void
enableModeration?: boolean
moderationService?: (text: string) => ReturnType<ModerationService>
visionConfig: VisionSettings
completionFiles: VisionFile[]
siteInfo: SiteInfo | null
apiKey: string
}
const Result: FC<IResultProps> = ({
isWorkflow,
isCallBatchAPI,
isPC,
isMobile,
isInstalledApp,
installedAppInfo,
isError,
isShowTextToSpeech,
promptConfig,
moreLikeThisEnabled,
inputs,
controlSend,
controlRetry,
controlStopResponding,
onShowRes,
handleSaveMessage,
taskId,
onCompleted,
visionConfig,
completionFiles,
siteInfo,
apiKey,
}) => {
const appDetail = useStore(state => state.appDetail)!
const [isResponding, { setTrue: setRespondingTrue, setFalse: setRespondingFalse }] = useBoolean(false)
useEffect(() => {
if (controlStopResponding)
setRespondingFalse()
}, [controlStopResponding])
const [completionRes, doSetCompletionRes] = useState<any>('')
const completionResRef = useRef<any>()
const setCompletionRes = (res: any) => {
completionResRef.current = res
doSetCompletionRes(res)
}
const getCompletionRes = () => completionResRef.current
const [workflowProcessData, doSetWorkflowProcessData] = useState<WorkflowProcess>()
const workflowProcessDataRef = useRef<WorkflowProcess>()
const containerRef = useRef<HTMLDivElement>(null)
const bottomRef = useRef<HTMLDivElement>(null)
const renderRef = useRef<HTMLDivElement>(null)
const [isAtBottom, setIsAtBottom] = useState(true)
const isInitialMount = useRef(true)
const setWorkflowProcessData = (data: WorkflowProcess) => {
workflowProcessDataRef.current = data
if(isAtBottom) bottomRef.current?.scrollIntoView({ behavior: 'smooth' })
doSetWorkflowProcessData(data)
}
const getWorkflowProcessData = () => workflowProcessDataRef.current
const { notify } = Toast
const isNoData = !completionRes
const [messageId, setMessageId] = useState<string | null>(null)
const [feedback, setFeedback] = useState<FeedbackType>({
rating: null,
})
const handleFeedback = async (feedback: FeedbackType) => {
await updateFeedback({ url: `/messages/${messageId}/feedbacks`, body: { rating: feedback.rating } }, isInstalledApp, installedAppInfo?.id)
setFeedback(feedback)
}
const logError = (message: string) => {
notify({ type: 'error', message })
}
const checkCanSend = () => {
// batch will check outer
if (isCallBatchAPI)
return true
const prompt_variables = promptConfig?.prompt_variables
if (!prompt_variables || prompt_variables?.length === 0) {
if (completionFiles.find(item => item.transfer_method === TransferMethod.local_file && !item.upload_file_id)) {
notify({ type: 'info', message: t('appDebug.errorMessage.waitForFileUpload') })
return false
}
return true
}
let hasEmptyInput = ''
const requiredVars = prompt_variables?.filter(({ key, name, required }) => {
const res = (!key || !key.trim()) || (!name || !name.trim()) || (required || required === undefined || required === null)
return res
}) || [] // compatible with old version
requiredVars.forEach(({ key, name }) => {
if (hasEmptyInput)
return
if (!inputs[key])
hasEmptyInput = name
})
if (hasEmptyInput) {
logError(t('appDebug.errorMessage.valueOfVarRequired', { key: hasEmptyInput }))
return false
}
if (completionFiles.find(item => item.transfer_method === TransferMethod.local_file && !item.upload_file_id)) {
notify({ type: 'info', message: t('appDebug.errorMessage.waitForFileUpload') })
return false
}
return !hasEmptyInput
}
const handleSend = async () => {
if (isResponding) {
notify({ type: 'info', message: t('appDebug.errorMessage.waitForResponse') })
return false
}
if (!checkCanSend())
return
const data: Record<string, any> = {
inputs,
}
if (visionConfig.enabled && completionFiles && completionFiles?.length > 0) {
data.files = completionFiles.map((item) => {
if (item.transfer_method === TransferMethod.local_file) {
return {
...item,
url: '',
}
}
return item
})
}
setMessageId(null)
setFeedback({
rating: null,
})
setCompletionRes('')
const res: string[] = []
let tempMessageId = ''
if (!isPC)
onShowRes()
setRespondingTrue()
let isEnd = false
let isTimeout = false;
(async () => {
await sleep(TEXT_GENERATION_TIMEOUT_MS)
if (!isEnd) {
setRespondingFalse()
onCompleted(getCompletionRes(), taskId, false)
isTimeout = true
}
})()
data.user = 'test'
if (isWorkflow) {
sendWorkflowRun(
data,
{
onWorkflowStarted: ({ workflow_run_id }) => {
tempMessageId = workflow_run_id
setWorkflowProcessData({
status: WorkflowRunningStatus.Running,
tracing: [],
expand: false,
resultText: '',
})
},
onIterationStart: ({ data }) => {
setWorkflowProcessData(produce(getWorkflowProcessData()!, (draft) => {
draft.expand = true
draft.tracing!.push({
...data,
status: NodeRunningStatus.Running,
expand: true,
} as any)
}))
},
onIterationNext: () => {
setWorkflowProcessData(produce(getWorkflowProcessData()!, (draft) => {
draft.expand = true
const iterations = draft.tracing.find(item => item.node_id === data.node_id
&& (item.execution_metadata?.parallel_id === data.execution_metadata?.parallel_id || item.parallel_id === data.execution_metadata?.parallel_id))!
iterations?.details!.push([])
}))
},
onIterationFinish: ({ data }) => {
setWorkflowProcessData(produce(getWorkflowProcessData()!, (draft) => {
draft.expand = true
const iterationsIndex = draft.tracing.findIndex(item => item.node_id === data.node_id
&& (item.execution_metadata?.parallel_id === data.execution_metadata?.parallel_id || item.parallel_id === data.execution_metadata?.parallel_id))!
draft.tracing[iterationsIndex] = {
...data,
expand: !!data.error,
} as any
}))
},
onNodeStarted: ({ data }) => {
if (data.iteration_id)
return
setWorkflowProcessData(produce(getWorkflowProcessData()!, (draft) => {
draft.expand = true
draft.tracing!.push({
...data,
status: NodeRunningStatus.Running,
expand: true,
} as any)
}))
},
onNodeFinished: ({ data }) => {
if (data.iteration_id)
return
setWorkflowProcessData(produce(getWorkflowProcessData()!, (draft) => {
const currentIndex = draft.tracing!.findIndex(trace => trace.node_id === data.node_id
&& (trace.execution_metadata?.parallel_id === data.execution_metadata?.parallel_id || trace.parallel_id === data.execution_metadata?.parallel_id))
if (currentIndex > -1 && draft.tracing) {
draft.tracing[currentIndex] = {
...(draft.tracing[currentIndex].extras
? { extras: draft.tracing[currentIndex].extras }
: {}),
...data,
expand: !!data.error,
} as any
}
}))
},
onWorkflowFinished: ({ data }) => {
if (isTimeout) {
notify({ type: 'warning', message: t('appDebug.warningMessage.timeoutExceeded') })
return
}
if (data.error) {
notify({ type: 'error', message: data.error })
setWorkflowProcessData(produce(getWorkflowProcessData()!, (draft) => {
draft.status = WorkflowRunningStatus.Failed
}))
setRespondingFalse()
onCompleted(getCompletionRes(), taskId, false)
isEnd = true
return
}
setWorkflowProcessData(produce(getWorkflowProcessData()!, (draft) => {
draft.status = WorkflowRunningStatus.Succeeded
draft.files = getFilesInLogs(data.outputs || []) as any[]
}))
if (!data.outputs) {
setCompletionRes('')
}
else {
setCompletionRes(data.outputs)
const isStringOutput = Object.keys(data.outputs).length === 1 && typeof data.outputs[Object.keys(data.outputs)[0]] === 'string'
if (isStringOutput) {
setWorkflowProcessData(produce(getWorkflowProcessData()!, (draft) => {
draft.resultText = data.outputs[Object.keys(data.outputs)[0]]
}))
}
}
setRespondingFalse()
setMessageId(tempMessageId)
onCompleted(getCompletionRes(), taskId, true)
isEnd = true
},
onTextChunk: (params) => {
const { data: { text } } = params
setWorkflowProcessData(produce(getWorkflowProcessData()!, (draft) => {
draft.resultText += text
}))
},
onTextReplace: (params) => {
const { data: { text } } = params
setWorkflowProcessData(produce(getWorkflowProcessData()!, (draft) => {
draft.resultText = text
}))
},
},
isInstalledApp,
apiKey,
)
}
}
const controlSendRef = useRef<number | undefined>()
const [controlClearMoreLikeThis, setControlClearMoreLikeThis] = useState(0)
useEffect(() => {
if (controlSend && controlSendRef?.current !== controlSend) {
controlSendRef.current = controlSend
handleSend()
setControlClearMoreLikeThis(Date.now())
}
}, [controlSend])
useEffect(() => {
if (controlRetry)
handleSend()
}, [controlRetry])
useEffect(() => {
const el = containerRef.current
if (!el) return
const handleScroll = throttle(() => {
const distanceToBottom = el.scrollHeight - el.scrollTop - el.clientHeight
console.log('1', el.scrollHeight, el.scrollTop, el.clientHeight)
console.log('renderRef', renderRef.current?.scrollHeight, renderRef.current?.scrollTop, renderRef.current?.clientHeight)
const atBottom = distanceToBottom <= 200 // 缓冲 20px 容错
setIsAtBottom(atBottom)
}, 1000)
const delay = setTimeout(() => {
isInitialMount.current = false
el.addEventListener('scroll', handleScroll)
}, 300) // 避免内容撑开误判
return () => {
clearTimeout(delay)
el.removeEventListener('scroll', handleScroll)
}
}, [])
useEffect(() => {
const el = containerRef.current
if (!el || !isAtBottom) return
let attempts = 0
const maxAttempts = 30 // 最多尝试 30 次,避免死循环
const delayMs = 16 // 每帧尝试(≈ 60fps
const threshold = 10 // 容忍范围内算到底了
const tryScroll = () => {
if (!el) return
const scrollTarget = el.scrollHeight - el.clientHeight
const currentScroll = el.scrollTop
const distance = Math.abs(currentScroll - scrollTarget)
if (distance > threshold && attempts < maxAttempts) {
el.scrollTo({ top: scrollTarget, behavior: 'smooth' })
attempts++
requestAnimationFrame(tryScroll)
}
else {
// 最后再确保锚点视图内
bottomRef.current?.scrollIntoView({ behavior: 'smooth' })
}
}
tryScroll()
}, [workflowProcessData?.tracing, isAtBottom])
useEffect(() => {
}, [renderRef])
const renderTextGenerationRes = () => (
<div className=''
ref={renderRef}
>
<div className='text-right text-sm flex justify-end w-full'>
<div className='bg-background-section-burn py-2 my-2 rounded-lg p-2 max-w-[80%] flex-1'>
{t('run.startAnalysis')}
{inputs && (
<div className={cn('mb-1')}>
<CodeEditor
readOnly
title={<div>{t('workflow.common.input').toLocaleUpperCase()}</div>}
language={CodeLanguage.json}
value={inputs}
isJSONStringifyBeauty
/>
</div>
)}
</div></div>
<div className=' text-sm flex w-full justify-start'>
<div className='bg-background-section-burn py-2 my-2 rounded-lg p-2 max-w-[80%] ' >
{t('run.aiAnalysis')}
</div></div>
<TracingPanel
className='bg-background-section-burn'
list={workflowProcessData?.tracing || []}
isForRun={true}
/>
</div>
// <TextGenerationRes
// isWorkflow={isWorkflow}
// workflowProcessData={workflowProcessData}
// className='mt-3'
// isError={isError}
// onRetry={handleSend}
// content={completionRes}
// messageId={messageId}
// isInWebApp
// moreLikeThis={moreLikeThisEnabled}
// onFeedback={handleFeedback}
// feedback={feedback}
// onSave={handleSaveMessage}
// isMobile={isMobile}
// isInstalledApp={isInstalledApp}
// installedAppId={installedAppInfo?.id}
// isLoading={isCallBatchAPI ? (!completionRes && isResponding) : false}
// taskId={isCallBatchAPI ? ((taskId as number) < 10 ? `0${taskId}` : `${taskId}`) : undefined}
// controlClearMoreLikeThis={controlClearMoreLikeThis}
// isShowTextToSpeech={isShowTextToSpeech}
// hideProcessDetail
// siteInfo={siteInfo}
// />
)
return (
<div className={cn(
isNoData && !isCallBatchAPI && 'h-full',
'overflow-y-auto',
)}
ref={containerRef}
> {
!isCallBatchAPI && isWorkflow && (
(isResponding && !workflowProcessData)
? (
<div className='flex h-full w-full justify-center items-center'>
<Loading type='area' />
</div>
)
: !workflowProcessData
? <NoData />
: renderTextGenerationRes()
)
}
{isCallBatchAPI && (
<div className='mt-2'>
{renderTextGenerationRes()}
</div>
)}
<div ref={bottomRef} />
</div>
)
}
export default React.memo(Result)

@ -0,0 +1,12 @@
.installedApp {
height: 100%;
border-radius: 16px;
box-shadow: 0px 12px 16px -4px rgba(16, 24, 40, 0.08), 0px 4px 6px -2px rgba(16, 24, 40, 0.03);
}
.starIcon {
width: 16px;
height: 16px;
background: url(./icons/star.svg) center center no-repeat;
background-size: contain;
}

@ -0,0 +1,53 @@
import { CONVERSATION_ID_INFO } from '../base/chat/constants'
import { fetchAccessToken } from '@/service/share'
export const checkOrSetAccessToken = async () => {
const sharedToken = globalThis.location.pathname.split('/').slice(-1)[0]
const accessToken = localStorage.getItem('token') || JSON.stringify({ [sharedToken]: '' })
let accessTokenJson = { [sharedToken]: '' }
try {
accessTokenJson = JSON.parse(accessToken)
}
catch (e) {
}
if (!accessTokenJson[sharedToken]) {
const res = await fetchAccessToken(sharedToken)
accessTokenJson[sharedToken] = res.access_token
localStorage.setItem('token', JSON.stringify(accessTokenJson))
}
}
export const setAccessToken = async (sharedToken: string, token: string) => {
const accessToken = localStorage.getItem('token') || JSON.stringify({ [sharedToken]: '' })
let accessTokenJson = { [sharedToken]: '' }
try {
accessTokenJson = JSON.parse(accessToken)
}
catch (e) {
}
localStorage.removeItem(CONVERSATION_ID_INFO)
accessTokenJson[sharedToken] = token
localStorage.setItem('token', JSON.stringify(accessTokenJson))
}
export const removeAccessToken = () => {
const sharedToken = globalThis.location.pathname.split('/').slice(-1)[0]
const accessToken = localStorage.getItem('token') || JSON.stringify({ [sharedToken]: '' })
let accessTokenJson = { [sharedToken]: '' }
try {
accessTokenJson = JSON.parse(accessToken)
}
catch (e) {
}
localStorage.removeItem(CONVERSATION_ID_INFO)
delete accessTokenJson[sharedToken]
localStorage.setItem('token', JSON.stringify(accessTokenJson))
}

@ -183,7 +183,7 @@ const TracingPanel: FC<TracingPanelProps> = ({
return (
<div
className={cn(className || 'bg-components-panel-bg', 'py-2')}
className={cn(className || 'bg-components-panel-bg', 'py-2', 'rounded-lg')}
onClick={(e) => {
e.stopPropagation()
e.nativeEvent.stopImmediatePropagation()

@ -1,3 +1,29 @@
const translation = {}
const translation = {
toolType: {
select: 'APO Auswählen',
analysis: 'APO-Analyse',
},
chart: {
chartTitle: 'Diagramm-Anzeige',
},
displayType: {
memory: 'Metriken für den Arbeitsspeicher',
metric: 'Metrisches Liniendiagramm',
cpu: 'CPU-Metriken',
custom: 'Benutzerdefinierte Abfrage gibt Daten zurück',
alert: 'Warnungsereignisse',
network: 'Netzwerk-Metriken',
topology: 'Struktur der Topologie',
log: 'Log-Daten',
},
tool: {
use: 'Gebrauchen',
desc: 'Beschreibung',
input: 'Eingabe',
output: 'Ausgabe',
unit: 'Einheit',
test: 'Test',
},
}
export default translation

@ -201,6 +201,7 @@ const translation = {
label: 'APP',
noParams: 'Keine Parameter erforderlich',
},
notPublish: 'Dieser Workflow wurde nicht veröffentlicht oder der API-Key wurde nicht erstellt',
}
export default translation

@ -180,6 +180,8 @@ const translation = {
pluginsResult: '{{num}} Ergebnisse',
empower: 'Unterstützen Sie Ihre KI-Entwicklung',
and: 'und',
verifiedTip: 'Verifiziert von Dify',
partnerTip: 'Verifiziert von einem Dify-Partner',
},
task: {
clearAll: 'Alle löschen',

@ -0,0 +1,6 @@
const translation = {
startAnalysis: 'Im Folgenden sind meine Parameter aufgeführt. Bitte helfen Sie mir bei der Analyse.',
aiAnalysis: 'Analysieren starten',
}
export default translation

@ -1,3 +1,37 @@
const translation = {}
const translation = {
daysInWeek: {
Sat: 'Saß',
Sun: 'Sonne',
Thu: 'Do',
Wed: 'Wetten',
Tue: 'Tötet',
Fri: 'Kostenlos',
Mon: 'Mo',
},
months: {
December: 'Dezember',
February: 'Februar',
August: 'August',
June: 'Juni',
March: 'März',
October: 'Oktober',
September: 'September',
January: 'Januar',
July: 'Juli',
May: 'Nähen',
November: 'November',
April: 'April',
},
operation: {
pickDate: 'Datum der Kommissionierung',
cancel: 'Abbrechen',
ok: 'OKAY',
now: 'Jetzt',
},
title: {
pickTime: 'Zeit der Ernte',
},
defaultPlaceholder: 'Wählen Sie eine Zeit...',
}
export default translation

@ -0,0 +1,6 @@
const translation = {
startAnalysis: 'The following are my parameters. Please help me analyze.',
aiAnalysis: 'Start Analyze',
}
export default translation

@ -42,13 +42,13 @@ const translation = {
description: 'Start generating content, and find your saved results here.',
startCreateContent: 'Start create content',
},
title: 'AI Completion',
title: 'AI Analysis',
queryTitle: 'Query content',
completionResult: 'Completion result',
queryPlaceholder: 'Write your query content...',
run: 'Execute',
copy: 'Copy',
resultTitle: 'AI Completion',
resultTitle: 'AI Analysis',
noData: 'AI will give you what you want here.',
csvUploadTitle: 'Drag and drop your CSV file here, or ',
browse: 'browse',

@ -1,3 +1,28 @@
const translation = {}
const translation = {
toolType: {
analysis: 'Análisis APO',
select: 'Selección de APO',
},
chart: {
chartTitle: 'Visualización de gráficos',
},
displayType: {
metric: 'Gráfico de líneas métricas',
custom: 'Datos devueltos de consultas personalizadas',
log: 'Datos de registro',
topology: 'Estructura de la topología',
alert: 'Eventos de alerta',
memory: 'Métricas de memoria',
network: 'Métricas de red',
cpu: 'Métricas de CPU',
},
tool: {
desc: 'Descripción',
use: 'Uso',
output: 'Salida',
test: 'Prueba',
unit: 'Unidad',
},
}
export default translation

@ -194,6 +194,7 @@ const translation = {
noParams: 'No se necesitan parámetros',
params: 'PARÁMETROS DE LA APLICACIÓN',
},
notPublish: 'Este flujo de trabajo no se ha publicado o no se ha creado la clave de API',
}
export default translation

@ -180,6 +180,8 @@ const translation = {
discover: 'Descubrir',
and: 'y',
difyMarketplace: 'Mercado de Dify',
partnerTip: 'Verificado por un socio de Dify',
verifiedTip: 'Verificado por Dify',
},
task: {
installing: 'Instalando plugins {{installingLength}}, 0 hecho.',

@ -0,0 +1,6 @@
const translation = {
startAnalysis: 'Los siguientes son mis parámetros. Por favor, ayúdame a analizar.',
aiAnalysis: 'Iniciar análisis',
}
export default translation

@ -1,3 +1,37 @@
const translation = {}
const translation = {
daysInWeek: {
Thu: 'Jue',
Fri: 'Gratis',
Tue: 'Mata',
Mon: 'Mon',
Sun: 'Sol',
Sat: 'Sábado',
Wed: 'Apostar',
},
months: {
March: 'Marzo',
June: 'Junio',
May: 'Coser',
July: 'Julio',
October: 'Octubre',
November: 'Noviembre',
January: 'Enero',
August: 'Agosto',
April: 'Abril',
December: 'Diciembre',
February: 'Febrero',
September: 'Septiembre',
},
operation: {
pickDate: 'Fecha de selección',
now: 'Ahora',
cancel: 'Cancelar',
ok: 'De acuerdo',
},
title: {
pickTime: 'Hora de selección',
},
defaultPlaceholder: 'Escoge una hora...',
}
export default translation

@ -1,3 +1,29 @@
const translation = {}
const translation = {
toolType: {
analysis: 'تجزیه و تحلیل APO',
select: 'انتخاب APO',
},
chart: {
chartTitle: 'نمایش نمودار',
},
displayType: {
cpu: 'معیارهای CPU',
alert: 'رویدادهای هشدار',
memory: 'معیارهای حافظه',
network: 'معیارهای شبکه',
topology: 'ساختار توپولوژی',
custom: 'داده های بازگرداندن پرس و جو سفارشی',
metric: 'نمودار خط متریک',
log: 'داده های گزارش',
},
tool: {
test: 'آزمون',
use: 'استفاده',
output: 'خروجی',
unit: 'واحد',
desc: 'توضیحات',
input: 'ورودی',
},
}
export default translation

@ -194,6 +194,7 @@ const translation = {
label: 'برنامه',
placeholder: 'برنامه ای را انتخاب کنید...',
},
notPublish: 'این گردش کار منتشر نشده است یا API-Key ایجاد نشده است',
}
export default translation

@ -180,6 +180,8 @@ const translation = {
difyMarketplace: 'بازار دیفی',
empower: 'توسعه هوش مصنوعی خود را توانمند کنید',
discover: 'کشف',
verifiedTip: 'تایید شده توسط Dify',
partnerTip: 'تأیید شده توسط یک شریک Dify',
},
task: {
installing: 'نصب پلاگین های {{installingLength}}، 0 انجام شد.',

@ -0,0 +1,6 @@
const translation = {
startAnalysis: 'پارامترهای زیر عبارتند از. لطفا به من کمک کنید تجزیه و تحلیل.',
aiAnalysis: 'شروع تجزیه و تحلیل',
}
export default translation

@ -1,3 +1,37 @@
const translation = {}
const translation = {
daysInWeek: {
Mon: 'دوشنبه',
Wed: 'شرط',
Tue: 'کشد',
Fri: 'رایگان',
Thu: 'پنج شنبه',
Sat: 'شنبه',
Sun: 'خورشید',
},
months: {
September: 'سپتامبر',
November: 'نوامبر',
March: 'مارس',
August: 'اوت',
June: 'ژوئن',
April: 'آوریل',
December: 'دسامبر',
October: 'اکتبر',
February: 'فوریه',
July: 'ژوئيه',
May: 'دوختن',
January: 'ژانویه',
},
operation: {
now: 'حال حاضر',
ok: 'باشه',
pickDate: 'انتخاب تاریخ',
cancel: 'لغو',
},
title: {
pickTime: 'زمان را انتخاب کنید',
},
defaultPlaceholder: 'زمان را انتخاب کنید...',
}
export default translation

@ -1,3 +1,29 @@
const translation = {}
const translation = {
toolType: {
select: 'Sélection APO',
analysis: 'Analyse de lAPO',
},
chart: {
chartTitle: 'Affichage du graphique',
},
displayType: {
custom: 'Données de retour de requête personnalisées',
alert: 'Événements dalerte',
memory: 'Métriques de mémoire',
topology: 'Structure topologique',
metric: 'Graphique linéaire métrique',
network: 'Métriques réseau',
log: 'Données de journal',
cpu: 'Métriques du processeur',
},
tool: {
input: 'Entrée',
test: 'Test',
unit: 'Unité',
use: 'Utiliser',
output: 'Sortie',
desc: 'Description',
},
}
export default translation

@ -194,6 +194,7 @@ const translation = {
label: 'APPLI',
placeholder: 'Sélectionnez une application...',
},
notPublish: 'Ce workflow na pas été publié ou la clé API na pas été créée',
}
export default translation

@ -180,6 +180,8 @@ const translation = {
difyMarketplace: 'Marché Dify',
empower: 'Renforcez le développement de votre IA',
sortBy: 'Ville noire',
partnerTip: 'Vérifié par un partenaire Dify',
verifiedTip: 'Vérifié par Dify',
},
task: {
installError: '{{errorLength}} les plugins nont pas pu être installés, cliquez pour voir',

@ -0,0 +1,6 @@
const translation = {
startAnalysis: 'Voici mes paramètres. Sil vous plaît, aidez-moi à analyser.',
aiAnalysis: 'Démarrer lanalyse',
}
export default translation

@ -1,3 +1,37 @@
const translation = {}
const translation = {
daysInWeek: {
Mon: 'Lun',
Wed: 'Parier',
Sun: 'Soleil',
Thu: 'jeu',
Tue: 'Tue',
Sat: 'Sam',
Fri: 'Libre',
},
months: {
August: 'Août',
May: 'Coudre',
February: 'Février',
June: 'Juin',
March: 'Mars',
October: 'Octobre',
April: 'Avril',
July: 'Juillet',
November: 'Novembre',
December: 'Décembre',
September: 'Septembre',
January: 'Janvier',
},
operation: {
ok: 'DACCORD',
cancel: 'Annuler',
now: 'Maintenant',
pickDate: 'Choisir la date',
},
title: {
pickTime: 'Heure de sélection',
},
defaultPlaceholder: 'Choisissez un moment...',
}
export default translation

@ -1,3 +1,29 @@
const translation = {}
const translation = {
toolType: {
analysis: 'एपीओ विश्लेषण',
select: 'एपीओ चयन',
},
chart: {
chartTitle: 'चार्ट प्रदर्शन',
},
displayType: {
memory: 'मेमोरी मैट्रिक्स',
network: 'नेटवर्क मैट्रिक्स',
log: 'लॉग डेटा',
custom: 'कस्टम क्वेरी डेटा लौटाएँ',
alert: 'अनुचित घटनाएँ',
cpu: 'सीपीयू मेट्रिक्स',
topology: 'टोपोलॉजी संरचना',
metric: 'मैट्रिक लाइन चार्ट',
},
tool: {
unit: 'इकाई',
desc: 'विवरण',
output: 'आउटपुट',
input: 'इनपुट',
use: 'उपयोग करें',
test: 'परीक्षण',
},
}
export default translation

@ -194,6 +194,7 @@ const translation = {
placeholder: 'एक ऐप चुनें...',
label: 'ऐप',
},
notPublish: 'यह कार्यप्रवाह प्रकाशित नहीं किया गया है या API-K चाबी नहीं बनाई गई है',
}
export default translation

@ -180,6 +180,8 @@ const translation = {
difyMarketplace: 'डिफाई मार्केटप्लेस',
sortBy: 'काला शहर',
discover: 'खोजें',
partnerTip: 'Dify भागीदार द्वारा सत्यापित',
verifiedTip: 'डीफाई द्वारा सत्यापित',
},
task: {
clearAll: 'सभी साफ करें',

@ -0,0 +1,6 @@
const translation = {
startAnalysis: 'निम्नलिखित मेरे पैरामीटर हैं। कृपया मेरी सहायता करें।',
aiAnalysis: 'विश्लेषण शुरू करें',
}
export default translation

@ -1,3 +1,37 @@
const translation = {}
const translation = {
daysInWeek: {
Sat: 'शनिवार',
Sun: 'सूर्य',
Wed: 'बुधवार',
Fri: 'शुक्रवार',
Mon: 'मोन',
Thu: 'गुरुवार',
Tue: 'मंगलवार',
},
months: {
May: 'मई',
September: 'सितंबर',
March: 'मार्च',
November: 'नवंबर',
June: 'जून',
January: 'जनवरी',
December: 'दिसंबर',
August: 'अगस्त',
February: 'फरवरी',
October: 'अक्टूबर',
April: 'अप्रैल',
July: 'जुलाई',
},
operation: {
cancel: 'रद्द करें',
now: 'अब',
ok: 'ठीक है',
pickDate: 'तारीख़ चुनें',
},
title: {
pickTime: 'समय चुनें',
},
defaultPlaceholder: 'एक समय चुनें...',
}
export default translation

@ -32,6 +32,7 @@ const loadLangResources = (lang: string) => ({
pluginTags: require(`./${lang}/plugin-tags`).default,
time: require(`./${lang}/time`).default,
apo: require(`./${lang}/apo`).default,
run: require(`./${lang}/run`).default,
},
})

@ -1,3 +1,29 @@
const translation = {}
const translation = {
toolType: {
select: 'APO Seleziona',
analysis: 'Analisi APO',
},
chart: {
chartTitle: 'Visualizzazione del grafico',
},
displayType: {
alert: 'Eventi di avviso',
memory: 'Metriche di memoria',
metric: 'Grafico a linee metriche',
topology: 'Struttura topologica',
network: 'Metriche di rete',
custom: 'Dati restituiti da query personalizzate',
cpu: 'Metriche della CPU',
log: 'Dati di registro',
},
tool: {
input: 'Immissione',
output: 'Prodotto',
use: 'Usare',
desc: 'Descrizione',
unit: 'Unità',
test: 'Test',
},
}
export default translation

@ -206,6 +206,7 @@ const translation = {
placeholder: 'Seleziona un\'app...',
label: 'APP',
},
notPublish: 'Questo flusso di lavoro non è stato pubblicato o la chiave API non è stata creata',
}
export default translation

@ -180,6 +180,8 @@ const translation = {
sortBy: 'Città nera',
and: 'e',
viewMore: 'Vedi di più',
partnerTip: 'Verificato da un partner Dify',
verifiedTip: 'Verificato da Dify',
},
task: {
clearAll: 'Cancella tutto',

@ -0,0 +1,6 @@
const translation = {
startAnalysis: 'Di seguito sono riportati i miei parametri. Per favore aiutami ad analizzare.',
aiAnalysis: 'Inizia l\'analisi',
}
export default translation

@ -1,3 +1,37 @@
const translation = {}
const translation = {
daysInWeek: {
Wed: 'Scommettere',
Fri: 'Gratuito',
Mon: 'Mon',
Sun: 'Sole',
Sat: 'Sab',
Thu: 'Gio',
Tue: 'Uccide',
},
months: {
April: 'Aprile',
July: 'Luglio',
October: 'Ottobre',
March: 'Marzo',
January: 'Gennaio',
September: 'Settembre',
February: 'Febbraio',
December: 'Dicembre',
November: 'Novembre',
June: 'Giugno',
May: 'Cucire',
August: 'Agosto',
},
operation: {
cancel: 'Annulla',
pickDate: 'Data di prelievo',
now: 'Ora',
ok: 'OK',
},
title: {
pickTime: 'Tempo di prelievo',
},
defaultPlaceholder: 'Scegli un orario...',
}
export default translation

@ -1,3 +1,29 @@
const translation = {}
const translation = {
toolType: {
analysis: 'APO分析',
select: 'APOセレクト',
},
chart: {
chartTitle: 'チャート表示',
},
displayType: {
cpu: 'CPU メトリクス',
custom: 'カスタムクエリの戻りデータ',
memory: 'メモリメトリクス',
topology: 'トポロジー構造',
alert: 'アラートイベント',
log: 'ログデータ',
network: 'ネットワークメトリクス',
metric: '指標折れ線グラフ',
},
tool: {
output: '出力',
test: 'テスト',
unit: 'ユニット',
input: '入力',
desc: '説明',
use: '使う',
},
}
export default translation

@ -195,6 +195,7 @@ const translation = {
noParams: 'パラメータは必要ありません',
placeholder: 'アプリを選択...',
},
notPublish: 'このワークフローは公開されていないか、APIキーが作成されていません。',
}
export default translation

@ -180,6 +180,8 @@ const translation = {
viewMore: 'もっと見る',
discover: '発見する',
empower: 'AI開発を強化する',
verifiedTip: 'Difyによって確認された',
partnerTip: 'Difyのパートナーによって確認済み',
},
task: {
installError: '{{errorLength}} プラグインのインストールに失敗しました。表示するにはクリックしてください。',

@ -0,0 +1,6 @@
const translation = {
startAnalysis: '以下は私のパラメータです。分析を手伝ってください。',
aiAnalysis: '分析を開始する',
}
export default translation

@ -1,3 +1,37 @@
const translation = {}
const translation = {
daysInWeek: {
Wed: '水曜日',
Fri: '自由',
Tue: '火曜日',
Sun: '太陽',
Thu: '木曜日',
Sat: '土曜日',
Mon: 'モン',
},
months: {
February: '2月',
August: '八月',
December: '12月',
May: '5月',
April: '四月',
July: '7月',
November: '11月',
June: '6月',
October: '十月',
March: '3月',
September: '9月',
January: '1月',
},
operation: {
cancel: 'キャンセル',
ok: 'はい',
now: '今',
pickDate: '日付を選択',
},
title: {
pickTime: 'ピックタイム',
},
defaultPlaceholder: '時間を選んでください...',
}
export default translation

@ -1,3 +1,29 @@
const translation = {}
const translation = {
toolType: {
analysis: 'APO 분석',
select: 'APO 선택',
},
chart: {
chartTitle: '차트 표시',
},
displayType: {
network: '네트워크 메트릭',
custom: '사용자 지정 쿼리는 데이터를 반환합니다.',
metric: '미터법 꺾은선형 차트',
log: '로그 데이터',
memory: '메모리 메트릭',
topology: '토폴로지 구조',
cpu: 'CPU 메트릭',
alert: '경고 이벤트',
},
tool: {
input: '입력',
desc: '묘사',
unit: '단위',
test: '테스트',
output: '출력',
use: '쓰다',
},
}
export default translation

@ -190,6 +190,7 @@ const translation = {
label: '앱',
placeholder: '앱 선택...',
},
notPublish: '이 워크플로가 게시되지 않았거나 API 키가 만들어지지 않았습니다.',
}
export default translation

@ -180,6 +180,8 @@ const translation = {
moreFrom: 'Marketplace에서 더 보기',
sortBy: '블랙 시티',
and: '그리고',
verifiedTip: 'Dify에 의해 확인',
partnerTip: 'Dify 파트너에 의한 검증',
},
task: {
installingWithSuccess: '{{installingLength}} 플러그인 설치, {{successLength}} 성공.',

@ -0,0 +1,6 @@
const translation = {
startAnalysis: '다음은 내 매개 변수입니다. 분석하도록 도와주세요.',
aiAnalysis: '분석 시작',
}
export default translation

@ -1,3 +1,37 @@
const translation = {}
const translation = {
daysInWeek: {
Wed: '걸다',
Fri: '무료',
Tue: '죽이고',
Sat: '토',
Thu: '목',
Sun: '태양',
Mon: '월',
},
months: {
January: '1월',
February: '2월',
August: '8월',
May: '꿰매다',
September: '9월',
March: '3월',
June: '6월',
October: '10월',
December: '12월',
July: '7월',
November: '11월',
April: '4월',
},
operation: {
pickDate: '날짜 선택',
now: '지금',
cancel: '취소',
ok: '그래',
},
title: {
pickTime: '픽 타임',
},
defaultPlaceholder: '시간 선택...',
}
export default translation

@ -1,3 +1,29 @@
const translation = {}
const translation = {
toolType: {
select: 'APO Wybierz',
analysis: 'Analiza APO',
},
chart: {
chartTitle: 'Wyświetlanie wykresów',
},
displayType: {
log: 'Dane dziennika',
topology: 'Struktura topologii',
metric: 'Metryczny wykres liniowy',
network: 'Metryki sieci',
memory: 'Metryki pamięci',
cpu: 'Metryki procesora CPU',
alert: 'Zdarzenia alertów',
custom: 'Niestandardowe dane zwracane przez zapytanie',
},
tool: {
unit: 'Jednostka',
use: 'Używać',
input: 'Wkład',
output: 'Wyjście',
test: 'Test',
desc: 'Opis',
},
}
export default translation

@ -201,6 +201,7 @@ const translation = {
placeholder: 'Wybierz aplikację...',
label: 'Aplikacja',
},
notPublish: 'Ten przepływ pracy nie został opublikowany lub klucz interfejsu API nie został utworzony',
}
export default translation

@ -180,6 +180,8 @@ const translation = {
difyMarketplace: 'Rynek Dify',
noPluginFound: 'Nie znaleziono wtyczki',
pluginsResult: '{{num}} wyniki',
verifiedTip: 'Zweryfikowane przez Dify',
partnerTip: 'Zweryfikowane przez partnera Dify',
},
task: {
installError: 'Nie udało się zainstalować wtyczek {{errorLength}}, kliknij, aby wyświetlić',

@ -0,0 +1,6 @@
const translation = {
startAnalysis: 'Poniżej znajdują się moje parametry. Proszę o pomoc w analizie.',
aiAnalysis: 'Rozpocznij analizę',
}
export default translation

@ -1,3 +1,37 @@
const translation = {}
const translation = {
daysInWeek: {
Tue: 'Zabija',
Mon: 'Poniedziałek',
Sat: 'Sobota',
Wed: 'Zakład',
Sun: 'Słońce',
Fri: 'Wolny',
Thu: 'czw',
},
months: {
April: 'Kwiecień',
July: 'Lipiec',
March: 'Marzec',
December: 'Grudzień',
June: 'Czerwiec',
November: 'Listopad',
August: 'Sierpień',
May: 'Szyć',
October: 'Październik',
January: 'Styczeń',
February: 'Luty',
September: 'Wrzesień',
},
operation: {
now: 'Teraz',
cancel: 'Anuluj',
pickDate: 'Proszę wybrać datę',
ok: 'OK',
},
title: {
pickTime: 'Czas wyboru',
},
defaultPlaceholder: 'Wybierz czas...',
}
export default translation

@ -1,3 +1,29 @@
const translation = {}
const translation = {
toolType: {
select: 'Seleção de APO',
analysis: 'Análise APO',
},
chart: {
chartTitle: 'Exibição de gráfico',
},
displayType: {
custom: 'Dados de retorno de consulta personalizada',
log: 'Dados de log',
metric: 'Gráfico de linhas métricas',
network: 'Métricas de rede',
alert: 'Eventos de alerta',
topology: 'Estrutura de topologia',
memory: 'Métricas de memória',
cpu: 'Métricas de CPU',
},
tool: {
input: 'Entrada',
desc: 'Descrição',
use: 'Usar',
unit: 'Unidade',
test: 'Teste',
output: 'Saída',
},
}
export default translation

@ -194,6 +194,7 @@ const translation = {
placeholder: 'Selecione um aplicativo...',
params: 'PARÂMETROS DO APLICATIVO',
},
notPublish: 'Este fluxo de trabalho não foi publicado ou a chave de API não foi criada',
}
export default translation

@ -180,6 +180,8 @@ const translation = {
moreFrom: 'Mais do Marketplace',
noPluginFound: 'Nenhum plugin encontrado',
discover: 'Descobrir',
partnerTip: 'Verificado por um parceiro da Dify',
verifiedTip: 'Verificado por Dify',
},
task: {
installedError: 'Falha na instalação dos plug-ins {{errorLength}}',

@ -0,0 +1,6 @@
const translation = {
startAnalysis: 'A seguir estão meus parâmetros. Por favor, ajude-me a analisar.',
aiAnalysis: 'Iniciar análise',
}
export default translation

@ -1,3 +1,37 @@
const translation = {}
const translation = {
daysInWeek: {
Sat: 'Sáb',
Sun: 'Sol',
Fri: 'Livre',
Wed: 'Apostar',
Tue: 'Mata',
Thu: 'Qui',
Mon: 'Seg',
},
months: {
November: 'Novembro',
July: 'Julho',
December: 'Dezembro',
April: 'Abril',
January: 'Janeiro',
February: 'Fevereiro',
March: 'Março',
June: 'Junho',
October: 'Outubro',
September: 'Setembro',
August: 'Agosto',
May: 'Costurar',
},
operation: {
ok: 'OKEY',
now: 'Agora',
pickDate: 'Escolher data',
cancel: 'Cancelar',
},
title: {
pickTime: 'Escolher Tempo',
},
defaultPlaceholder: 'Escolha um horário...',
}
export default translation

@ -1,3 +1,29 @@
const translation = {}
const translation = {
toolType: {
select: 'APO Select',
analysis: 'Analiza APO',
},
chart: {
chartTitle: 'Afișarea graficului',
},
displayType: {
topology: 'Structura topologiei',
log: 'Date de jurnal',
memory: 'Valori de memorie',
alert: 'Evenimente de alertă',
cpu: 'Valori CPU',
metric: 'Diagramă cu linii metrice',
network: 'Valori de rețea',
custom: 'Date de returnare a interogărilor particularizate',
},
tool: {
desc: 'Descriere',
test: 'Testa',
output: 'Ieşire',
unit: 'Unitate',
input: 'Intrare',
use: 'Folosi',
},
}
export default translation

@ -194,6 +194,7 @@ const translation = {
noParams: 'Nu sunt necesari parametri',
placeholder: 'Selectați o aplicație...',
},
notPublish: 'Acest flux de lucru nu a fost publicat sau cheia API nu a fost creată',
}
export default translation

@ -180,6 +180,8 @@ const translation = {
moreFrom: 'Mai multe din Marketplace',
and: 'și',
viewMore: 'Vezi mai mult',
verifiedTip: 'Verificat de Dify',
partnerTip: 'Verificat de un partener Dify',
},
task: {
installError: '{{errorLength}} plugin-urile nu s-au instalat, faceți clic pentru a vizualiza',

@ -0,0 +1,6 @@
const translation = {
startAnalysis: 'Următorii sunt parametrii mei. Vă rog să mă ajutați să analizez.',
aiAnalysis: 'Începeți analiza',
}
export default translation

@ -1,3 +1,37 @@
const translation = {}
const translation = {
daysInWeek: {
Sun: 'Soare',
Sat: 'Sâmbătă',
Mon: 'Luni',
Fri: 'Libera',
Wed: 'Pariu',
Thu: 'Joi',
Tue: 'Ucide',
},
months: {
October: 'Octombrie',
January: 'Ianuarie',
April: 'Aprilie',
June: 'Iunie',
March: 'Martie',
May: 'Coase',
July: 'Iulie',
December: 'Decembrie',
September: 'Septembrie',
February: 'Februarie',
August: 'August',
November: 'Noiembrie',
},
operation: {
cancel: 'Anula',
pickDate: 'Data alegerii',
ok: 'OK',
now: 'Acum',
},
title: {
pickTime: 'Alegere Timp',
},
defaultPlaceholder: 'Alegeți o oră...',
}
export default translation

@ -1,3 +1,29 @@
const translation = {}
const translation = {
toolType: {
select: 'APO Выбор',
analysis: 'Анализ APO',
},
chart: {
chartTitle: 'Отображение диаграмм',
},
displayType: {
metric: 'Метрическая линейная диаграмма',
topology: 'Структура топологии',
cpu: 'Метрики ЦП',
log: 'Данные журнала',
memory: 'Метрики памяти',
network: 'Сетевые метрики',
custom: 'Возвращаемые данные пользовательского запроса',
alert: 'События оповещения',
},
tool: {
desc: 'Описание',
use: 'Использование',
unit: 'Единица',
output: 'Выпуск',
input: 'Ввод',
test: 'Тест',
},
}
export default translation

@ -194,6 +194,7 @@ const translation = {
placeholder: 'Выберите приложение...',
params: 'ПАРАМЕТРЫ ПРИЛОЖЕНИЯ',
},
notPublish: 'Этот рабочий процесс не был опубликован или ключ API не был создан',
}
export default translation

@ -180,6 +180,8 @@ const translation = {
viewMore: 'Подробнее',
and: 'и',
discover: 'Обнаруживать',
verifiedTip: 'Проверено Dify',
partnerTip: 'Проверено партнером Dify',
},
task: {
installing: 'Установка плагинов {{installingLength}}, 0 готово.',

@ -0,0 +1,6 @@
const translation = {
startAnalysis: 'Ниже приведены мои параметры. Пожалуйста, помогите мне проанализировать.',
aiAnalysis: 'Начать анализ',
}
export default translation

@ -1,3 +1,37 @@
const translation = {}
const translation = {
daysInWeek: {
Mon: 'Пн',
Tue: 'Убивает',
Sat: 'Сидеть',
Thu: 'Чт',
Wed: 'Пари',
Sun: 'Солнце',
Fri: 'Свободный',
},
months: {
December: 'Декабрь',
October: 'Октябрь',
July: 'Июль',
May: 'Шить',
November: 'Ноябрь',
February: 'Февраль',
January: 'Январь',
August: 'Август',
March: 'Март',
April: 'Апрель',
June: 'Июнь',
September: 'Сентябрь',
},
operation: {
now: 'Сейчас',
ok: 'ХОРОШО',
cancel: 'Отмена',
pickDate: 'Выбрать дату',
},
title: {
pickTime: 'Время выбора',
},
defaultPlaceholder: 'Выберите время...',
}
export default translation

@ -1,3 +1,29 @@
const translation = {}
const translation = {
toolType: {
analysis: 'Analiza APO',
select: 'Izbira APO',
},
chart: {
chartTitle: 'Prikaz grafikona',
},
displayType: {
topology: 'Struktura topologije',
cpu: 'Meritve CPE-ja',
metric: 'Metrični črtni grafikon',
memory: 'Meritve pomnilnika',
alert: 'Opozorilni dogodki',
network: 'Omrežne meritve',
log: 'Dnevniški podatki',
custom: 'Vrnjeni podatki poizvedbe po meri',
},
tool: {
input: 'Vhodni',
output: 'Izhod',
use: 'Uporabiti',
desc: 'Opis',
unit: 'Enota',
test: 'Preizkus',
},
}
export default translation

@ -194,6 +194,7 @@ const translation = {
label: 'APL',
placeholder: 'Izberite aplikacijo ...',
},
notPublish: 'Ta potek dela ni bil objavljen ali ključ API-ja ni bil ustvarjen',
}
export default translation

@ -0,0 +1,6 @@
const translation = {
startAnalysis: 'Sledijo moji parametri. Prosim, pomagajte mi analizirati.',
aiAnalysis: 'Začnite analizirati',
}
export default translation

@ -1,3 +1,37 @@
const translation = {}
const translation = {
daysInWeek: {
Sun: 'Sonce',
Tue: 'Ubija',
Fri: 'Brezplačno',
Wed: 'Stava',
Thu: 'Čet',
Sat: 'Sedel',
Mon: 'Ponedeljek',
},
months: {
January: 'Januar',
November: 'November',
June: 'Junij',
February: 'Februar',
March: 'Marec',
August: 'Avgust',
October: 'Oktober',
July: 'Julij',
May: 'Šivati',
April: 'April',
December: 'December',
September: 'September',
},
operation: {
cancel: 'Odpovedati',
ok: 'V redu',
now: 'Zdaj',
pickDate: 'Izbira datuma',
},
title: {
pickTime: 'Čas izbire',
},
defaultPlaceholder: 'Izberite čas ...',
}
export default translation

@ -1,3 +1,29 @@
const translation = {}
const translation = {
toolType: {
select: 'เลือก APO',
analysis: 'การวิเคราะห์ APO',
},
chart: {
chartTitle: 'การแสดงแผนภูมิ',
},
displayType: {
custom: 'การส่งคืนข้อมูลแบบสอบถามแบบกําหนดเอง',
alert: 'เหตุการณ์การแจ้งเตือน',
memory: 'เมตริกหน่วยความจํา',
log: 'ข้อมูลบันทึก',
cpu: 'ตัวชี้วัด CPU',
metric: 'แผนภูมิเส้นเมตริก',
topology: 'โครงสร้างโทโพโลยี',
network: 'ตัวชี้วัดเครือข่าย',
},
tool: {
output: 'ผลิตภัณฑ์',
unit: 'หน่วย',
desc: 'คำอธิบาย',
use: 'ใช้',
input: 'อินพุต',
test: 'ทดสอบ',
},
}
export default translation

@ -190,6 +190,7 @@ const translation = {
noParams: 'ไม่จําเป็นต้องใช้พารามิเตอร์',
label: 'แอพ',
},
notPublish: 'เวิร์กโฟลว์นี้ยังไม่ได้เผยแพร่หรือยังไม่ได้สร้างคีย์ API',
}
export default translation

@ -180,6 +180,8 @@ const translation = {
noPluginFound: 'ไม่พบปลั๊กอิน',
empower: 'เพิ่มศักยภาพในการพัฒนา AI ของคุณ',
difyMarketplace: 'ตลาด Dify',
partnerTip: 'ตรวจสอบโดยพันธมิตร Dify',
verifiedTip: 'ตรวจสอบโดย Dify',
},
task: {
installing: 'การติดตั้งปลั๊กอิน {{installingLength}} 0 เสร็จแล้ว',

@ -0,0 +1,6 @@
const translation = {
startAnalysis: 'ต่อไปนี้เป็นพารามิเตอร์ของฉัน โปรดช่วยฉันวิเคราะห์',
aiAnalysis: 'เริ่มวิเคราะห์',
}
export default translation

@ -1,3 +1,37 @@
const translation = {}
const translation = {
daysInWeek: {
Sat: 'เสาร์',
Fri: 'ฟรี',
Wed: 'พนัน',
Thu: 'พฤหัสบดี',
Sun: 'พระอาทิตย์',
Mon: 'มอญ',
Tue: 'ฆ่า',
},
months: {
February: 'กุมภาพันธ์',
April: 'เมษายน',
June: 'มิถุนายน',
September: 'กันยายน',
October: 'ตุลาคม',
December: 'ธันวาคม',
November: 'พฤศจิกายน',
May: 'เย็บ',
August: 'สิงหาคม',
January: 'มกราคม',
July: 'กรกฎาคม',
March: 'มีนาคม',
},
operation: {
pickDate: 'เลือกวันที่',
ok: 'ตกลง, ได้',
cancel: 'ยกเลิก',
now: 'เดี๋ยวนี้',
},
title: {
pickTime: 'เลือกเวลา',
},
defaultPlaceholder: 'เลือกเวลา...',
}
export default translation

@ -1,3 +1,29 @@
const translation = {}
const translation = {
toolType: {
select: 'APO Seçimi',
analysis: 'APO Analizi',
},
chart: {
chartTitle: 'Grafik Gösterimi',
},
displayType: {
topology: 'Topoloji yapısı',
memory: 'Bellek ölçümleri',
log: 'Günlük verileri',
metric: 'Metrik Çizgi Grafiği',
custom: 'Özel sorgu dönüş verileri',
network: 'Ağ metrikleri',
cpu: 'CPU ölçümleri',
alert: 'Uyarı olayları',
},
tool: {
use: 'Kullanmak',
output: ıktı',
input: 'Girdi',
unit: 'Birim',
test: 'Test',
desc: 'Açıklama',
},
}
export default translation

@ -190,6 +190,7 @@ const translation = {
placeholder: 'Bir uygulama seçin...',
params: 'UYGULAMA PARAMETRELERI',
},
notPublish: 'Bu iş akışı yayımlanmadı veya API Anahtarı oluşturulmadı',
}
export default translation

@ -180,6 +180,8 @@ const translation = {
noPluginFound: 'Eklenti bulunamadı',
viewMore: 'Daha fazla göster',
discover: 'Keşfetmek',
partnerTip: 'Bir Dify ortağı tarafından doğrulandı',
verifiedTip: 'Dify tarafından doğrulandı',
},
task: {
installedError: '{{errorLength}} eklentileri yüklenemedi',

@ -0,0 +1,6 @@
const translation = {
startAnalysis: 'Aşağıdakiler benim parametrelerim. Lütfen analiz etmeme yardım et.',
aiAnalysis: 'Analize Başla',
}
export default translation

@ -1,3 +1,37 @@
const translation = {}
const translation = {
daysInWeek: {
Sat: 'Cumartesi',
Tue: 'Öldürür',
Sun: 'Güneş',
Fri: 'Serbest',
Wed: 'Bahis',
Thu: 'Per',
Mon: 'Pzt',
},
months: {
June: 'Haziran',
March: 'Mart',
October: 'Ekim',
January: 'Ocak',
July: 'Temmuz',
December: 'Aralık',
February: 'Şubat',
November: 'Kasım',
August: 'Ağustos',
September: 'Eylül',
May: 'Dikmek',
April: 'Nisan',
},
operation: {
cancel: 'İptal',
now: 'Şimdi',
pickDate: 'Tarih Seç',
ok: 'TAMAM',
},
title: {
pickTime: 'Seçim Zamanı',
},
defaultPlaceholder: 'Bir zaman seçin...',
}
export default translation

@ -1,3 +1,29 @@
const translation = {}
const translation = {
toolType: {
analysis: 'Аналіз APO',
select: 'Вибір APO',
},
chart: {
chartTitle: 'Відображення діаграми',
},
displayType: {
topology: 'Структура топології',
cpu: 'Метрики ЦП',
metric: 'Діаграма метричних ліній',
log: 'Дані журналу',
network: 'Мережеві метрики',
alert: 'Сповіщення про події',
custom: 'Дані про повернення користувацького запиту',
memory: 'Показники пам\'яті',
},
tool: {
test: 'Тест',
unit: 'Одиниці',
desc: 'Опис',
use: 'Використання',
output: 'Вихід',
input: 'Вводу',
},
}
export default translation

@ -194,6 +194,7 @@ const translation = {
params: 'ПАРАМЕТРИ ПРОГРАМИ',
placeholder: 'Виберіть програму...',
},
notPublish: 'Цей робочий процес не був опублікований або API-ключ не був створений',
}
export default translation

@ -180,6 +180,8 @@ const translation = {
difyMarketplace: 'Dify Marketplace',
viewMore: 'Дивитись більше',
noPluginFound: 'Плагін не знайдено',
verifiedTip: 'Перевірено Dify',
partnerTip: 'Перевірено партнером Dify',
},
task: {
installingWithError: 'Не вдалося встановити плагіни {{installingLength}}, успіх {{successLength}}, {{errorLength}}',

@ -0,0 +1,6 @@
const translation = {
startAnalysis: 'Нижче наведені мої параметри. Допоможіть, будь ласка, проаналізувати.',
aiAnalysis: 'Почати аналізувати',
}
export default translation

@ -1,3 +1,37 @@
const translation = {}
const translation = {
daysInWeek: {
Wed: 'Ставку',
Thu: 'чт',
Tue: 'Вбиває',
Sat: 'Сб',
Mon: 'Пн',
Sun: 'Сонце',
Fri: 'Безкоштовний',
},
months: {
May: 'Шити',
January: 'Січень',
April: 'Квітень',
March: 'Березень',
July: 'Липень',
October: 'Жовтень',
August: 'Серпень',
February: 'Лютий',
November: 'Листопад',
June: 'Червень',
September: 'Вересень',
December: 'Грудень',
},
operation: {
now: 'Зараз',
cancel: 'Скасувати',
ok: 'ГАРАЗД',
pickDate: 'Вибрати дату',
},
title: {
pickTime: 'Час вибору',
},
defaultPlaceholder: 'Виберіть час...',
}
export default translation

@ -1,3 +1,29 @@
const translation = {}
const translation = {
toolType: {
analysis: 'Phân tích APO',
select: 'Chọn APO',
},
chart: {
chartTitle: 'Hiển thị biểu đồ',
},
displayType: {
custom: 'Truy vấn tùy chỉnh trả về dữ liệu',
alert: 'Sự kiện cảnh báo',
topology: 'Cấu trúc cấu trúc liên kết',
memory: 'Số liệu bộ nhớ',
network: 'Chỉ số mạng',
log: 'Dữ liệu nhật ký',
cpu: 'Chỉ số CPU',
metric: 'Biểu đồ đường số liệu',
},
tool: {
desc: 'Sự miêu tả',
use: 'Dùng',
unit: 'Đơn vị',
input: 'Nhập',
output: 'Ra',
test: 'Kiểm tra',
},
}
export default translation

@ -194,6 +194,7 @@ const translation = {
noParams: 'Không cần thông số',
label: 'Ứng dụng',
},
notPublish: 'Quy trình làm việc này chưa được xuất bản hoặc Khóa API chưa được tạo',
}
export default translation

@ -180,6 +180,8 @@ const translation = {
sortBy: 'Thành phố đen',
noPluginFound: 'Không tìm thấy plugin nào',
and: 'và',
partnerTip: 'Được xác minh bởi đối tác Dify',
verifiedTip: 'Xác minh bởi Dify',
},
task: {
installingWithError: 'Cài đặt {{installingLength}} plugins, {{successLength}} thành công, {{errorLength}} không thành công',

@ -0,0 +1,6 @@
const translation = {
startAnalysis: 'Sau đây là các thông số của tôi. Xin hãy giúp tôi phân tích.',
aiAnalysis: 'Bắt đầu phân tích',
}
export default translation

@ -1,3 +1,37 @@
const translation = {}
const translation = {
daysInWeek: {
Sun: 'Mặt trời',
Sat: 'Ngồi',
Fri: 'Tự do',
Tue: 'Giết chết',
Thu: 'Thứ Năm',
Mon: 'Thứ hai',
Wed: 'Cá',
},
months: {
September: 'Tháng 9',
December: 'Tháng 12',
November: 'Tháng 11',
October: 'Tháng 10',
June: 'Tháng 6',
May: 'Tháng 5',
April: 'Tháng 4',
August: 'Tháng 8',
July: 'Tháng 7',
February: 'Tháng hai',
January: 'Tháng 1',
March: 'Tháng 3',
},
operation: {
now: 'Bây giờ',
pickDate: 'Chọn ngày',
cancel: 'Hủy',
ok: 'OK',
},
title: {
pickTime: 'Chọn thời gian',
},
defaultPlaceholder: 'Chọn thời gian...',
}
export default translation

@ -24,7 +24,6 @@ const translation = {
input: '输入',
unit: '单位',
},
}
export default translation

@ -0,0 +1,6 @@
const translation = {
startAnalysis: '以下是我的参数,请帮我分析',
aiAnalysis: '开始执行工作流分析',
}
export default translation

@ -38,13 +38,13 @@ const translation = {
description: '开始生成内容,您可以在这里找到保存的结果。',
startCreateContent: '开始生成内容',
},
title: 'AI 智能书写',
title: 'AI智能分析',
queryTitle: '查询内容',
completionResult: '生成结果',
queryPlaceholder: '请输入文本内容',
run: '运行',
copy: '拷贝',
resultTitle: 'AI 书写',
resultTitle: 'AI智能分析',
noData: 'AI 会在这里给你惊喜。',
csvUploadTitle: '将您的 CSV 文件拖放到此处,或',
browse: '浏览',

@ -26,6 +26,7 @@ const translation = {
now: '此刻',
ok: '确定',
cancel: '取消',
pickDate: '选取日期',
},
title: {
pickTime: '选择时间',

@ -1,3 +1,29 @@
const translation = {}
const translation = {
toolType: {
analysis: 'APO 分析',
select: 'APO 精選',
},
chart: {
chartTitle: '圖表顯示',
},
displayType: {
topology: '拓撲結構',
alert: '警報事件',
log: '日誌數據',
custom: '自訂查詢返回數據',
memory: '記憶體指標',
network: '網路指標',
cpu: 'CPU 指標',
metric: '度量度折線圖',
},
tool: {
input: '輸入',
unit: '單位',
test: '測試',
use: '用',
desc: '描述',
output: '輸出',
},
}
export default translation

@ -193,6 +193,7 @@ const translation = {
params: '應用程式參數',
label: '應用程式',
},
notPublish: '此工作流尚未發佈或尚未創建 API 金鑰',
}
export default translation

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save