Feat/attachments (#9526)
Co-authored-by: Joel <iamjoel007@gmail.com> Co-authored-by: JzoNg <jzongcode@gmail.com>
This commit is contained in:
3
web/app/components/workflow/run/assets/bg-line-error.svg
Normal file
3
web/app/components/workflow/run/assets/bg-line-error.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg width="368" height="52" viewBox="0 0 368 52" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path opacity="0.5" d="M0 0H368M0 2H368M0 4H368M0 6H368M0 8H368M0 10H368M0 12H368M0 14H368M0 16H368M0 18H368M0 20H368M0 22H368M0 24H368M0 26H368M0 28H368M0 30H368M0 32H368M0 34H368M0 36H368M0 38H368M0 40H368M0 42H368M0 44H368M0 46H368M0 48H368M0 50H368M0 52H368M0 54H368M0 56H368M0 58H368M0 60H368M0 62H368M0 64H368M0 66H368M0 68H368M0 70H368M0 72H368M0 74H368M0 76H368M0 78H368M0 80H368M0 82H368M0 84H368M0 86H368M0 88H368M0 90H368M0 92H368M0 94H368M0 96H368M0 98H368M0 100H368M0 102H368M0 104H368M0 106H368M0 108H368M0 110H368M0 112H368M0 114H368M0 116H368M0 118H368M0 120H368M0 122H368M0 124H368M0 126H368M0 128H368M0 130H368M0 132H368M0 134H368M0 136H368M0 138H368M0 140H368M0 142H368M0 144H368M0 146H368M0 148H368M0 150H368M0 152H368M0 154H368M0 156H368M0 158H368M0 160H368M0 162H368M0 164H368M0 166H368M0 168H368M0 170H368M0 172H368M0 174H368M0 176H368M0 178H368M0 180H368M0 182H368M0 184H368M0 186H368M0 188H368M0 190H368M0 192H368M0 194H368M0 196H368M0 198H368M0 200H368M0 202H368M0 204H368M0 206H368M0 208H368M0 210H368M0 212H368M0 214H368M0 216H368M0 218H368M0 220H368M0 222H368M0 224H368M0 226H368" stroke="#F04438" stroke-opacity="0.3" stroke-width="0.5"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.2 KiB |
@@ -0,0 +1,3 @@
|
||||
<svg width="368" height="52" viewBox="0 0 368 52" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path opacity="0.5" d="M0 0.5H368M0 2.5H368M0 4.5H368M0 6.5H368M0 8.5H368M0 10.5H368M0 12.5H368M0 14.5H368M0 16.5H368M0 18.5H368M0 20.5H368M0 22.5H368M0 24.5H368M0 26.5H368M0 28.5H368M0 30.5H368M0 32.5H368M0 34.5H368M0 36.5H368M0 38.5H368M0 40.5H368M0 42.5H368M0 44.5H368M0 46.5H368M0 48.5H368M0 50.5H368M0 52.5H368M0 54.5H368M0 56.5H368M0 58.5H368M0 60.5H368M0 62.5H368M0 64.5H368M0 66.5H368M0 68.5H368M0 70.5H368M0 72.5H368M0 74.5H368M0 76.5H368M0 78.5H368M0 80.5H368M0 82.5H368M0 84.5H368M0 86.5H368M0 88.5H368M0 90.5H368M0 92.5H368M0 94.5H368M0 96.5H368M0 98.5H368M0 100.5H368M0 102.5H368M0 104.5H368M0 106.5H368M0 108.5H368M0 110.5H368M0 112.5H368M0 114.5H368M0 116.5H368M0 118.5H368M0 120.5H368M0 122.5H368M0 124.5H368M0 126.5H368M0 128.5H368M0 130.5H368M0 132.5H368M0 134.5H368M0 136.5H368M0 138.5H368M0 140.5H368M0 142.5H368M0 144.5H368M0 146.5H368M0 148.5H368M0 150.5H368M0 152.5H368M0 154.5H368M0 156.5H368M0 158.5H368M0 160.5H368M0 162.5H368M0 164.5H368M0 166.5H368M0 168.5H368M0 170.5H368M0 172.5H368M0 174.5H368M0 176.5H368M0 178.5H368M0 180.5H368M0 182.5H368M0 184.5H368M0 186.5H368M0 188.5H368M0 190.5H368M0 192.5H368M0 194.5H368M0 196.5H368M0 198.5H368M0 200.5H368M0 202.5H368M0 204.5H368M0 206.5H368M0 208.5H368M0 210.5H368M0 212.5H368M0 214.5H368M0 216.5H368M0 218.5H368M0 220.5H368M0 222.5H368M0 224.5H368M0 226.5H368" stroke="#0BA5EC" stroke-opacity="0.3" stroke-width="0.5"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.5 KiB |
@@ -0,0 +1,3 @@
|
||||
<svg width="368" height="52" viewBox="0 0 368 52" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path opacity="0.5" d="M0 0H368M0 2H368M0 4H368M0 6H368M0 8H368M0 10H368M0 12H368M0 14H368M0 16H368M0 18H368M0 20H368M0 22H368M0 24H368M0 26H368M0 28H368M0 30H368M0 32H368M0 34H368M0 36H368M0 38H368M0 40H368M0 42H368M0 44H368M0 46H368M0 48H368M0 50H368M0 52H368M0 54H368M0 56H368M0 58H368M0 60H368M0 62H368M0 64H368M0 66H368M0 68H368M0 70H368M0 72H368M0 74H368M0 76H368M0 78H368M0 80H368M0 82H368M0 84H368M0 86H368M0 88H368M0 90H368M0 92H368M0 94H368M0 96H368M0 98H368M0 100H368M0 102H368M0 104H368M0 106H368M0 108H368M0 110H368M0 112H368M0 114H368M0 116H368M0 118H368M0 120H368M0 122H368M0 124H368M0 126H368M0 128H368M0 130H368M0 132H368M0 134H368M0 136H368M0 138H368M0 140H368M0 142H368M0 144H368M0 146H368M0 148H368M0 150H368M0 152H368M0 154H368M0 156H368M0 158H368M0 160H368M0 162H368M0 164H368M0 166H368M0 168H368M0 170H368M0 172H368M0 174H368M0 176H368M0 178H368M0 180H368M0 182H368M0 184H368M0 186H368M0 188H368M0 190H368M0 192H368M0 194H368M0 196H368M0 198H368M0 200H368M0 202H368M0 204H368M0 206H368M0 208H368M0 210H368M0 212H368M0 214H368M0 216H368M0 218H368M0 220H368M0 222H368M0 224H368M0 226H368" stroke="#17B26A" stroke-opacity="0.3" stroke-width="0.5"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.2 KiB |
@@ -0,0 +1,3 @@
|
||||
<svg width="368" height="52" viewBox="0 0 368 52" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path opacity="0.5" d="M0 0.5H368M0 2.5H368M0 4.5H368M0 6.5H368M0 8.5H368M0 10.5H368M0 12.5H368M0 14.5H368M0 16.5H368M0 18.5H368M0 20.5H368M0 22.5H368M0 24.5H368M0 26.5H368M0 28.5H368M0 30.5H368M0 32.5H368M0 34.5H368M0 36.5H368M0 38.5H368M0 40.5H368M0 42.5H368M0 44.5H368M0 46.5H368M0 48.5H368M0 50.5H368M0 52.5H368M0 54.5H368M0 56.5H368M0 58.5H368M0 60.5H368M0 62.5H368M0 64.5H368M0 66.5H368M0 68.5H368M0 70.5H368M0 72.5H368M0 74.5H368M0 76.5H368M0 78.5H368M0 80.5H368M0 82.5H368M0 84.5H368M0 86.5H368M0 88.5H368M0 90.5H368M0 92.5H368M0 94.5H368M0 96.5H368M0 98.5H368M0 100.5H368M0 102.5H368M0 104.5H368M0 106.5H368M0 108.5H368M0 110.5H368M0 112.5H368M0 114.5H368M0 116.5H368M0 118.5H368M0 120.5H368M0 122.5H368M0 124.5H368M0 126.5H368M0 128.5H368M0 130.5H368M0 132.5H368M0 134.5H368M0 136.5H368M0 138.5H368M0 140.5H368M0 142.5H368M0 144.5H368M0 146.5H368M0 148.5H368M0 150.5H368M0 152.5H368M0 154.5H368M0 156.5H368M0 158.5H368M0 160.5H368M0 162.5H368M0 164.5H368M0 166.5H368M0 168.5H368M0 170.5H368M0 172.5H368M0 174.5H368M0 176.5H368M0 178.5H368M0 180.5H368M0 182.5H368M0 184.5H368M0 186.5H368M0 188.5H368M0 190.5H368M0 192.5H368M0 194.5H368M0 196.5H368M0 198.5H368M0 200.5H368M0 202.5H368M0 204.5H368M0 206.5H368M0 208.5H368M0 210.5H368M0 212.5H368M0 214.5H368M0 216.5H368M0 218.5H368M0 220.5H368M0 222.5H368M0 224.5H368M0 226.5H368" stroke="#F79009" stroke-opacity="0.3" stroke-width="0.5"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.5 KiB |
9
web/app/components/workflow/run/assets/highlight.svg
Normal file
9
web/app/components/workflow/run/assets/highlight.svg
Normal file
@@ -0,0 +1,9 @@
|
||||
<svg width="237" height="50" viewBox="0 0 237 50" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path opacity="0.5" d="M0 8C0 3.58172 3.58172 0 8 0H237L215.033 50H8C3.58172 50 0 46.4183 0 42V8Z" fill="url(#paint0_linear_3552_29170)"/>
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear_3552_29170" x1="-4.89158e-08" y1="4.62963" x2="168.013" y2="23.1752" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="white" stop-opacity="0.12"/>
|
||||
<stop offset="1" stop-color="white" stop-opacity="0.5"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
After Width: | Height: | Size: 516 B |
@@ -22,10 +22,9 @@ export type RunProps = {
|
||||
activeTab?: 'RESULT' | 'DETAIL' | 'TRACING'
|
||||
runID: string
|
||||
getResultCallback?: (result: WorkflowRunDetailResponse) => void
|
||||
onShowIterationDetail: (detail: NodeTracing[][]) => void
|
||||
}
|
||||
|
||||
const RunPanel: FC<RunProps> = ({ hideResult, activeTab = 'RESULT', runID, getResultCallback, onShowIterationDetail }) => {
|
||||
const RunPanel: FC<RunProps> = ({ hideResult, activeTab = 'RESULT', runID, getResultCallback }) => {
|
||||
const { t } = useTranslation()
|
||||
const { notify } = useContext(ToastContext)
|
||||
const [currentTab, setCurrentTab] = useState<string>(activeTab)
|
||||
@@ -167,35 +166,35 @@ const RunPanel: FC<RunProps> = ({ hideResult, activeTab = 'RESULT', runID, getRe
|
||||
return (
|
||||
<div className='grow relative flex flex-col'>
|
||||
{/* tab */}
|
||||
<div className='shrink-0 flex items-center px-4 border-b-[0.5px] border-[rgba(0,0,0,0.05)]'>
|
||||
<div className='shrink-0 flex items-center px-4 border-b-[0.5px] border-divider-subtle'>
|
||||
{!hideResult && (
|
||||
<div
|
||||
className={cn(
|
||||
'mr-6 py-3 border-b-2 border-transparent text-[13px] font-semibold leading-[18px] text-gray-400 cursor-pointer',
|
||||
currentTab === 'RESULT' && '!border-[rgb(21,94,239)] text-gray-700',
|
||||
'mr-6 py-3 border-b-2 border-transparent system-sm-semibold-uppercase text-text-tertiary cursor-pointer',
|
||||
currentTab === 'RESULT' && '!border-util-colors-blue-brand-blue-brand-600 text-text-primary',
|
||||
)}
|
||||
onClick={() => switchTab('RESULT')}
|
||||
>{t('runLog.result')}</div>
|
||||
)}
|
||||
<div
|
||||
className={cn(
|
||||
'mr-6 py-3 border-b-2 border-transparent text-[13px] font-semibold leading-[18px] text-gray-400 cursor-pointer',
|
||||
currentTab === 'DETAIL' && '!border-[rgb(21,94,239)] text-gray-700',
|
||||
'mr-6 py-3 border-b-2 border-transparent system-sm-semibold-uppercase text-text-tertiary cursor-pointer',
|
||||
currentTab === 'DETAIL' && '!border-util-colors-blue-brand-blue-brand-600 text-text-primary',
|
||||
)}
|
||||
onClick={() => switchTab('DETAIL')}
|
||||
>{t('runLog.detail')}</div>
|
||||
<div
|
||||
className={cn(
|
||||
'mr-6 py-3 border-b-2 border-transparent text-[13px] font-semibold leading-[18px] text-gray-400 cursor-pointer',
|
||||
currentTab === 'TRACING' && '!border-[rgb(21,94,239)] text-gray-700',
|
||||
'mr-6 py-3 border-b-2 border-transparent system-sm-semibold-uppercase text-text-tertiary cursor-pointer',
|
||||
currentTab === 'TRACING' && '!border-util-colors-blue-brand-blue-brand-600 text-text-primary',
|
||||
)}
|
||||
onClick={() => switchTab('TRACING')}
|
||||
>{t('runLog.tracing')}</div>
|
||||
</div>
|
||||
{/* panel detail */}
|
||||
<div ref={ref} className={cn('grow bg-white h-0 overflow-y-auto rounded-b-2xl', currentTab !== 'DETAIL' && '!bg-gray-50')}>
|
||||
<div ref={ref} className={cn('grow bg-components-panel-bg h-0 overflow-y-auto rounded-b-2xl', currentTab !== 'DETAIL' && '!bg-background-section-burn')}>
|
||||
{loading && (
|
||||
<div className='flex h-full items-center justify-center bg-white'>
|
||||
<div className='flex h-full items-center justify-center bg-components-panel-bg'>
|
||||
<Loading />
|
||||
</div>
|
||||
)}
|
||||
@@ -221,6 +220,7 @@ const RunPanel: FC<RunProps> = ({ hideResult, activeTab = 'RESULT', runID, getRe
|
||||
)}
|
||||
{!loading && currentTab === 'TRACING' && (
|
||||
<TracingPanel
|
||||
className='bg-background-section-burn'
|
||||
list={list}
|
||||
onShowIterationDetail={handleShowIterationDetail}
|
||||
/>
|
||||
|
@@ -111,7 +111,7 @@ const IterationResultPanel: FC<Props> = ({
|
||||
}}
|
||||
onClick={handleNotBubble}
|
||||
>
|
||||
<div className='h-full rounded-2xl bg-white flex flex-col'>
|
||||
<div className='h-full rounded-2xl bg-components-panel-bg flex flex-col'>
|
||||
{main}
|
||||
</div>
|
||||
</div >
|
||||
|
@@ -27,13 +27,13 @@ const MetaData: FC<Props> = ({
|
||||
|
||||
return (
|
||||
<div className='relative'>
|
||||
<div className='h-6 leading-6 text-gray-500 text-xs font-medium'>{t('runLog.meta.title')}</div>
|
||||
<div className='h-6 py-1 text-text-tertiary system-xs-medium-uppercase'>{t('runLog.meta.title')}</div>
|
||||
<div className='py-1'>
|
||||
<div className='flex'>
|
||||
<div className='shrink-0 w-[104px] px-2 py-[5px] text-gray-500 text-xs leading-[18px] truncate'>{t('runLog.meta.status')}</div>
|
||||
<div className='grow px-2 py-[5px] text-gray-900 text-xs leading-[18px]'>
|
||||
<div className='shrink-0 w-[104px] px-2 py-1.5 text-text-tertiary system-xs-regular truncate'>{t('runLog.meta.status')}</div>
|
||||
<div className='grow px-2 py-1.5 text-text-secondary system-xs-regular'>
|
||||
{status === 'running' && (
|
||||
<div className='my-[5px] w-16 h-2 rounded-sm bg-[rgba(0,0,0,0.05)]'/>
|
||||
<div className='my-1 w-16 h-2 rounded-sm bg-text-quaternary'/>
|
||||
)}
|
||||
{status === 'succeeded' && (
|
||||
<span>SUCCESS</span>
|
||||
@@ -47,10 +47,10 @@ const MetaData: FC<Props> = ({
|
||||
</div>
|
||||
</div>
|
||||
<div className='flex'>
|
||||
<div className='shrink-0 w-[104px] px-2 py-[5px] text-gray-500 text-xs leading-[18px] truncate'>{t('runLog.meta.executor')}</div>
|
||||
<div className='grow px-2 py-[5px] text-gray-900 text-xs leading-[18px]'>
|
||||
<div className='shrink-0 w-[104px] px-2 py-1.5 text-text-tertiary system-xs-regular truncate'>{t('runLog.meta.executor')}</div>
|
||||
<div className='grow px-2 py-1.5 text-text-secondary system-xs-regular'>
|
||||
{status === 'running' && (
|
||||
<div className='my-[5px] w-[88px] h-2 rounded-sm bg-[rgba(0,0,0,0.05)]'/>
|
||||
<div className='my-1 w-[88px] h-2 rounded-sm bg-text-quaternary'/>
|
||||
)}
|
||||
{status !== 'running' && (
|
||||
<span>{executor || 'N/A'}</span>
|
||||
@@ -58,10 +58,10 @@ const MetaData: FC<Props> = ({
|
||||
</div>
|
||||
</div>
|
||||
<div className='flex'>
|
||||
<div className='shrink-0 w-[104px] px-2 py-[5px] text-gray-500 text-xs leading-[18px] truncate'>{t('runLog.meta.startTime')}</div>
|
||||
<div className='grow px-2 py-[5px] text-gray-900 text-xs leading-[18px]'>
|
||||
<div className='shrink-0 w-[104px] px-2 py-1.5 text-text-tertiary system-xs-regular truncate'>{t('runLog.meta.startTime')}</div>
|
||||
<div className='grow px-2 py-1.5 text-text-secondary system-xs-regular'>
|
||||
{status === 'running' && (
|
||||
<div className='my-[5px] w-[72px] h-2 rounded-sm bg-[rgba(0,0,0,0.05)]'/>
|
||||
<div className='my-1 w-[72px] h-2 rounded-sm bg-text-quaternary'/>
|
||||
)}
|
||||
{status !== 'running' && (
|
||||
<span>{startTime ? formatTime(startTime, t('appLog.dateTimeFormat') as string) : '-'}</span>
|
||||
@@ -69,10 +69,10 @@ const MetaData: FC<Props> = ({
|
||||
</div>
|
||||
</div>
|
||||
<div className='flex'>
|
||||
<div className='shrink-0 w-[104px] px-2 py-[5px] text-gray-500 text-xs leading-[18px] truncate'>{t('runLog.meta.time')}</div>
|
||||
<div className='grow px-2 py-[5px] text-gray-900 text-xs leading-[18px]'>
|
||||
<div className='shrink-0 w-[104px] px-2 py-1.5 text-text-tertiary system-xs-regular truncate'>{t('runLog.meta.time')}</div>
|
||||
<div className='grow px-2 py-1.5 text-text-secondary system-xs-regular'>
|
||||
{status === 'running' && (
|
||||
<div className='my-[5px] w-[72px] h-2 rounded-sm bg-[rgba(0,0,0,0.05)]'/>
|
||||
<div className='my-1 w-[72px] h-2 rounded-sm bg-text-quaternary'/>
|
||||
)}
|
||||
{status !== 'running' && (
|
||||
<span>{time ? `${time.toFixed(3)}s` : '-'}</span>
|
||||
@@ -80,10 +80,10 @@ const MetaData: FC<Props> = ({
|
||||
</div>
|
||||
</div>
|
||||
<div className='flex'>
|
||||
<div className='shrink-0 w-[104px] px-2 py-[5px] text-gray-500 text-xs leading-[18px] truncate'>{t('runLog.meta.tokens')}</div>
|
||||
<div className='grow px-2 py-[5px] text-gray-900 text-xs leading-[18px]'>
|
||||
<div className='shrink-0 w-[104px] px-2 py-1.5 text-text-tertiary system-xs-regular truncate'>{t('runLog.meta.tokens')}</div>
|
||||
<div className='grow px-2 py-1.5 text-text-secondary system-xs-regular'>
|
||||
{status === 'running' && (
|
||||
<div className='my-[5px] w-[48px] h-2 rounded-sm bg-[rgba(0,0,0,0.05)]'/>
|
||||
<div className='my-1 w-[48px] h-2 rounded-sm bg-text-quaternary'/>
|
||||
)}
|
||||
{status !== 'running' && (
|
||||
<span>{`${tokens || 0} Tokens`}</span>
|
||||
@@ -92,10 +92,10 @@ const MetaData: FC<Props> = ({
|
||||
</div>
|
||||
{showSteps && (
|
||||
<div className='flex'>
|
||||
<div className='shrink-0 w-[104px] px-2 py-[5px] text-gray-500 text-xs leading-[18px] truncate'>{t('runLog.meta.steps')}</div>
|
||||
<div className='grow px-2 py-[5px] text-gray-900 text-xs leading-[18px]'>
|
||||
<div className='shrink-0 w-[104px] px-2 py-1.5 text-text-tertiary system-xs-regular truncate'>{t('runLog.meta.steps')}</div>
|
||||
<div className='grow px-2 py-1.5 text-text-secondary system-xs-regular'>
|
||||
{status === 'running' && (
|
||||
<div className='my-[5px] w-[24px] h-2 rounded-sm bg-[rgba(0,0,0,0.05)]'/>
|
||||
<div className='my-1 w-[24px] h-2 rounded-sm bg-text-quaternary'/>
|
||||
)}
|
||||
{status !== 'running' && (
|
||||
<span>{steps}</span>
|
||||
|
@@ -3,6 +3,7 @@ import { useTranslation } from 'react-i18next'
|
||||
import type { FC } from 'react'
|
||||
import { useCallback, useEffect, useState } from 'react'
|
||||
import {
|
||||
RiAlertFill,
|
||||
RiArrowRightSLine,
|
||||
RiCheckboxCircleFill,
|
||||
RiErrorWarningLine,
|
||||
@@ -13,15 +14,16 @@ import { BlockEnum } from '../types'
|
||||
import Split from '../nodes/_base/components/split'
|
||||
import { Iteration } from '@/app/components/base/icons/src/vender/workflow'
|
||||
import cn from '@/utils/classnames'
|
||||
import StatusContainer from '@/app/components/workflow/run/status-container'
|
||||
import CodeEditor from '@/app/components/workflow/nodes/_base/components/editor/code-editor'
|
||||
import Button from '@/app/components/base/button'
|
||||
import { CodeLanguage } from '@/app/components/workflow/nodes/code/types'
|
||||
import { AlertTriangle } from '@/app/components/base/icons/src/vender/line/alertsAndFeedback'
|
||||
import type { NodeTracing } from '@/types/workflow'
|
||||
|
||||
type Props = {
|
||||
className?: string
|
||||
nodeInfo: NodeTracing
|
||||
inMessage?: boolean
|
||||
hideInfo?: boolean
|
||||
hideProcessDetail?: boolean
|
||||
onShowIterationDetail?: (detail: NodeTracing[][]) => void
|
||||
@@ -32,6 +34,7 @@ type Props = {
|
||||
const NodePanel: FC<Props> = ({
|
||||
className,
|
||||
nodeInfo,
|
||||
inMessage = false,
|
||||
hideInfo = false,
|
||||
hideProcessDetail,
|
||||
onShowIterationDetail,
|
||||
@@ -82,7 +85,7 @@ const NodePanel: FC<Props> = ({
|
||||
}
|
||||
return (
|
||||
<div className={cn('px-2 py-1', className)}>
|
||||
<div className='group transition-all bg-background-default border border-components-panel-border rounded-[10px] shadows-shadow-xs hover:shadow-md'>
|
||||
<div className='group transition-all bg-background-default border border-components-panel-border rounded-[10px] shadow-xs hover:shadow-md'>
|
||||
<div
|
||||
className={cn(
|
||||
'flex items-center pl-1 pr-3 cursor-pointer',
|
||||
@@ -99,8 +102,7 @@ const NodePanel: FC<Props> = ({
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
|
||||
<BlockIcon size={hideInfo ? 'xs' : 'sm'} className={cn('shrink-0 mr-2', hideInfo && '!mr-1')} type={nodeInfo.node_type} toolIcon={nodeInfo.extras?.icon || nodeInfo.extras} />
|
||||
<BlockIcon size={inMessage ? 'xs' : 'sm'} className={cn('shrink-0 mr-2', inMessage && '!mr-1')} type={nodeInfo.node_type} toolIcon={nodeInfo.extras?.icon || nodeInfo.extras} />
|
||||
<div className={cn(
|
||||
'grow text-text-secondary system-xs-semibold-uppercase truncate',
|
||||
hideInfo && '!text-xs',
|
||||
@@ -115,7 +117,7 @@ const NodePanel: FC<Props> = ({
|
||||
<RiErrorWarningLine className='shrink-0 ml-2 w-3.5 h-3.5 text-text-warning' />
|
||||
)}
|
||||
{nodeInfo.status === 'stopped' && (
|
||||
<AlertTriangle className='shrink-0 ml-2 w-3.5 h-3.5 text-[#F79009]' />
|
||||
<RiAlertFill className={cn('shrink-0 ml-2 w-4 h-4 text-text-warning-secondary', inMessage && 'w-3.5 h-3.5')} />
|
||||
)}
|
||||
{nodeInfo.status === 'running' && (
|
||||
<div className='shrink-0 flex items-center text-text-accent text-[13px] leading-[16px] font-medium'>
|
||||
@@ -125,7 +127,7 @@ const NodePanel: FC<Props> = ({
|
||||
)}
|
||||
</div>
|
||||
{!collapseState && !hideProcessDetail && (
|
||||
<div className='pb-2'>
|
||||
<div className='px-1 pb-1'>
|
||||
{/* The nav to the iteration detail */}
|
||||
{isIterationNode && !notShowIterationNav && (
|
||||
<div className='mt-2 mb-1 !px-2'>
|
||||
@@ -151,14 +153,18 @@ const NodePanel: FC<Props> = ({
|
||||
)}
|
||||
<div className={cn('px-[10px]', hideInfo && '!px-2 !py-0.5')}>
|
||||
{nodeInfo.status === 'stopped' && (
|
||||
<div className='px-3 py-[10px] bg-[#fffaeb] rounded-lg border-[0.5px] border-[rbga(0,0,0,0.05)] text-xs leading-[18px] text-[#dc6803] shadow-xs'>{t('workflow.tracing.stopBy', { user: nodeInfo.created_by ? nodeInfo.created_by.name : 'N/A' })}</div>
|
||||
<StatusContainer status='stopped'>
|
||||
{t('workflow.tracing.stopBy', { user: nodeInfo.created_by ? nodeInfo.created_by.name : 'N/A' })}
|
||||
</StatusContainer>
|
||||
)}
|
||||
{nodeInfo.status === 'failed' && (
|
||||
<div className='px-3 py-[10px] bg-[#fef3f2] rounded-lg border-[0.5px] border-[rbga(0,0,0,0.05)] text-xs leading-[18px] text-[#d92d20] shadow-xs'>{nodeInfo.error}</div>
|
||||
<StatusContainer status='failed'>
|
||||
{nodeInfo.error}
|
||||
</StatusContainer>
|
||||
)}
|
||||
</div>
|
||||
{nodeInfo.inputs && (
|
||||
<div className={cn('px-[10px] py-1', hideInfo && '!px-2 !py-0.5')}>
|
||||
<div className={cn('mb-1')}>
|
||||
<CodeEditor
|
||||
readOnly
|
||||
title={<div>{t('workflow.common.input').toLocaleUpperCase()}</div>}
|
||||
@@ -169,7 +175,7 @@ const NodePanel: FC<Props> = ({
|
||||
</div>
|
||||
)}
|
||||
{nodeInfo.process_data && (
|
||||
<div className={cn('px-[10px] py-1', hideInfo && '!px-2 !py-0.5')}>
|
||||
<div className={cn('mb-1')}>
|
||||
<CodeEditor
|
||||
readOnly
|
||||
title={<div>{t('workflow.common.processData').toLocaleUpperCase()}</div>}
|
||||
@@ -180,7 +186,7 @@ const NodePanel: FC<Props> = ({
|
||||
</div>
|
||||
)}
|
||||
{nodeInfo.outputs && (
|
||||
<div className={cn('px-[10px] py-1', hideInfo && '!px-2 !py-0.5')}>
|
||||
<div>
|
||||
<CodeEditor
|
||||
readOnly
|
||||
title={<div>{t('workflow.common.output').toLocaleUpperCase()}</div>}
|
||||
|
@@ -4,6 +4,7 @@ import CodeEditor from '@/app/components/workflow/nodes/_base/components/editor/
|
||||
import { CodeLanguage } from '@/app/components/workflow/nodes/code/types'
|
||||
import { Markdown } from '@/app/components/base/markdown'
|
||||
import LoadingAnim from '@/app/components/base/chat/chat/loading-anim'
|
||||
import StatusContainer from '@/app/components/workflow/run/status-container'
|
||||
|
||||
type OutputPanelProps = {
|
||||
isRunning?: boolean
|
||||
@@ -19,7 +20,7 @@ const OutputPanel: FC<OutputPanelProps> = ({
|
||||
height,
|
||||
}) => {
|
||||
return (
|
||||
<div className='bg-gray-50 py-2'>
|
||||
<div className='py-2'>
|
||||
{isRunning && (
|
||||
<div className='pt-4 pl-[26px]'>
|
||||
<LoadingAnim type='text' />
|
||||
@@ -27,9 +28,7 @@ const OutputPanel: FC<OutputPanelProps> = ({
|
||||
)}
|
||||
{!isRunning && error && (
|
||||
<div className='px-4'>
|
||||
<div className='px-3 py-[10px] rounded-lg !bg-[#fef3f2] border-[0.5px] border-[rbga(0,0,0,0.05)] shadow-xs'>
|
||||
<div className='text-xs leading-[18px] text-[#d92d20]'>{error}</div>
|
||||
</div>
|
||||
<StatusContainer status='failed'>{error}</StatusContainer>
|
||||
</div>
|
||||
)}
|
||||
{!isRunning && !outputs && (
|
||||
|
@@ -36,7 +36,7 @@ const ResultPanel: FC<ResultPanelProps> = ({
|
||||
}) => {
|
||||
const { t } = useTranslation()
|
||||
return (
|
||||
<div className='bg-white py-2'>
|
||||
<div className='bg-components-panel-bg py-2'>
|
||||
<div className='px-4 py-2'>
|
||||
<StatusPanel
|
||||
status={status}
|
||||
@@ -73,7 +73,7 @@ const ResultPanel: FC<ResultPanelProps> = ({
|
||||
)}
|
||||
</div>
|
||||
<div className='px-4 py-2'>
|
||||
<div className='h-[0.5px] bg-black opacity-5' />
|
||||
<div className='h-[0.5px] divider-subtle' />
|
||||
</div>
|
||||
<div className='px-4 py-2'>
|
||||
<MetaData
|
||||
|
@@ -4,12 +4,16 @@ import { useTranslation } from 'react-i18next'
|
||||
import { ImageIndentLeft } from '@/app/components/base/icons/src/vender/line/editor'
|
||||
import { Markdown } from '@/app/components/base/markdown'
|
||||
import LoadingAnim from '@/app/components/base/chat/chat/loading-anim'
|
||||
import StatusContainer from '@/app/components/workflow/run/status-container'
|
||||
import { FileList } from '@/app/components/base/file-uploader'
|
||||
import type { FileEntity } from '@/app/components/base/file-uploader/types'
|
||||
|
||||
type ResultTextProps = {
|
||||
isRunning?: boolean
|
||||
outputs?: any
|
||||
error?: string
|
||||
onClick?: () => void
|
||||
allFiles?: FileEntity[]
|
||||
}
|
||||
|
||||
const ResultText: FC<ResultTextProps> = ({
|
||||
@@ -17,10 +21,11 @@ const ResultText: FC<ResultTextProps> = ({
|
||||
outputs,
|
||||
error,
|
||||
onClick,
|
||||
allFiles,
|
||||
}) => {
|
||||
const { t } = useTranslation()
|
||||
return (
|
||||
<div className='bg-gray-50 py-2'>
|
||||
<div className='bg-background-section-burn py-2'>
|
||||
{isRunning && !outputs && (
|
||||
<div className='pt-4 pl-[26px]'>
|
||||
<LoadingAnim type='text' />
|
||||
@@ -28,9 +33,9 @@ const ResultText: FC<ResultTextProps> = ({
|
||||
)}
|
||||
{!isRunning && error && (
|
||||
<div className='px-4'>
|
||||
<div className='px-3 py-[10px] rounded-lg !bg-[#fef3f2] border-[0.5px] border-[rbga(0,0,0,0.05)] shadow-xs'>
|
||||
<div className='text-xs leading-[18px] text-[#d92d20]'>{error}</div>
|
||||
</div>
|
||||
<StatusContainer status='failed'>
|
||||
{error}
|
||||
</StatusContainer>
|
||||
</div>
|
||||
)}
|
||||
{!isRunning && !outputs && !error && (
|
||||
@@ -47,6 +52,14 @@ const ResultText: FC<ResultTextProps> = ({
|
||||
{outputs && (
|
||||
<div className='px-4 py-2'>
|
||||
<Markdown content={outputs} />
|
||||
{!!allFiles?.length && (
|
||||
<FileList
|
||||
files={allFiles}
|
||||
showDeleteAction={false}
|
||||
showDownloadAction
|
||||
canPreview
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
30
web/app/components/workflow/run/status-container.tsx
Normal file
30
web/app/components/workflow/run/status-container.tsx
Normal file
@@ -0,0 +1,30 @@
|
||||
'use client'
|
||||
import type { FC } from 'react'
|
||||
import cn from '@/utils/classnames'
|
||||
|
||||
type Props = {
|
||||
status: string
|
||||
children?: React.ReactNode
|
||||
}
|
||||
|
||||
const StatusContainer: FC<Props> = ({
|
||||
status,
|
||||
children,
|
||||
}) => {
|
||||
return (
|
||||
<div
|
||||
className={cn(
|
||||
'relative px-3 py-2.5 rounded-lg border system-xs-regular',
|
||||
status === 'succeeded' && 'border-[rgba(23,178,106,0.8)] bg-workflow-display-success-bg bg-[url(~@/app/components/workflow/run/assets/bg-line-success.svg)] shadow-[inset_2px_2px_0_0_rgba(255,255,255,0.5),inset_0_1px_3px_0_rgba(0,0,0,0.12),inset_0_2px_24px_0_rgba(23,178,106,0.2),0_1px_2px_0_rgba(9,9,11,0.05),0_0_0_1px_rgba(0,0,0,0.05)] text-text-success',
|
||||
status === 'failed' && 'border-[rgba(240,68,56,0.8)] bg-workflow-display-error-bg bg-[url(~@/app/components/workflow/run/assets/bg-line-error.svg)] shadow-[inset_2px_2px_0_0_rgba(255,255,255,0.5),inset_0_1px_3px_0_rgba(0,0,0,0.12),inset_0_2px_24px_0_rgba(240,68,56,0.2),0_1px_2px_0_rgba(9,9,11,0.05),0_0_0_1px_rgba(0,0,0,0.05)] text-text-warning',
|
||||
status === 'stopped' && 'border-[rgba(247,144,9,0.8)] bg-workflow-display-warning-bg bg-[url(~@/app/components/workflow/run/assets/bg-line-warning.svg)] shadow-[inset_2px_2px_0_0_rgba(255,255,255,0.5),inset_0_1px_3px_0_rgba(0,0,0,0.12),inset_0_2px_24px_0_rgba(247,144,9,0.2),0_1px_2px_0_rgba(9,9,11,0.05),0_0_0_1px_rgba(0,0,0,0.05)] text-text-destructive',
|
||||
status === 'running' && 'border-[rgba(11,165,236,0.8)] bg-workflow-display-normal-bg bg-[url(~@/app/components/workflow/run/assets/bg-line-running.svg)] shadow-[inset_2px_2px_0_0_rgba(255,255,255,0.5),inset_0_1px_3px_0_rgba(0,0,0,0.12),inset_0_2px_24px_0_rgba(11,165,236,0.2),0_1px_2px_0_rgba(9,9,11,0.05),0_0_0_1px_rgba(0,0,0,0.05)] text-util-colors-blue-light-blue-light-600',
|
||||
)}
|
||||
>
|
||||
<div className='absolute top-0 left-0 w-[65%] h-[50px] bg-[url(~@/app/components/workflow/run/assets/highlight.svg)]'></div>
|
||||
{children}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default StatusContainer
|
@@ -3,6 +3,7 @@ import type { FC } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import cn from '@/utils/classnames'
|
||||
import Indicator from '@/app/components/header/indicator'
|
||||
import StatusContainer from '@/app/components/workflow/run/status-container'
|
||||
|
||||
type ResultProps = {
|
||||
status: string
|
||||
@@ -20,29 +21,24 @@ const StatusPanel: FC<ResultProps> = ({
|
||||
const { t } = useTranslation()
|
||||
|
||||
return (
|
||||
<div
|
||||
className={cn(
|
||||
'px-3 py-[10px] rounded-lg border-[0.5px] border-[rbga(0,0,0,0.05)] shadow-xs',
|
||||
status === 'running' && '!bg-primary-50',
|
||||
status === 'succeeded' && '!bg-[#ecfdf3]',
|
||||
status === 'failed' && '!bg-[#fef3f2]',
|
||||
status === 'stopped' && '!bg-[#fffaeb]',
|
||||
)}
|
||||
>
|
||||
<StatusContainer status={status}>
|
||||
<div className='flex'>
|
||||
<div className='flex-[33%] max-w-[120px]'>
|
||||
<div className='text-xs leading-[18px] font-medium text-gray-400'>{t('runLog.resultPanel.status')}</div>
|
||||
<div className='mb-1 text-text-tertiary system-2xs-medium-uppercase'>{t('runLog.resultPanel.status')}</div>
|
||||
<div
|
||||
className={cn(
|
||||
'flex items-center gap-1 h-[18px] text-xs leading-3 font-semibold',
|
||||
status === 'running' && '!text-primary-600',
|
||||
status === 'succeeded' && '!text-[#039855]',
|
||||
status === 'failed' && '!text-[#d92d20]',
|
||||
status === 'stopped' && '!text-[#f79009]',
|
||||
'flex items-center gap-1 system-xs-semibold-uppercase',
|
||||
status === 'succeeded' && 'text-util-colors-green-green-600',
|
||||
status === 'failed' && 'text-util-colors-red-red-600',
|
||||
status === 'stopped' && 'text-util-colors-warning-warning-600',
|
||||
status === 'running' && 'text-util-colors-blue-light-blue-light-600',
|
||||
)}
|
||||
>
|
||||
{status === 'running' && (
|
||||
<span>Running</span>
|
||||
<>
|
||||
<Indicator color={'blue'} />
|
||||
<span>Running</span>
|
||||
</>
|
||||
)}
|
||||
{status === 'succeeded' && (
|
||||
<>
|
||||
@@ -65,10 +61,10 @@ const StatusPanel: FC<ResultProps> = ({
|
||||
</div>
|
||||
</div>
|
||||
<div className='flex-[33%] max-w-[152px]'>
|
||||
<div className='text-xs leading-[18px] font-medium text-gray-400'>{t('runLog.resultPanel.time')}</div>
|
||||
<div className='flex items-center gap-1 h-[18px] text-gray-700 text-xs leading-3 font-semibold'>
|
||||
<div className='mb-1 text-text-tertiary system-2xs-medium-uppercase'>{t('runLog.resultPanel.time')}</div>
|
||||
<div className='flex items-center gap-1 system-sm-medium text-text-secondary'>
|
||||
{status === 'running' && (
|
||||
<div className='w-16 h-2 rounded-sm bg-[rgba(0,0,0,0.05)]' />
|
||||
<div className='w-16 h-2 rounded-sm bg-text-quaternary' />
|
||||
)}
|
||||
{status !== 'running' && (
|
||||
<span>{time ? `${time?.toFixed(3)}s` : '-'}</span>
|
||||
@@ -76,10 +72,10 @@ const StatusPanel: FC<ResultProps> = ({
|
||||
</div>
|
||||
</div>
|
||||
<div className='flex-[33%]'>
|
||||
<div className='text-xs leading-[18px] font-medium text-gray-400'>{t('runLog.resultPanel.tokens')}</div>
|
||||
<div className='flex items-center gap-1 h-[18px] text-gray-700 text-xs leading-3 font-semibold'>
|
||||
<div className='mb-1 text-text-tertiary system-2xs-medium-uppercase'>{t('runLog.resultPanel.tokens')}</div>
|
||||
<div className='flex items-center gap-1 system-sm-medium text-text-secondary'>
|
||||
{status === 'running' && (
|
||||
<div className='w-20 h-2 rounded-sm bg-[rgba(0,0,0,0.05)]' />
|
||||
<div className='w-20 h-2 rounded-sm bg-text-quaternary' />
|
||||
)}
|
||||
{status !== 'running' && (
|
||||
<span>{`${tokens || 0} Tokens`}</span>
|
||||
@@ -89,11 +85,11 @@ const StatusPanel: FC<ResultProps> = ({
|
||||
</div>
|
||||
{status === 'failed' && error && (
|
||||
<>
|
||||
<div className='my-2 h-[0.5px] bg-black opacity-5' />
|
||||
<div className='text-xs leading-[18px] text-[#d92d20]'>{error}</div>
|
||||
<div className='my-2 h-[0.5px] bg-divider-subtle'/>
|
||||
<div className='system-xs-regular text-text-destructive'>{error}</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</StatusContainer>
|
||||
)
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user