viberadar 0.3.175 → 0.3.176
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/probe/runner.d.ts.map +1 -1
- package/dist/probe/runner.js +34 -1
- package/dist/probe/runner.js.map +1 -1
- package/dist/probe/types.d.ts +2 -1
- package/dist/probe/types.d.ts.map +1 -1
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +46 -27
- package/dist/server/index.js.map +1 -1
- package/dist/ui/dashboard.html +54 -28
- package/package.json +1 -1
package/dist/ui/dashboard.html
CHANGED
|
@@ -1641,7 +1641,6 @@
|
|
|
1641
1641
|
<div class="view-tab" data-view="features">Features</div>
|
|
1642
1642
|
<div class="view-tab" data-view="files">Files</div>
|
|
1643
1643
|
<div class="view-tab" data-view="tests">Tests</div>
|
|
1644
|
-
<div class="view-tab" data-view="probe">Probe</div>
|
|
1645
1644
|
</div>
|
|
1646
1645
|
<input class="search-input" id="searchInput" type="text" placeholder="Search…" />
|
|
1647
1646
|
<div id="sidebarExtra"></div>
|
|
@@ -1808,13 +1807,14 @@ function switchMode(nextMode) {
|
|
|
1808
1807
|
saveModeState(contextMode);
|
|
1809
1808
|
contextMode = nextMode;
|
|
1810
1809
|
restoreModeState(contextMode);
|
|
1811
|
-
if (contextMode === 'observability' || contextMode === 'docs' || contextMode === 'services' || contextMode === 'load') {
|
|
1810
|
+
if (contextMode === 'observability' || contextMode === 'docs' || contextMode === 'services' || contextMode === 'load' || contextMode === 'probe') {
|
|
1812
1811
|
view = 'features';
|
|
1813
1812
|
drillFeatureKey = null;
|
|
1814
1813
|
drillTestType = null;
|
|
1815
1814
|
activePanelKey = null;
|
|
1816
1815
|
clearFeatureHash();
|
|
1817
1816
|
}
|
|
1817
|
+
if (contextMode === 'probe') { loadProbeData(); }
|
|
1818
1818
|
if (contextMode === 'load' && loadK6Available === null) { checkK6(); }
|
|
1819
1819
|
if (contextMode === 'load') {
|
|
1820
1820
|
loadRefreshScripts();
|
|
@@ -3183,6 +3183,7 @@ function renderModeSwitch() {
|
|
|
3183
3183
|
{ key: 'scenarios', label: 'Сценарии', hint: 'Пользовательские сценарии, user journeys' },
|
|
3184
3184
|
{ key: 'services', label: 'Карта сервисов', hint: 'Зависимости, пайплайны, мониторинг' },
|
|
3185
3185
|
{ key: 'load', label: 'Нагрузка', hint: 'k6: метрики, сценарии, AI-анализ' },
|
|
3186
|
+
{ key: 'probe', label: 'Probe', hint: 'Synthetic monitoring, E2E на стенде' },
|
|
3186
3187
|
];
|
|
3187
3188
|
root.innerHTML = modes.map(m => `
|
|
3188
3189
|
<button class="mode-switch-btn ${contextMode === m.key ? 'active' : ''}" data-mode="${m.key}">
|
|
@@ -3201,6 +3202,16 @@ function renderSidebar() {
|
|
|
3201
3202
|
const tabs = document.getElementById('viewTabs');
|
|
3202
3203
|
const extra = document.getElementById('sidebarExtra');
|
|
3203
3204
|
|
|
3205
|
+
if (contextMode === 'probe') {
|
|
3206
|
+
tabs.style.display = 'none';
|
|
3207
|
+
extra.innerHTML = `
|
|
3208
|
+
<div class="sidebar-label">Probe</div>
|
|
3209
|
+
<div style="font-size:12px;color:var(--muted);padding:0 6px;line-height:1.45">
|
|
3210
|
+
Запуск E2E-проверок на стенде. Домен задаётся в Настройках.
|
|
3211
|
+
</div>`;
|
|
3212
|
+
return;
|
|
3213
|
+
}
|
|
3214
|
+
|
|
3204
3215
|
if (contextMode === 'observability') {
|
|
3205
3216
|
tabs.style.display = 'none';
|
|
3206
3217
|
extra.innerHTML = `
|
|
@@ -3346,7 +3357,7 @@ function renderContent() {
|
|
|
3346
3357
|
return;
|
|
3347
3358
|
}
|
|
3348
3359
|
|
|
3349
|
-
if (
|
|
3360
|
+
if (contextMode === 'probe') {
|
|
3350
3361
|
renderProbePanel(c);
|
|
3351
3362
|
return;
|
|
3352
3363
|
}
|
|
@@ -3412,10 +3423,10 @@ function renderProbePanel(c) {
|
|
|
3412
3423
|
<div class="probe-header">
|
|
3413
3424
|
<div>
|
|
3414
3425
|
<div class="probe-title">🔭 Probe monitoring</div>
|
|
3415
|
-
${d && d.
|
|
3416
|
-
: `<div style="color:var(--yellow);font-size:12px">⚠️
|
|
3426
|
+
${d && d.effectiveTarget ? `<div style="color:var(--muted);font-size:12px">${escapeHtml(d.effectiveTarget)} · ${escapeHtml((d.checks || []).length)} checks · <span style="color:${statusColor}">${statusLabel}</span></div>`
|
|
3427
|
+
: `<div style="color:var(--yellow);font-size:12px">⚠️ Задайте домен стенда в Настройках</div>`}
|
|
3417
3428
|
</div>
|
|
3418
|
-
<button class="probe-btn" onclick="
|
|
3429
|
+
<button class="probe-btn" onclick="openProbeSettingsModal()">⚙️ Настройки</button>
|
|
3419
3430
|
</div>
|
|
3420
3431
|
|
|
3421
3432
|
<div class="probe-section">
|
|
@@ -3460,42 +3471,57 @@ async function probeScheduleStop() {
|
|
|
3460
3471
|
renderContent();
|
|
3461
3472
|
}
|
|
3462
3473
|
|
|
3463
|
-
function
|
|
3464
|
-
fetch('/api/probe/
|
|
3474
|
+
function openProbeSettingsModal() {
|
|
3475
|
+
fetch('/api/probe/settings').then(r => r.json()).then(saved => {
|
|
3465
3476
|
const tg = saved.telegram || {};
|
|
3466
|
-
|
|
3477
|
+
const inp = s => `style="width:100%;box-sizing:border-box;padding:8px 12px;border-radius:6px;border:1px solid var(--border);background:var(--bg);color:var(--text);font-size:13px"`;
|
|
3478
|
+
const lbl = t => `<label style="font-size:12px;color:var(--muted);display:block;margin:12px 0 4px">${t}</label>`;
|
|
3479
|
+
let overlay = document.getElementById('probeSettingsOverlay');
|
|
3467
3480
|
if (overlay) overlay.remove();
|
|
3468
3481
|
overlay = document.createElement('div');
|
|
3469
|
-
overlay.id = '
|
|
3482
|
+
overlay.id = 'probeSettingsOverlay';
|
|
3470
3483
|
overlay.style.cssText = 'position:fixed;inset:0;background:rgba(0,0,0,0.6);display:flex;align-items:center;justify-content:center;z-index:9999';
|
|
3471
3484
|
overlay.innerHTML = `
|
|
3472
|
-
<div style="background:var(--bg-card);border:1px solid var(--border);border-radius:12px;padding:24px 28px;width:
|
|
3473
|
-
<h3 style="margin:0 0
|
|
3474
|
-
<
|
|
3475
|
-
|
|
3476
|
-
|
|
3477
|
-
|
|
3478
|
-
|
|
3479
|
-
style="
|
|
3480
|
-
|
|
3481
|
-
|
|
3482
|
-
<div style="
|
|
3483
|
-
<
|
|
3484
|
-
|
|
3485
|
+
<div style="background:var(--bg-card);border:1px solid var(--border);border-radius:12px;padding:24px 28px;width:440px;max-width:90vw">
|
|
3486
|
+
<h3 style="margin:0 0 4px;font-size:16px;color:var(--text)">⚙️ Настройки Probe</h3>
|
|
3487
|
+
<div style="font-size:12px;color:var(--muted);margin-bottom:16px">Настройки сохраняются локально, не попадают в git</div>
|
|
3488
|
+
|
|
3489
|
+
<div style="border-bottom:1px solid var(--border);padding-bottom:16px;margin-bottom:4px">
|
|
3490
|
+
${lbl('Домен стенда')}
|
|
3491
|
+
<input id="probeTarget" type="text" placeholder="https://staging.myapp.com" value="${escapeHtml(saved.target || '')}" ${inp()}>
|
|
3492
|
+
<div style="font-size:11px;color:var(--muted);margin-top:4px">Все проверки будут запускаться на этом домене. Переопределяет target из probe.config.yml</div>
|
|
3493
|
+
</div>
|
|
3494
|
+
|
|
3495
|
+
<div style="margin-top:16px">
|
|
3496
|
+
<div style="font-size:12px;font-weight:600;color:var(--text);margin-bottom:8px">Telegram уведомления</div>
|
|
3497
|
+
${lbl('Bot Token')}
|
|
3498
|
+
<input id="probeBotToken" type="password" placeholder="1234567890:AAF..." value="${escapeHtml(tg.botToken || '')}" ${inp()}>
|
|
3499
|
+
${lbl('Chat ID')}
|
|
3500
|
+
<input id="probeChatId" type="text" placeholder="-1001234567890" value="${escapeHtml(tg.chatId || '')}" ${inp()}>
|
|
3501
|
+
<div style="font-size:11px;color:var(--muted);margin-top:4px">Токен у @BotFather · Chat ID через @userinfobot</div>
|
|
3502
|
+
</div>
|
|
3503
|
+
|
|
3504
|
+
<div id="probeSettingsErr" style="display:none;margin-top:12px;padding:8px 12px;border-radius:6px;background:rgba(248,81,73,0.1);color:var(--red);font-size:12px"></div>
|
|
3505
|
+
<div style="display:flex;gap:10px;justify-content:flex-end;margin-top:20px">
|
|
3506
|
+
<button onclick="document.getElementById('probeSettingsOverlay').remove()" style="padding:6px 16px;border-radius:6px;border:1px solid var(--border);background:var(--bg);color:var(--text);cursor:pointer;font-size:13px">Отмена</button>
|
|
3507
|
+
<button id="probeSettingsSave" style="padding:6px 16px;border-radius:6px;border:1px solid var(--blue);background:var(--blue);color:#fff;cursor:pointer;font-size:13px">Сохранить</button>
|
|
3485
3508
|
</div>
|
|
3486
3509
|
</div>`;
|
|
3487
3510
|
document.body.appendChild(overlay);
|
|
3488
3511
|
overlay.addEventListener('click', e => { if (e.target === overlay) overlay.remove(); });
|
|
3489
|
-
document.getElementById('
|
|
3512
|
+
document.getElementById('probeSettingsSave').addEventListener('click', async () => {
|
|
3513
|
+
const target = document.getElementById('probeTarget').value.trim();
|
|
3490
3514
|
const botToken = document.getElementById('probeBotToken').value.trim();
|
|
3491
3515
|
const chatId = document.getElementById('probeChatId').value.trim();
|
|
3492
|
-
const err = document.getElementById('
|
|
3493
|
-
|
|
3494
|
-
const btn = document.getElementById('probeNotifySave');
|
|
3516
|
+
const err = document.getElementById('probeSettingsErr');
|
|
3517
|
+
const btn = document.getElementById('probeSettingsSave');
|
|
3495
3518
|
btn.disabled = true; btn.textContent = 'Сохраняю…';
|
|
3496
3519
|
try {
|
|
3497
|
-
const res = await fetch('/api/probe/
|
|
3520
|
+
const res = await fetch('/api/probe/settings', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ target, botToken, chatId }) });
|
|
3498
3521
|
if (!res.ok) { const d = await res.json(); throw new Error(d.error || 'Ошибка сохранения'); }
|
|
3522
|
+
// Refresh probe data to show new target
|
|
3523
|
+
await loadProbeData();
|
|
3524
|
+
renderContent();
|
|
3499
3525
|
overlay.remove();
|
|
3500
3526
|
} catch (e) { err.style.display = 'block'; err.textContent = e.message; btn.disabled = false; btn.textContent = 'Сохранить'; }
|
|
3501
3527
|
});
|