11import React from 'react' ;
22import { useTranslation } from '@i18next-toolkit/react' ;
33import { Badge } from '@/components/ui/badge' ;
4+ import { Button } from '@/components/ui/button' ;
45import { ScrollArea } from '@/components/ui/scroll-area' ;
56import { SheetDataSection } from '@/components/ui/sheet' ;
67import dayjs from 'dayjs' ;
78import { cn } from '@/utils/style' ;
89import { formatDate } from '@/utils/date' ;
910import { DataRender } from '../DataRender' ;
1011import { drop } from 'lodash-es' ;
12+ import { LuPlay } from 'react-icons/lu' ;
13+ import { useEventWithLoading } from '@/hooks/useEvent' ;
14+ import { AlertConfirm } from '../AlertConfirm' ;
1115
1216interface WorkerExecutionDetailProps {
1317 vertical ?: boolean ;
@@ -23,13 +27,20 @@ interface WorkerExecutionDetailProps {
2327 responsePayload ?: unknown ;
2428 logs ?: ( string | number ) [ ] [ ] | null ;
2529 } ;
30+ onReplay ?: ( payload : unknown ) => Promise < void > ;
2631}
2732
2833export const WorkerExecutionDetail : React . FC < WorkerExecutionDetailProps > =
2934 React . memo ( ( props ) => {
30- const { vertical = false , execution } = props ;
35+ const { vertical = false , execution, onReplay } = props ;
3136 const { t } = useTranslation ( ) ;
3237
38+ const [ handleReplay , isReplaying ] = useEventWithLoading ( async ( ) => {
39+ if ( onReplay ) {
40+ await onReplay ( execution . requestPayload ) ;
41+ }
42+ } ) ;
43+
3344 return (
3445 < ScrollArea className = "h-full" >
3546 < div className = "space-y-4 p-1" >
@@ -76,11 +87,34 @@ export const WorkerExecutionDetail: React.FC<WorkerExecutionDetailProps> =
7687
7788 { execution . requestPayload !== null &&
7889 execution . requestPayload !== undefined && (
79- < SheetDataSection label = { t ( 'Request' ) } >
80- < div className = "mt-1 max-h-[400px] overflow-auto rounded-md bg-gray-100 p-3 text-gray-900 dark:bg-gray-900 dark:text-gray-100" >
81- < DataRender type = "json" value = { execution . requestPayload } />
82- </ div >
83- </ SheetDataSection >
90+ < >
91+ < SheetDataSection label = { t ( 'Request' ) } >
92+ < div className = "mt-1 max-h-[400px] overflow-auto rounded-md bg-gray-100 p-3 text-gray-900 dark:bg-gray-900 dark:text-gray-100" >
93+ < DataRender type = "json" value = { execution . requestPayload } />
94+ </ div >
95+ </ SheetDataSection >
96+
97+ { onReplay && (
98+ < div className = "flex justify-end" >
99+ < AlertConfirm
100+ title = { t ( 'Replay Worker Execution' ) }
101+ description = { t (
102+ 'Are you sure you want to replay this execution with the same payload?'
103+ ) }
104+ onConfirm = { handleReplay }
105+ >
106+ < Button
107+ size = "sm"
108+ Icon = { LuPlay }
109+ loading = { isReplaying }
110+ disabled = { isReplaying }
111+ >
112+ { t ( 'Replay' ) }
113+ </ Button >
114+ </ AlertConfirm >
115+ </ div >
116+ ) }
117+ </ >
84118 ) }
85119
86120 { execution . responsePayload !== null &&
0 commit comments