diff --git a/frontend/src/components/WsUpdateModal.jsx b/frontend/src/components/WsUpdateModal.jsx index a2c8be6..c166609 100644 --- a/frontend/src/components/WsUpdateModal.jsx +++ b/frontend/src/components/WsUpdateModal.jsx @@ -17,21 +17,37 @@ function WsUpdateModal({ show, url, onClose }) { setStatus('connecting'); ws.onopen = () => setStatus('open'); ws.onmessage = (evt) => { - const text = typeof evt.data === 'string' ? evt.data : '[binary]'; - // Пробуем распарсить JSON после префикса "$ " + const text = typeof evt.data === 'string' ? evt.data : ''; + // Ищем JSON-часть в сообщении (после `$ ` или без него) let parsed = null; - let clean = text; - if (text.startsWith('$ ')) { - const jsonPart = text.slice(2); + let jsonStart = text.indexOf('{'); + if (jsonStart >= 0) { + const candidate = text.slice(jsonStart).trim(); try { - parsed = JSON.parse(jsonPart); - clean = parsed?.line || parsed?.event || jsonPart; - if (parsed?.event === 'start' && parsed?.ts) { - setStartedAt(new Date(parsed.ts)); - } - } catch {} + parsed = JSON.parse(candidate); + } catch { + parsed = null; + } } - setRawMessages((prev) => [...prev, { text: clean, json: parsed }]); + + // Если пришёл JSON — показываем только поле `line`. Остальные события (start, etc.) не выводим в лог + if (parsed) { + if (parsed.event === 'start' && parsed.ts) { + setStartedAt(new Date(parsed.ts)); + return; // ничего не выводим + } + if (typeof parsed.line === 'string' && parsed.line.trim().length > 0) { + setRawMessages((prev) => [...prev, { text: parsed.line, json: parsed }]); + return; + } + // Нет поля line — игнорируем + return; + } + + // Если JSON не распарсился — выводим как есть (обрежем префикс `$ ` при наличии) + const clean = text.startsWith('$ ') ? text.slice(2) : text; + if (clean.trim().length === 0) return; + setRawMessages((prev) => [...prev, { text: clean, json: null }]); }; ws.onerror = () => setStatus('error'); ws.onclose = () => setStatus('closed');