From 833fa97f56b4976ade9ff1a185ee467eb26e645d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=98=D0=BB=D1=8C=D1=8F=D1=81=20=D0=A1=D1=83=D0=BB=D1=82?= =?UTF-8?q?=D0=B0=D0=BD=D0=BE=D0=B2?= Date: Sat, 11 Jul 2026 21:48:35 +0300 Subject: [PATCH] =?UTF-8?q?feat(qr):=20offline=20show=5Flist=20=D0=B4?= =?UTF-8?q?=D0=B8=D0=B0=D0=BB=D0=BE=D0=B3=20=D0=B4=D0=BB=D1=8F=20QR-=D0=B0?= =?UTF-8?q?=D0=B2=D1=82=D0=BE=D0=BC=D0=B0=D1=82=D0=B8=D0=B7=D0=B0=D1=86?= =?UTF-8?q?=D0=B8=D0=B8=20=D0=9A=D0=98=D0=9F=D0=B8=D0=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - clientAutomationEngine: onShowTaskDialog callback для show_list - QrHandler: Dialog со списком найденных задач, навигация на /forms/11/tasks/:id --- client/src/lib/clientAutomationEngine.ts | 18 +++++++-- client/src/pages/QrHandler.tsx | 47 +++++++++++++++++++++++- 2 files changed, 59 insertions(+), 6 deletions(-) diff --git a/client/src/lib/clientAutomationEngine.ts b/client/src/lib/clientAutomationEngine.ts index bf6663a..4fdf4f5 100644 --- a/client/src/lib/clientAutomationEngine.ts +++ b/client/src/lib/clientAutomationEngine.ts @@ -208,6 +208,7 @@ export async function handleAutomationActions( deps: { toast: (opts: { title?: string; description?: string; variant?: 'default' | 'destructive' }) => void; navigate?: (path: string) => void; + onShowTaskDialog?: (tasks: Array<{ id: number; title: string }>) => void; }, ): Promise { const holder = extractActions(result); @@ -244,7 +245,11 @@ export async function handleAutomationActions( if (holder.legacy) { handled = true; - await handleLegacyAction(holder.legacy, deps); + await handleLegacyAction(holder.legacy, { + toast: deps.toast, + navigate: deps.navigate, + onShowTaskDialog: deps.onShowTaskDialog, + }); } return handled; @@ -291,6 +296,7 @@ async function handleLegacyAction( deps: { toast: (opts: { title?: string; description?: string; variant?: 'default' | 'destructive' }) => void; navigate?: (path: string) => void; + onShowTaskDialog?: (tasks: Array<{ id: number; title: string }>) => void; }, ): Promise { const nav = deps.navigate ?? navigate; @@ -317,9 +323,13 @@ async function handleLegacyAction( break; } case 'show_list': { - // Legacy show_list has no direct screen — notify the user instead. - const titles = action.tasks.map((t) => t.title).join(', '); - deps.toast({ title: 'Найдены задачи', description: titles || 'Список пуст' }); + if (deps.onShowTaskDialog && action.tasks.length > 0) { + deps.onShowTaskDialog(action.tasks); + } else { + // Fallback when no dialog handler is provided. + const titles = action.tasks.map((t) => t.title).join(', '); + deps.toast({ title: 'Найдены задачи', description: titles || 'Список пуст' }); + } break; } } diff --git a/client/src/pages/QrHandler.tsx b/client/src/pages/QrHandler.tsx index 6be4687..382157d 100644 --- a/client/src/pages/QrHandler.tsx +++ b/client/src/pages/QrHandler.tsx @@ -6,6 +6,13 @@ import { runOfflineAutomations, handleAutomationActions, type ClientAutomationRe import { checkServerReachable } from '@/lib/syncEngine'; import { Button } from '@/components/ui/button'; import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; +import { + Dialog, + DialogContent, + DialogHeader, + DialogTitle, + DialogDescription, +} from '@/components/ui/dialog'; import { Loader2, Terminal, ArrowLeft } from 'lucide-react'; import { apiRequest } from '@/lib/queryClient'; @@ -17,6 +24,10 @@ export default function QrHandler() { const [results, setResults] = useState([]); const [loading, setLoading] = useState(true); + const [taskDialog, setTaskDialog] = useState<{ open: boolean; tasks: Array<{ id: number; title: string }> }>({ + open: false, + tasks: [], + }); const templateKey = params.templateKey ?? ''; const objectId = params.objectId ? parseInt(params.objectId) : undefined; @@ -57,7 +68,11 @@ export default function QrHandler() { if (res.error) { toast({ title: 'Ошибка автоматизации', description: res.error, variant: 'destructive' }); } else if (res.result) { - await handleAutomationActions(res.result, { toast, navigate }); + await handleAutomationActions(res.result, { + toast, + navigate, + onShowTaskDialog: (tasks) => setTaskDialog({ open: true, tasks }), + }); } } } @@ -82,7 +97,11 @@ export default function QrHandler() { ); for (const res of data.results) { if (res.result) { - await handleAutomationActions(res.result, { toast, navigate }); + await handleAutomationActions(res.result, { + toast, + navigate, + onShowTaskDialog: (tasks) => setTaskDialog({ open: true, tasks }), + }); } } } else { @@ -165,6 +184,30 @@ export default function QrHandler() { ))} + + setTaskDialog((prev) => ({ ...prev, open }))}> + + + Найдены заявки + Выберите задачу для открытия + +
+ {taskDialog.tasks.map((task) => ( + + ))} +
+
+
);