Add pipeline cancellation feature with UI and i18n support
- Add cancelPipeline API endpoint - Add cancel button to status dialog - Update status response type - Add cancellation UI translations - Handle cancellation request states
This commit is contained in:
parent
78ad8873b8
commit
f89b5ab101
7 changed files with 125 additions and 32 deletions
|
|
@ -242,6 +242,7 @@ export type PipelineStatusResponse = {
|
|||
batchs: number
|
||||
cur_batch: number
|
||||
request_pending: boolean
|
||||
cancellation_requested?: boolean
|
||||
latest_message: string
|
||||
history_messages?: string[]
|
||||
update_status?: Record<string, any>
|
||||
|
|
@ -691,6 +692,14 @@ export const getPipelineStatus = async (): Promise<PipelineStatusResponse> => {
|
|||
return response.data
|
||||
}
|
||||
|
||||
export const cancelPipeline = async (): Promise<{
|
||||
status: 'cancellation_requested' | 'not_busy'
|
||||
message: string
|
||||
}> => {
|
||||
const response = await axiosInstance.post('/documents/cancel_pipeline')
|
||||
return response.data
|
||||
}
|
||||
|
||||
export const loginToServer = async (username: string, password: string): Promise<LoginResponse> => {
|
||||
const formData = new FormData();
|
||||
formData.append('username', username);
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import {
|
|||
DialogDescription
|
||||
} from '@/components/ui/Dialog'
|
||||
import Button from '@/components/ui/Button'
|
||||
import { getPipelineStatus, PipelineStatusResponse } from '@/api/lightrag'
|
||||
import { getPipelineStatus, cancelPipeline, PipelineStatusResponse } from '@/api/lightrag'
|
||||
import { errorMessage } from '@/lib/utils'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
|
|
@ -81,6 +81,23 @@ export default function PipelineStatusDialog({
|
|||
return () => clearInterval(interval)
|
||||
}, [open, t])
|
||||
|
||||
// Handle cancel pipeline
|
||||
const handleCancelPipeline = async () => {
|
||||
try {
|
||||
const result = await cancelPipeline()
|
||||
if (result.status === 'cancellation_requested') {
|
||||
toast.success(t('documentPanel.pipelineStatus.cancelSuccess'))
|
||||
} else if (result.status === 'not_busy') {
|
||||
toast.info(t('documentPanel.pipelineStatus.cancelNotBusy'))
|
||||
}
|
||||
} catch (err) {
|
||||
toast.error(t('documentPanel.pipelineStatus.cancelFailed', { error: errorMessage(err) }))
|
||||
}
|
||||
}
|
||||
|
||||
// Determine if cancel button should be enabled
|
||||
const canCancel = status?.busy === true && !status?.cancellation_requested
|
||||
|
||||
return (
|
||||
<Dialog open={open} onOpenChange={onOpenChange}>
|
||||
<DialogContent
|
||||
|
|
@ -142,16 +159,43 @@ export default function PipelineStatusDialog({
|
|||
|
||||
{/* Status Content */}
|
||||
<div className="space-y-4 pt-4">
|
||||
{/* Pipeline Status */}
|
||||
<div className="flex items-center gap-4">
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="text-sm font-medium">{t('documentPanel.pipelineStatus.busy')}:</div>
|
||||
<div className={`h-2 w-2 rounded-full ${status?.busy ? 'bg-green-500' : 'bg-gray-300'}`} />
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="text-sm font-medium">{t('documentPanel.pipelineStatus.requestPending')}:</div>
|
||||
<div className={`h-2 w-2 rounded-full ${status?.request_pending ? 'bg-green-500' : 'bg-gray-300'}`} />
|
||||
{/* Pipeline Status - with cancel button */}
|
||||
<div className="flex flex-wrap items-center justify-between gap-4">
|
||||
{/* Left side: Status indicators */}
|
||||
<div className="flex items-center gap-4">
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="text-sm font-medium">{t('documentPanel.pipelineStatus.busy')}:</div>
|
||||
<div className={`h-2 w-2 rounded-full ${status?.busy ? 'bg-green-500' : 'bg-gray-300'}`} />
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="text-sm font-medium">{t('documentPanel.pipelineStatus.requestPending')}:</div>
|
||||
<div className={`h-2 w-2 rounded-full ${status?.request_pending ? 'bg-green-500' : 'bg-gray-300'}`} />
|
||||
</div>
|
||||
{/* Only show cancellation status when it's requested */}
|
||||
{status?.cancellation_requested && (
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="text-sm font-medium">{t('documentPanel.pipelineStatus.cancellationRequested')}:</div>
|
||||
<div className="h-2 w-2 rounded-full bg-red-500" />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Right side: Cancel button - only show when pipeline is busy */}
|
||||
{status?.busy && (
|
||||
<Button
|
||||
variant="destructive"
|
||||
size="sm"
|
||||
disabled={!canCancel}
|
||||
onClick={handleCancelPipeline}
|
||||
title={
|
||||
status?.cancellation_requested
|
||||
? t('documentPanel.pipelineStatus.cancelInProgress')
|
||||
: t('documentPanel.pipelineStatus.cancelTooltip')
|
||||
}
|
||||
>
|
||||
{t('documentPanel.pipelineStatus.cancelButton')}
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Job Information */}
|
||||
|
|
|
|||
|
|
@ -157,17 +157,25 @@
|
|||
"hideFileNameTooltip": "إخفاء اسم الملف"
|
||||
},
|
||||
"pipelineStatus": {
|
||||
"title": "حالة خط المعالجة",
|
||||
"busy": "خط المعالجة مشغول",
|
||||
"requestPending": "الطلب معلق",
|
||||
"title": "حالة خط الأنابيب",
|
||||
"busy": "خط الأنابيب مشغول",
|
||||
"requestPending": "طلب معلق",
|
||||
"cancellationRequested": "طلب الإلغاء",
|
||||
"jobName": "اسم المهمة",
|
||||
"startTime": "وقت البدء",
|
||||
"progress": "التقدم",
|
||||
"unit": "دفعة",
|
||||
"latestMessage": "آخر رسالة",
|
||||
"historyMessages": "سجل الرسائل",
|
||||
"historyMessages": "رسائل السجل",
|
||||
"cancelButton": "إلغاء",
|
||||
"cancelTooltip": "إلغاء معالجة خط الأنابيب",
|
||||
"cancelInProgress": "الإلغاء قيد التقدم...",
|
||||
"pipelineNotRunning": "خط الأنابيب غير قيد التشغيل",
|
||||
"cancelSuccess": "تم طلب إلغاء خط الأنابيب",
|
||||
"cancelFailed": "فشل إلغاء خط الأنابيب\n{{error}}",
|
||||
"cancelNotBusy": "خط الأنابيب غير قيد التشغيل، لا حاجة للإلغاء",
|
||||
"errors": {
|
||||
"fetchFailed": "فشل في جلب حالة خط المعالجة\n{{error}}"
|
||||
"fetchFailed": "فشل في جلب حالة خط الأنابيب\n{{error}}"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -160,14 +160,22 @@
|
|||
"title": "Pipeline Status",
|
||||
"busy": "Pipeline Busy",
|
||||
"requestPending": "Request Pending",
|
||||
"cancellationRequested": "Cancellation Requested",
|
||||
"jobName": "Job Name",
|
||||
"startTime": "Start Time",
|
||||
"progress": "Progress",
|
||||
"unit": "batch",
|
||||
"unit": "Batch",
|
||||
"latestMessage": "Latest Message",
|
||||
"historyMessages": "History Messages",
|
||||
"cancelButton": "Cancel",
|
||||
"cancelTooltip": "Cancel pipeline processing",
|
||||
"cancelInProgress": "Cancellation in progress...",
|
||||
"pipelineNotRunning": "Pipeline not running",
|
||||
"cancelSuccess": "Pipeline cancellation requested",
|
||||
"cancelFailed": "Failed to cancel pipeline\n{{error}}",
|
||||
"cancelNotBusy": "Pipeline is not running, no need to cancel",
|
||||
"errors": {
|
||||
"fetchFailed": "Failed to get pipeline status\n{{error}}"
|
||||
"fetchFailed": "Failed to fetch pipeline status\n{{error}}"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -158,14 +158,22 @@
|
|||
},
|
||||
"pipelineStatus": {
|
||||
"title": "État du Pipeline",
|
||||
"busy": "Pipeline occupé",
|
||||
"requestPending": "Requête en attente",
|
||||
"jobName": "Nom du travail",
|
||||
"startTime": "Heure de début",
|
||||
"progress": "Progression",
|
||||
"unit": "lot",
|
||||
"latestMessage": "Dernier message",
|
||||
"historyMessages": "Historique des messages",
|
||||
"busy": "Pipeline Occupé",
|
||||
"requestPending": "Demande en Attente",
|
||||
"cancellationRequested": "Annulation Demandée",
|
||||
"jobName": "Nom du Travail",
|
||||
"startTime": "Heure de Début",
|
||||
"progress": "Progrès",
|
||||
"unit": "Lot",
|
||||
"latestMessage": "Dernier Message",
|
||||
"historyMessages": "Messages d'Historique",
|
||||
"cancelButton": "Annuler",
|
||||
"cancelTooltip": "Annuler le traitement du pipeline",
|
||||
"cancelInProgress": "Annulation en cours...",
|
||||
"pipelineNotRunning": "Le pipeline n'est pas en cours d'exécution",
|
||||
"cancelSuccess": "Annulation du pipeline demandée",
|
||||
"cancelFailed": "Échec de l'annulation du pipeline\n{{error}}",
|
||||
"cancelNotBusy": "Le pipeline n'est pas en cours d'exécution, pas besoin d'annuler",
|
||||
"errors": {
|
||||
"fetchFailed": "Échec de la récupération de l'état du pipeline\n{{error}}"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -160,12 +160,20 @@
|
|||
"title": "流水线状态",
|
||||
"busy": "流水线忙碌",
|
||||
"requestPending": "待处理请求",
|
||||
"cancellationRequested": "取消请求",
|
||||
"jobName": "作业名称",
|
||||
"startTime": "开始时间",
|
||||
"progress": "进度",
|
||||
"unit": "批",
|
||||
"latestMessage": "最新消息",
|
||||
"historyMessages": "历史消息",
|
||||
"cancelButton": "中断",
|
||||
"cancelTooltip": "中断流水线处理",
|
||||
"cancelInProgress": "取消请求进行中...",
|
||||
"pipelineNotRunning": "流水线未运行",
|
||||
"cancelSuccess": "流水线中断请求已发送",
|
||||
"cancelFailed": "中断流水线失败\n{{error}}",
|
||||
"cancelNotBusy": "流水线未运行,无需中断",
|
||||
"errors": {
|
||||
"fetchFailed": "获取流水线状态失败\n{{error}}"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -157,17 +157,25 @@
|
|||
"hideFileNameTooltip": "隱藏檔案名稱"
|
||||
},
|
||||
"pipelineStatus": {
|
||||
"title": "pipeline 狀態",
|
||||
"busy": "pipeline 忙碌中",
|
||||
"title": "流水線狀態",
|
||||
"busy": "流水線忙碌",
|
||||
"requestPending": "待處理請求",
|
||||
"jobName": "工作名稱",
|
||||
"cancellationRequested": "取消請求",
|
||||
"jobName": "作業名稱",
|
||||
"startTime": "開始時間",
|
||||
"progress": "進度",
|
||||
"unit": "梯次",
|
||||
"latestMessage": "最新訊息",
|
||||
"historyMessages": "歷史訊息",
|
||||
"unit": "批",
|
||||
"latestMessage": "最新消息",
|
||||
"historyMessages": "歷史消息",
|
||||
"cancelButton": "中斷",
|
||||
"cancelTooltip": "中斷流水線處理",
|
||||
"cancelInProgress": "取消請求進行中...",
|
||||
"pipelineNotRunning": "流水線未運行",
|
||||
"cancelSuccess": "流水線中斷請求已發送",
|
||||
"cancelFailed": "中斷流水線失敗\n{{error}}",
|
||||
"cancelNotBusy": "流水線未運行,無需中斷",
|
||||
"errors": {
|
||||
"fetchFailed": "取得pipeline 狀態失敗\n{{error}}"
|
||||
"fetchFailed": "獲取流水線狀態失敗\n{{error}}"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue