Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
D
dify
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
ai-tech
dify
Commits
93e2dc4f
Commit
93e2dc4f
authored
Mar 08, 2024
by
JzoNg
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
workflow log result
parent
08d2a427
Changes
10
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
115 additions
and
50 deletions
+115
-50
detail.tsx
web/app/components/app/workflow-log/detail.tsx
+3
-4
index.tsx
web/app/components/app/workflow-log/index.tsx
+2
-5
list.tsx
web/app/components/app/workflow-log/list.tsx
+2
-2
index.tsx
web/app/components/workflow/run/index.tsx
+5
-4
meta.tsx
web/app/components/workflow/run/meta.tsx
+2
-6
result.tsx
web/app/components/workflow/run/result.tsx
+72
-24
status.tsx
web/app/components/workflow/run/status.tsx
+3
-3
tracing.tsx
web/app/components/workflow/run/tracing.tsx
+2
-2
log.ts
web/models/log.ts
+19
-0
log.ts
web/service/log.ts
+5
-0
No files found.
web/app/components/app/workflow-log/detail.tsx
View file @
93e2dc4f
'use client'
import
type
{
FC
}
from
'react'
import
{
useTranslation
}
from
'react-i18next'
import
type
{
App
}
from
'@/types/app'
import
Run
from
'@/app/components/workflow/run'
import
{
XClose
}
from
'@/app/components/base/icons/src/vender/line/general'
type
ILogDetail
=
{
appDetail
:
App
runID
:
string
onClose
:
()
=>
void
}
const
DetailPanel
:
FC
<
ILogDetail
>
=
({
appDetail
,
onClose
})
=>
{
const
DetailPanel
:
FC
<
ILogDetail
>
=
({
runID
,
onClose
})
=>
{
const
{
t
}
=
useTranslation
()
return
(
...
...
@@ -19,7 +18,7 @@ const DetailPanel: FC<ILogDetail> = ({ appDetail, onClose }) => {
<
XClose
className=
'w-4 h-4 text-gray-500'
/>
</
span
>
<
h1
className=
'shrink-0 px-4 py-1 text-md font-semibold text-gray-900'
>
{
t
(
'appLog.runDetail.workflowTitle'
)
}
</
h1
>
<
Run
activeTab=
'
TRACING'
appId=
{
appDetail
.
id
}
></
Run
>
<
Run
activeTab=
'
RESULT'
runID=
{
runID
}
/
>
</
div
>
)
}
...
...
web/app/components/app/workflow-log/index.tsx
View file @
93e2dc4f
...
...
@@ -81,10 +81,7 @@ const Logs: FC<ILogsProps> = ({ appDetail }) => {
return
(
<
div
className=
'flex flex-col h-full'
>
<
h1
className=
'text-md font-semibold text-gray-900'
onClick=
{
()
=>
{
console
.
log
(
1
)
setShowDrawer
(
true
)
}
}
>
{
t
(
'appLog.workflowTitle'
)
}
</
h1
>
<
h1
className=
'text-md font-semibold text-gray-900'
onClick=
{
()
=>
setShowDrawer
(
true
)
}
>
{
t
(
'appLog.workflowTitle'
)
}
</
h1
>
<
p
className=
'flex text-sm font-normal text-gray-500'
>
{
t
(
'appLog.workflowSubtitle'
)
}
</
p
>
<
div
className=
'flex flex-col py-4 flex-1'
>
<
Filter
queryParams=
{
queryParams
}
setQueryParams=
{
setQueryParams
}
/>
...
...
@@ -136,7 +133,7 @@ const Logs: FC<ILogsProps> = ({ appDetail }) => {
footer=
{
null
}
panelClassname=
'mt-16 mx-2 sm:mr-2 mb-3 !p-0 !max-w-[600px] rounded-xl border border-gray-200'
>
<
DetailPanel
onClose=
{
onCloseDrawer
}
appDetail=
{
appDetail
}
/>
<
DetailPanel
onClose=
{
onCloseDrawer
}
runID=
{
'fakerRunID'
}
/>
</
Drawer
>
</
div
>
)
...
...
web/app/components/app/workflow-log/list.tsx
View file @
93e2dc4f
...
...
@@ -95,8 +95,8 @@ const WorkflowAppLogList: FC<ILogs> = ({ logs, appDetail, onRefresh }) => {
key=
{
log
.
id
}
className=
{
`border-b border-gray-200 h-8 hover:bg-gray-50 cursor-pointer ${currentLog?.id !== log.id ? '' : 'bg-gray-50'}`
}
onClick=
{
()
=>
{
setShowDrawer
(
true
)
setCurrentLog
(
log
)
setShowDrawer
(
true
)
}
}
>
<
td
className=
'text-center align-middle'
>
{
!
log
.
read_at
&&
<
span
className=
'inline-block bg-[#3F83F8] h-1.5 w-1.5 rounded'
></
span
>
}
</
td
>
<
td
className=
'w-[160px]'
>
{
dayjs
.
unix
(
log
.
created_at
).
format
(
t
(
'appLog.dateTimeFormat'
)
as
string
)
}
</
td
>
...
...
@@ -124,7 +124,7 @@ const WorkflowAppLogList: FC<ILogs> = ({ logs, appDetail, onRefresh }) => {
footer=
{
null
}
panelClassname=
'mt-16 mx-2 sm:mr-2 mb-3 !p-0 !max-w-[600px] rounded-xl border border-gray-200'
>
<
DetailPanel
onClose=
{
onCloseDrawer
}
appDetail=
{
appDetail
}
/>
<
DetailPanel
onClose=
{
onCloseDrawer
}
runID=
{
currentLog
?.
workflow_run
.
id
||
''
}
/>
</
Drawer
>
</
div
>
)
...
...
web/app/components/workflow/run/index.tsx
View file @
93e2dc4f
...
...
@@ -5,13 +5,14 @@ import { useTranslation } from 'react-i18next'
import
cn
from
'classnames'
import
Result
from
'./result'
import
Tracing
from
'./tracing'
// import type { App } from '@/types/app'
type
RunProps
=
{
activeTab
:
'RESULT'
|
'TRACING'
appId
:
string
runID
:
string
}
const
RunPanel
:
FC
<
RunProps
>
=
({
activeTab
,
appId
})
=>
{
const
RunPanel
:
FC
<
RunProps
>
=
({
activeTab
,
runID
})
=>
{
const
{
t
}
=
useTranslation
()
const
[
currentTab
,
setCurrentTab
]
=
useState
<
string
>
(
activeTab
)
...
...
@@ -36,8 +37,8 @@ const RunPanel: FC<RunProps> = ({ activeTab, appId }) => {
</
div
>
{
/* panel detal */
}
<
div
className=
{
cn
(
'grow bg-white h-0 overflow-y-auto'
,
currentTab
===
'TRACING'
&&
'!bg-gray-50'
)
}
>
{
currentTab
===
'RESULT'
&&
<
Result
/>
}
{
currentTab
===
'TRACING'
&&
<
Tracing
appId=
{
appId
}
/>
}
{
currentTab
===
'RESULT'
&&
<
Result
runID=
{
runID
}
/>
}
{
currentTab
===
'TRACING'
&&
<
Tracing
/>
}
</
div
>
</
div
>
)
...
...
web/app/components/workflow/run/meta.tsx
View file @
93e2dc4f
...
...
@@ -10,8 +10,6 @@ type Props = {
startTime
?:
number
time
?:
number
tokens
?:
number
fee
?:
number
currency
?:
string
steps
?:
number
}
...
...
@@ -21,8 +19,6 @@ const MetaData: FC<Props> = ({
startTime
=
0
,
time
,
tokens
,
fee
=
0
,
currency
=
'USD'
,
steps
=
1
,
})
=>
{
const
{
t
}
=
useTranslation
()
...
...
@@ -55,7 +51,7 @@ const MetaData: FC<Props> = ({
<
div
className=
'my-[5px] w-[88px] h-2 rounded-sm bg-[rgba(0,0,0,0.05)]'
/>
)
}
{
status
!==
'running'
&&
(
<
span
>
{
executor
}
</
span
>
<
span
>
{
executor
||
'N/A'
}
</
span
>
)
}
</
div
>
</
div
>
...
...
@@ -88,7 +84,7 @@ const MetaData: FC<Props> = ({
<
div
className=
'my-[5px] w-[48px] h-2 rounded-sm bg-[rgba(0,0,0,0.05)]'
/>
)
}
{
status
!==
'running'
&&
(
<
span
>
{
`${tokens} Tokens
· ${fee.toLocaleString('en-US', { style: 'currency', currency, minimumFractionDigits: 4 })}
`
}
</
span
>
<
span
>
{
`${tokens} Tokens`
}
</
span
>
)
}
</
div
>
</
div
>
...
...
web/app/components/workflow/run/result.tsx
View file @
93e2dc4f
'use client'
import
type
{
FC
}
from
'react'
// import React, { useState } from 'react'
// import { useTranslation } from 'react-i18next'
// import cn from 'classnames'
import
React
,
{
useEffect
,
useMemo
,
useState
}
from
'react'
import
StatusPanel
from
'./status'
import
MetaData
from
'./meta'
// import Loading from '@/app/components/base/loading'
import
Loading
from
'@/app/components/base/loading'
import
CodeEditor
from
'@/app/components/workflow/nodes/_base/components/editor/code-editor'
import
{
fetchRunDetail
}
from
'@/service/log'
import
{
CodeLanguage
}
from
'@/app/components/workflow/nodes/code/types'
import
type
{
WorkflowRunDetailResponse
}
from
'@/models/log'
import
{
useStore
as
useAppStore
}
from
'@/app/components/app/store'
type
ResultProps
=
{
// appId
: string
runID
:
string
}
const
Result
:
FC
<
ResultProps
>
=
()
=>
{
// const { t } = useTranslation()
// const [currentTab, setCurrentTab] = useState<string>(activeTab)
const
Result
:
FC
<
ResultProps
>
=
({
runID
})
=>
{
const
{
appDetail
}
=
useAppStore
()
const
[
loading
,
setLoading
]
=
useState
<
boolean
>
(
true
)
const
[
runDetail
,
setRunDetail
]
=
useState
<
WorkflowRunDetailResponse
>
()
const
executor
=
useMemo
(()
=>
{
if
(
runDetail
?.
created_by_role
===
'account'
)
return
runDetail
.
created_by_account
?.
name
if
(
runDetail
?.
created_by_role
===
'end_user'
)
return
runDetail
.
created_by_end_user
?.
session_id
return
'N/A'
},
[
runDetail
])
useEffect
(()
=>
{
// fetch data
if
(
appDetail
&&
runID
)
{
setLoading
(
true
)
fetchRunDetail
({
appID
:
appDetail
?.
id
,
runID
,
}).
then
((
res
:
WorkflowRunDetailResponse
)
=>
{
setLoading
(
false
)
setRunDetail
(
res
)
})
}
},
[
appDetail
,
runID
])
if
(
loading
||
!
runDetail
)
{
return
(
<
div
className=
'flex h-full items-center justify-center bg-white'
>
<
Loading
/>
</
div
>
)
}
return
(
<
div
className=
'bg-white py-2'
>
<
div
className=
'px-4 py-2'
>
<
StatusPanel
status=
{
'running'
}
time=
{
0.653
}
tokens=
{
27
}
/>
</
div
>
<
div
className=
'px-4 py-2'
>
<
StatusPanel
status=
{
'succeeded'
}
time=
{
0.653
}
tokens=
{
27
}
/>
</
div
>
<
div
className=
'px-4 py-2'
>
<
StatusPanel
status=
{
'failed'
}
time=
{
0.653
}
tokens=
{
27
}
error=
'Fail message here'
/>
</
div
>
<
div
className=
'px-4 py-2'
>
<
StatusPanel
status=
{
'stopped'
}
time=
{
0.653
}
tokens=
{
27
}
/>
<
StatusPanel
status=
{
runDetail
.
status
}
time=
{
runDetail
.
elapsed_time
}
tokens=
{
runDetail
.
total_tokens
}
error=
{
runDetail
.
error
}
/>
</
div
>
<
div
className=
'px-4 py-2 flex flex-col gap-2'
>
<
div
>
INPUT TODO
</
div
>
<
div
>
OUPUT TODO
</
div
>
{
/* ###TODO### value */
}
<
CodeEditor
readOnly
title=
{
<
div
>
INPUT
</
div
>
}
language=
{
CodeLanguage
.
json
}
value=
{
''
}
onChange=
{
()
=>
{}
}
/>
{
/* ###TODO### value */
}
<
CodeEditor
readOnly
title=
{
<
div
>
OUTPUT
</
div
>
}
language=
{
CodeLanguage
.
json
}
value=
{
''
}
onChange=
{
()
=>
{}
}
/>
</
div
>
<
div
className=
'px-4 py-2'
>
<
div
className=
'h-[0.5px] bg-black opacity-5'
/>
</
div
>
<
div
className=
'px-4 py-2'
>
<
MetaData
status=
{
'running'
}
/>
</
div
>
<
div
className=
'px-4 py-2'
>
<
MetaData
status=
{
'succeeded'
}
executor=
{
'Vince'
}
startTime=
{
1702972783
}
time=
{
0.653
}
tokens=
{
27
}
fee=
{
0.035
}
currency=
{
'USD'
}
steps=
{
7
}
/>
<
MetaData
status=
{
runDetail
.
status
}
executor=
{
executor
}
startTime=
{
runDetail
.
created_at
}
time=
{
runDetail
.
elapsed_time
}
tokens=
{
runDetail
.
total_tokens
}
steps=
{
runDetail
.
total_steps
}
/>
</
div
>
</
div
>
)
...
...
web/app/components/workflow/run/status.tsx
View file @
93e2dc4f
...
...
@@ -26,7 +26,7 @@ const StatusPanel: FC<ResultProps> = ({
status
===
'running'
&&
'!bg-primary-50'
,
status
===
'succeeded'
&&
'!bg-[#ecfdf3]'
,
status
===
'failed'
&&
'!bg-[#fef3f2]'
,
status
===
'stopped'
&&
'!bg-
gray-200
'
,
status
===
'stopped'
&&
'!bg-
[#fffaeb]
'
,
)
}
>
<
div
className=
'flex'
>
...
...
@@ -38,7 +38,7 @@ const StatusPanel: FC<ResultProps> = ({
status
===
'running'
&&
'!text-primary-600'
,
status
===
'succeeded'
&&
'!text-[#039855]'
,
status
===
'failed'
&&
'!text-[#d92d20]'
,
status
===
'stopped'
&&
'!text-
gray-700
'
,
status
===
'stopped'
&&
'!text-
[#f79009]
'
,
)
}
>
{
status
===
'running'
&&
(
...
...
@@ -58,7 +58,7 @@ const StatusPanel: FC<ResultProps> = ({
)
}
{
status
===
'stopped'
&&
(
<>
<
Indicator
color=
{
'
gray
'
}
/>
<
Indicator
color=
{
'
yellow
'
}
/>
<
span
>
STOP
</
span
>
</>
)
}
...
...
web/app/components/workflow/run/tracing.tsx
View file @
93e2dc4f
...
...
@@ -7,7 +7,7 @@ import { BlockEnum } from '../types'
import
NodePanel
from
'./node'
type
TracingProps
=
{
appId
:
string
//
appId: string
}
const
nodeInfoFake
=
{
...
...
@@ -18,7 +18,7 @@ const nodeInfoFake = {
status
:
'succeeded'
,
}
const
Tracing
:
FC
<
TracingProps
>
=
(
{
appId
}
)
=>
{
const
Tracing
:
FC
<
TracingProps
>
=
()
=>
{
const
{
t
}
=
useTranslation
()
const
[
nodeCollapsed
,
setCurrentTab
]
=
useState
<
boolean
>
(
false
)
...
...
web/models/log.ts
View file @
93e2dc4f
...
...
@@ -264,3 +264,22 @@ export type WorkflowLogsRequest = {
page
:
number
limit
:
number
// The default value is 20 and the range is 1-100
}
export
type
WorkflowRunDetailResponse
=
{
id
:
string
sequence_number
:
number
version
:
string
graph
:
any
// TODO
inputs
:
any
// json
status
:
'running'
|
'succeeded'
|
'failed'
|
'stopped'
outputs
?:
any
// json
error
?:
string
elapsed_time
?:
number
total_tokens
?:
number
total_steps
:
number
created_by_role
:
'account'
|
'end_user'
created_by_account
?:
AccountInfo
created_by_end_user
?:
EndUserInfo
created_at
:
number
finished_at
:
number
}
web/service/log.ts
View file @
93e2dc4f
...
...
@@ -17,6 +17,7 @@ import type {
LogMessageFeedbacksResponse
,
WorkflowLogsRequest
,
WorkflowLogsResponse
,
WorkflowRunDetailResponse
,
}
from
'@/models/log'
export
const
fetchConversationList
:
Fetcher
<
ConversationListResponse
,
{
name
:
string
;
appId
:
string
;
params
?:
Record
<
string
,
any
>
}
>
=
({
appId
,
params
})
=>
{
...
...
@@ -63,3 +64,7 @@ export const fetchAnnotationsCount: Fetcher<AnnotationsCountResponse, { url: str
export
const
fetchWorkflowLogs
:
Fetcher
<
WorkflowLogsResponse
,
{
url
:
string
;
params
?:
WorkflowLogsRequest
}
>
=
({
url
,
params
})
=>
{
return
get
<
WorkflowLogsResponse
>
(
url
,
{
params
})
}
export
const
fetchRunDetail
=
({
appID
,
runID
}:
{
appID
:
string
;
runID
:
string
})
=>
{
return
get
<
WorkflowRunDetailResponse
>
(
`/apps/
${
appID
}
/workflow-run/
${
runID
}
`
)
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment