mirror of
https://github.com/dartdavros/chatballs.git
synced 2026-10-05 01:14:58 +03:00
287 lines
34 KiB
HTML
287 lines
34 KiB
HTML
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<script src="./support.js"></script>
|
|
</head>
|
|
<body>
|
|
<x-dc>
|
|
<helmet>
|
|
<style>
|
|
*{box-sizing:border-box;}
|
|
html,body{margin:0;padding:0;}
|
|
::-webkit-scrollbar{width:10px;height:10px;}
|
|
::-webkit-scrollbar-thumb{background:#dcdcdc;border-radius:8px;border:2px solid #f0f2f5;background-clip:content-box;}
|
|
::-webkit-scrollbar-thumb:hover{background:#bfbfbf;background-clip:content-box;}
|
|
</style>
|
|
</helmet>
|
|
|
|
<div style="display:flex;height:100vh;overflow:hidden;background:#f0f2f5;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,'Helvetica Neue',Arial,sans-serif;color:#262626;-webkit-font-smoothing:antialiased;min-width:1120px;">
|
|
|
|
<!-- ============ SIDEBAR (уровень компании) ============ -->
|
|
<aside style="width:248px;flex:none;background:#ffffff;border-right:1px solid #f0f0f0;display:flex;flex-direction:column;height:100vh;">
|
|
<div style="height:56px;flex:none;display:flex;align-items:center;gap:11px;padding:0 20px;border-bottom:1px solid #f5f5f5;">
|
|
<div style="width:30px;height:30px;border-radius:8px;background:#1677ff;display:flex;align-items:center;justify-content:center;flex:none;"><svg viewBox="0 0 24 24" width="17" height="17" fill="none" stroke="#fff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 12h4l2 6 4-14 2 8h6"/></svg></div>
|
|
<div style="display:flex;flex-direction:column;line-height:1.15;"><span style="font-size:14px;font-weight:600;color:#1f1f1f;letter-spacing:-0.01em;">Edevs Hub</span><span style="font-size:11px;color:#8c8c8c;">Уровень компании</span></div>
|
|
</div>
|
|
<nav style="flex:1;overflow-y:auto;padding:12px 12px 8px;">
|
|
<a href="Командный центр.dc.html" style="display:flex;align-items:center;gap:11px;padding:9px 12px;border-radius:8px;color:#595959;font-size:13.5px;font-weight:500;text-decoration:none;margin-bottom:2px;" style-hover="background:#f5f5f5;color:#262626;"><svg viewBox="0 0 24 24" width="17" height="17" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="7" height="9" rx="1.4"/><rect x="14" y="3" width="7" height="5" rx="1.4"/><rect x="14" y="12" width="7" height="9" rx="1.4"/><rect x="3" y="16" width="7" height="5" rx="1.4"/></svg>Командный центр</a>
|
|
<div style="font-size:11px;font-weight:600;letter-spacing:0.06em;color:#bfbfbf;padding:14px 12px 6px;">КОМПАНИЯ</div>
|
|
<a href="Отделы.dc.html" style="display:flex;align-items:center;gap:11px;padding:9px 12px;border-radius:8px;color:#595959;font-size:13.5px;font-weight:500;text-decoration:none;margin-bottom:2px;" style-hover="background:#f5f5f5;color:#262626;"><svg viewBox="0 0 24 24" width="17" height="17" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"><path d="M3 21h18"/><path d="M5 21V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2v16"/><path d="M9 8h1.5M13.5 8H15M9 12h1.5M13.5 12H15M9 16h1.5M13.5 16H15"/></svg>Отделы</a>
|
|
<a href="Сотрудники.dc.html" style="display:flex;align-items:center;gap:11px;padding:9px 12px;border-radius:8px;color:#595959;font-size:13.5px;font-weight:500;text-decoration:none;margin-bottom:2px;" style-hover="background:#f5f5f5;color:#262626;"><svg viewBox="0 0 24 24" width="17" height="17" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"><path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M22 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 3.13a4 4 0 0 1 0 7.75"/></svg>Сотрудники</a>
|
|
<a href="Продукты.dc.html" style="display:flex;align-items:center;gap:11px;padding:9px 12px;border-radius:8px;color:#595959;font-size:13.5px;font-weight:500;text-decoration:none;margin-bottom:2px;" style-hover="background:#f5f5f5;color:#262626;"><svg viewBox="0 0 24 24" width="17" height="17" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"><path d="M21 8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16Z"/><path d="m3.3 7 8.7 5 8.7-5"/><path d="M12 22V12"/></svg>Продукты</a>
|
|
<div style="font-size:11px;font-weight:600;letter-spacing:0.06em;color:#bfbfbf;padding:14px 12px 6px;">ПЛАТФОРМА</div>
|
|
<a href="AI-агенты.dc.html" style="display:flex;align-items:center;gap:11px;padding:9px 12px;border-radius:8px;background:#e6f4ff;color:#0958d9;font-size:13.5px;font-weight:600;text-decoration:none;margin-bottom:2px;position:relative;"><span style="position:absolute;left:0;top:8px;bottom:8px;width:3px;border-radius:0 3px 3px 0;background:#1677ff;"></span><svg viewBox="0 0 24 24" width="17" height="17" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"><rect x="4" y="8" width="16" height="12" rx="2.5"/><path d="M12 8V4.5"/><circle cx="12" cy="3.5" r="1.2"/><circle cx="9" cy="13.5" r="1"/><circle cx="15" cy="13.5" r="1"/><path d="M2 13.5h2M20 13.5h2"/></svg>AI</a>
|
|
<a href="#" style="display:flex;align-items:center;gap:11px;padding:9px 12px;border-radius:8px;color:#595959;font-size:13.5px;font-weight:500;text-decoration:none;margin-bottom:2px;" style-hover="background:#f5f5f5;color:#262626;"><svg viewBox="0 0 24 24" width="17" height="17" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"><path d="M9 8V2.5M15 8V2.5M18 8v5.5a4 4 0 0 1-4 4h-4a4 4 0 0 1-4-4V8Z"/><path d="M12 17.5V22"/></svg>Интеграции</a>
|
|
<div style="height:1px;background:#f5f5f5;margin:14px 12px 10px;"></div>
|
|
<a href="#" style="display:flex;align-items:center;gap:11px;padding:9px 12px;border-radius:8px;color:#595959;font-size:13.5px;font-weight:500;text-decoration:none;margin-bottom:2px;" style-hover="background:#f5f5f5;color:#262626;"><svg viewBox="0 0 24 24" width="17" height="17" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"><line x1="21" y1="6" x2="9" y2="6"/><line x1="3" y1="6" x2="5" y2="6"/><circle cx="7" cy="6" r="2"/><line x1="21" y1="12" x2="13" y2="12"/><line x1="3" y1="12" x2="9" y2="12"/><circle cx="11" cy="12" r="2"/><line x1="21" y1="18" x2="15" y2="18"/><line x1="3" y1="18" x2="11" y2="18"/><circle cx="13" cy="18" r="2"/></svg>Настройки</a>
|
|
</nav>
|
|
<div style="flex:none;border-top:1px solid #f5f5f5;padding:10px 12px;">
|
|
<a href="#" style="display:flex;align-items:center;gap:11px;padding:8px 10px;border-radius:8px;text-decoration:none;" style-hover="background:#f5f5f5;"><div style="width:32px;height:32px;border-radius:50%;background:#1677ff;color:#fff;display:flex;align-items:center;justify-content:center;font-size:13px;font-weight:600;flex:none;">ИП</div><div style="display:flex;flex-direction:column;line-height:1.2;"><span style="font-size:13px;font-weight:600;color:#262626;">Иван Петров</span><span style="font-size:11px;color:#8c8c8c;">OWNER</span></div></a>
|
|
</div>
|
|
</aside>
|
|
|
|
<!-- ============ MAIN ============ -->
|
|
<div style="flex:1;min-width:0;display:flex;flex-direction:column;height:100vh;">
|
|
<header style="height:56px;flex:none;background:#ffffff;border-bottom:1px solid #f0f0f0;display:flex;align-items:center;justify-content:space-between;padding:0 24px;">
|
|
<div style="display:flex;align-items:center;gap:8px;font-size:13px;color:#8c8c8c;"><span style="font-weight:500;color:#595959;">AI</span><span style="color:#d9d9d9;">/</span><a href="Карточка AI-агента.dc.html" style="font-weight:500;color:#595959;text-decoration:none;" style-hover="color:#1677ff;">FirePage Sales</a><span style="color:#d9d9d9;">/</span><span style="font-weight:600;color:#262626;font-family:'SF Mono',ui-monospace,Menlo,monospace;">REL-FP-v5</span></div>
|
|
<div style="display:flex;align-items:center;gap:14px;">
|
|
<button style="position:relative;width:36px;height:36px;border-radius:8px;border:1px solid #f0f0f0;background:#fff;display:flex;align-items:center;justify-content:center;cursor:pointer;color:#595959;" style-hover="background:#f5f5f5;color:#262626;"><svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"><path d="M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9"/><path d="M10.3 21a1.94 1.94 0 0 0 3.4 0"/></svg><span style="position:absolute;top:6px;right:7px;width:8px;height:8px;border-radius:50%;background:#ff4d4f;border:1.5px solid #fff;"></span></button>
|
|
<div style="width:1px;height:24px;background:#f0f0f0;"></div>
|
|
<div style="width:28px;height:28px;border-radius:50%;background:#1677ff;color:#fff;display:flex;align-items:center;justify-content:center;font-size:12px;font-weight:600;">ИП</div>
|
|
</div>
|
|
</header>
|
|
|
|
<!-- STATUS BAR -->
|
|
<div style="flex:none;background:#fff;border-bottom:1px solid #f0f0f0;padding:14px 28px;display:flex;align-items:center;justify-content:space-between;gap:20px;">
|
|
<div style="display:flex;align-items:center;gap:13px;min-width:0;">
|
|
<div style="width:40px;height:40px;border-radius:10px;background:#f9f0ff;display:flex;align-items:center;justify-content:center;flex:none;"><svg viewBox="0 0 24 24" width="21" height="21" fill="none" stroke="#722ed1" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"><rect x="4" y="8" width="16" height="12" rx="2.5"/><path d="M12 8V4.5"/><circle cx="12" cy="3.5" r="1.2"/><circle cx="9" cy="13.5" r="1"/><circle cx="15" cy="13.5" r="1"/></svg></div>
|
|
<div style="min-width:0;">
|
|
<div style="display:flex;align-items:center;gap:10px;"><h1 style="margin:0;font-size:17px;font-weight:700;color:#1f1f1f;font-family:'SF Mono',ui-monospace,Menlo,monospace;">REL-FP-v5</h1><span style="display:inline-flex;align-items:center;gap:6px;padding:3px 11px;border-radius:14px;background:{{ st.bg }};border:1px solid {{ st.border }};font-size:11.5px;font-weight:600;color:{{ st.color }};"><span style="width:6px;height:6px;border-radius:50%;background:{{ st.dot }};"></span>{{ st.label }}</span></div>
|
|
<div style="font-size:12px;color:#8c8c8c;margin-top:2px;">FirePage Sales · candidate создан сегодня 11:20 · автор Иван Петров</div>
|
|
</div>
|
|
</div>
|
|
<div style="display:flex;align-items:center;gap:9px;flex:none;">
|
|
<button style="display:flex;align-items:center;gap:7px;height:38px;padding:0 14px;border-radius:9px;border:1px solid #d9d9d9;background:#fff;color:#262626;font-size:13px;font-weight:500;cursor:pointer;" style-hover="border-color:#1677ff;color:#1677ff;"><svg viewBox="0 0 24 24" width="15" height="15" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M16 3h5v5"/><path d="M8 3H3v5"/><path d="M21 3l-7 7"/><path d="M3 3l7 7"/><path d="M16 21h5v-5"/><path d="M8 21H3v-5"/><path d="M21 21l-7-7"/><path d="M3 21l7-7"/></svg>Сравнить с published</button>
|
|
<a href="Тестовый чат.dc.html" style="display:flex;align-items:center;gap:7px;height:38px;padding:0 14px;border-radius:9px;border:1px solid #d9d9d9;background:#fff;color:#262626;font-size:13px;font-weight:500;cursor:pointer;text-decoration:none;" style-hover="border-color:#1677ff;color:#1677ff;"><svg viewBox="0 0 24 24" width="15" height="15" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/></svg>Test chat</a>
|
|
<button onClick="{{ onPublish }}" style="{{ publishBtn }}"><svg viewBox="0 0 24 24" width="15" height="15" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M22 2 11 13"/><path d="M22 2 15 22l-4-9-9-4 20-7Z"/></svg>{{ publishLabel }}</button>
|
|
</div>
|
|
</div>
|
|
|
|
<main style="flex:1;overflow-y:auto;padding:20px 28px 40px;">
|
|
<div style="max-width:1180px;margin:0 auto;">
|
|
|
|
<!-- validation banner -->
|
|
<div style="display:flex;align-items:center;gap:11px;padding:12px 16px;border-radius:10px;margin-bottom:18px;background:{{ vb.bg }};border:1px solid {{ vb.border }};">
|
|
<span style="flex:none;">{{ vb.icon }}</span>
|
|
<div style="flex:1;min-width:0;"><div style="font-size:13px;font-weight:600;color:{{ vb.titleColor }};">{{ vb.title }}</div><div style="font-size:12px;color:#595959;margin-top:1px;">{{ vb.note }}</div></div>
|
|
<button style="height:32px;padding:0 13px;border-radius:8px;border:1px solid #d9d9d9;background:#fff;color:#262626;font-size:12.5px;font-weight:500;cursor:pointer;flex:none;" style-hover="border-color:#1677ff;color:#1677ff;">Запустить проверку</button>
|
|
</div>
|
|
|
|
<!-- 3-column layout: Состав | Проверки | Изменения -->
|
|
<div style="display:grid;grid-template-columns:1fr 320px;gap:18px;align-items:start;">
|
|
|
|
<!-- LEFT: Состав release -->
|
|
<div style="display:flex;flex-direction:column;gap:16px;">
|
|
<h2 style="margin:0;font-size:14px;font-weight:600;color:#595959;letter-spacing:0.01em;">Состав release</h2>
|
|
|
|
<!-- модель и параметры -->
|
|
<div style="background:#fff;border:1px solid #f0f0f0;border-radius:12px;box-shadow:0 1px 3px rgba(0,0,0,0.04);padding:16px 18px;">
|
|
<div style="display:flex;align-items:center;gap:9px;margin-bottom:13px;"><svg viewBox="0 0 24 24" width="17" height="17" fill="none" stroke="#722ed1" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><rect x="4" y="8" width="16" height="12" rx="2.5"/><path d="M12 8V4.5"/><circle cx="12" cy="3.5" r="1.2"/></svg><h3 style="margin:0;font-size:14px;font-weight:700;color:#1f1f1f;">Модель и параметры</h3></div>
|
|
<div style="display:grid;grid-template-columns:repeat(4,1fr);gap:14px;">
|
|
<div><div style="font-size:11px;color:#8c8c8c;">Модель</div><div style="font-size:13px;font-weight:600;color:#262626;margin-top:3px;font-family:'SF Mono',ui-monospace,Menlo,monospace;">gpt-4o-mini</div></div>
|
|
<div><div style="font-size:11px;color:#8c8c8c;">Temperature</div><div style="font-size:13px;font-weight:600;color:#262626;margin-top:3px;font-family:'SF Mono',ui-monospace,Menlo,monospace;">0.4</div></div>
|
|
<div><div style="font-size:11px;color:#8c8c8c;">Max tokens</div><div style="font-size:13px;font-weight:600;color:#262626;margin-top:3px;font-family:'SF Mono',ui-monospace,Menlo,monospace;">1024</div></div>
|
|
<div><div style="font-size:11px;color:#8c8c8c;">Top-p</div><div style="font-size:13px;font-weight:600;color:#262626;margin-top:3px;font-family:'SF Mono',ui-monospace,Menlo,monospace;">0.9</div></div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- версии prompts -->
|
|
<div style="background:#fff;border:1px solid #f0f0f0;border-radius:12px;box-shadow:0 1px 3px rgba(0,0,0,0.04);overflow:hidden;">
|
|
<div style="padding:14px 18px 11px;display:flex;align-items:center;gap:9px;"><svg viewBox="0 0 24 24" width="17" height="17" fill="none" stroke="#595959" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8Z"/><polyline points="14 2 14 8 20 8"/></svg><h3 style="margin:0;font-size:14px;font-weight:700;color:#1f1f1f;">Версии prompts</h3></div>
|
|
<sc-for list="{{ prompts }}" as="p" hint-placeholder-count="4">
|
|
<div style="display:flex;align-items:center;gap:12px;padding:11px 18px;border-top:1px solid #f5f5f5;">
|
|
<div style="flex:1;min-width:0;"><span style="font-size:13px;font-weight:500;color:#262626;">{{ p.name }}</span><span style="margin-left:8px;font-size:11px;color:#bfbfbf;font-family:'SF Mono',ui-monospace,Menlo,monospace;">{{ p.ver }}</span></div>
|
|
<sc-if value="{{ p.changed }}" hint-placeholder-val="{{ false }}"><span style="padding:1px 8px;border-radius:5px;background:#fff7e6;color:#d48806;font-size:10.5px;font-weight:600;">изменён</span></sc-if>
|
|
<span style="font-size:11.5px;color:#bfbfbf;width:90px;text-align:right;">{{ p.updated }}</span>
|
|
</div>
|
|
</sc-for>
|
|
</div>
|
|
|
|
<!-- обязательные знания + retrieval -->
|
|
<div style="background:#fff;border:1px solid #f0f0f0;border-radius:12px;box-shadow:0 1px 3px rgba(0,0,0,0.04);overflow:hidden;">
|
|
<div style="padding:14px 18px 11px;display:flex;align-items:center;justify-content:space-between;"><div style="display:flex;align-items:center;gap:9px;"><svg viewBox="0 0 24 24" width="17" height="17" fill="none" stroke="#595959" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"/><path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2Z"/></svg><h3 style="margin:0;font-size:14px;font-weight:700;color:#1f1f1f;">Обязательные знания</h3></div><span style="font-size:11.5px;color:#8c8c8c;">retrieval index · <b style="color:#389e0d;">собран</b></span></div>
|
|
<sc-for list="{{ knowledge }}" as="k" hint-placeholder-count="3">
|
|
<div style="display:flex;align-items:center;gap:11px;padding:10px 18px;border-top:1px solid #f5f5f5;">
|
|
<svg viewBox="0 0 24 24" width="15" height="15" fill="none" stroke="#389e0d" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="flex:none;"><path d="M20 6 9 17l-5-5"/></svg>
|
|
<span style="flex:1;font-size:13px;color:#262626;">{{ k.title }}</span>
|
|
<span style="font-size:11px;color:#bfbfbf;font-family:'SF Mono',ui-monospace,Menlo,monospace;">{{ k.ver }}</span>
|
|
</div>
|
|
</sc-for>
|
|
</div>
|
|
|
|
<!-- инструменты + лимиты -->
|
|
<div style="display:grid;grid-template-columns:1fr 1fr;gap:16px;">
|
|
<div style="background:#fff;border:1px solid #f0f0f0;border-radius:12px;box-shadow:0 1px 3px rgba(0,0,0,0.04);padding:16px 18px;">
|
|
<h3 style="margin:0 0 12px;font-size:14px;font-weight:700;color:#1f1f1f;">Инструменты</h3>
|
|
<div style="display:flex;flex-direction:column;gap:8px;">
|
|
<div style="display:flex;align-items:center;gap:8px;"><svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="#389e0d" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6 9 17l-5-5"/></svg><span style="font-size:12.5px;color:#595959;font-family:'SF Mono',ui-monospace,Menlo,monospace;">create_checkout</span></div>
|
|
<div style="display:flex;align-items:center;gap:8px;"><svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="#389e0d" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6 9 17l-5-5"/></svg><span style="font-size:12.5px;color:#595959;font-family:'SF Mono',ui-monospace,Menlo,monospace;">get_offers</span></div>
|
|
<div style="display:flex;align-items:center;gap:8px;"><svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="#389e0d" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6 9 17l-5-5"/></svg><span style="font-size:12.5px;color:#595959;font-family:'SF Mono',ui-monospace,Menlo,monospace;">handoff_to_operator</span></div>
|
|
</div>
|
|
</div>
|
|
<div style="background:#fff;border:1px solid #f0f0f0;border-radius:12px;box-shadow:0 1px 3px rgba(0,0,0,0.04);padding:16px 18px;">
|
|
<h3 style="margin:0 0 12px;font-size:14px;font-weight:700;color:#1f1f1f;">Лимиты</h3>
|
|
<div style="display:flex;align-items:center;justify-content:space-between;padding:5px 0;"><span style="font-size:12.5px;color:#8c8c8c;">Диалогов в день</span><span style="font-size:12.5px;font-weight:600;color:#262626;">5 000</span></div>
|
|
<div style="display:flex;align-items:center;justify-content:space-between;padding:5px 0;"><span style="font-size:12.5px;color:#8c8c8c;">Бюджет в день</span><span style="font-size:12.5px;font-weight:600;color:#262626;">₽5 000</span></div>
|
|
<div style="display:flex;align-items:center;justify-content:space-between;padding:5px 0;"><span style="font-size:12.5px;color:#8c8c8c;">Макс. сообщений / диалог</span><span style="font-size:12.5px;font-weight:600;color:#262626;">40</span></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- RIGHT: Проверки + Изменения -->
|
|
<div style="display:flex;flex-direction:column;gap:16px;">
|
|
<!-- Проверки -->
|
|
<div style="background:#fff;border:1px solid #f0f0f0;border-radius:12px;box-shadow:0 1px 3px rgba(0,0,0,0.04);overflow:hidden;">
|
|
<div style="padding:14px 18px 11px;display:flex;align-items:center;justify-content:space-between;"><h3 style="margin:0;font-size:14px;font-weight:700;color:#1f1f1f;">Проверки</h3><span style="font-size:11.5px;font-weight:600;color:{{ checksColor }};">{{ checksSummary }}</span></div>
|
|
<sc-for list="{{ checks }}" as="c" hint-placeholder-count="5">
|
|
<div style="display:flex;align-items:flex-start;gap:10px;padding:10px 18px;border-top:1px solid #f5f5f5;">
|
|
<span style="flex:none;margin-top:1px;">{{ c.icon }}</span>
|
|
<div style="flex:1;min-width:0;"><div style="font-size:12.5px;font-weight:500;color:#262626;">{{ c.label }}</div><sc-if value="{{ c.detail }}" hint-placeholder-val="{{ false }}"><div style="font-size:11px;color:{{ c.detailColor }};margin-top:1px;">{{ c.detail }}</div></sc-if></div>
|
|
</div>
|
|
</sc-for>
|
|
</div>
|
|
|
|
<!-- Изменения -->
|
|
<div style="background:#fff;border:1px solid #f0f0f0;border-radius:12px;box-shadow:0 1px 3px rgba(0,0,0,0.04);overflow:hidden;">
|
|
<div style="padding:14px 18px 11px;"><h3 style="margin:0;font-size:14px;font-weight:700;color:#1f1f1f;">Изменения</h3><div style="font-size:11.5px;color:#bfbfbf;margin-top:2px;">Относительно REL-FP-v4 (published)</div></div>
|
|
<sc-for list="{{ changes }}" as="ch" hint-placeholder-count="3">
|
|
<div style="display:flex;align-items:flex-start;gap:10px;padding:10px 18px;border-top:1px solid #f5f5f5;">
|
|
<span style="width:18px;height:18px;border-radius:5px;background:{{ ch.bg }};color:{{ ch.color }};font-size:13px;font-weight:700;display:inline-flex;align-items:center;justify-content:center;flex:none;line-height:1;">{{ ch.sign }}</span>
|
|
<div style="flex:1;min-width:0;"><div style="font-size:12.5px;color:#262626;line-height:1.4;">{{ ch.text }}</div></div>
|
|
</div>
|
|
</sc-for>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
</main>
|
|
</div>
|
|
|
|
<!-- PUBLISH CONFIRM MODAL -->
|
|
<sc-if value="{{ modalOpen }}" hint-placeholder-val="{{ false }}">
|
|
<div style="position:fixed;inset:0;z-index:50;background:rgba(0,0,0,0.45);display:flex;align-items:center;justify-content:center;padding:20px;">
|
|
<div style="width:480px;max-width:100%;background:#fff;border-radius:14px;box-shadow:0 20px 60px rgba(0,0,0,0.3);overflow:hidden;">
|
|
<div style="padding:22px 24px 18px;">
|
|
<div style="display:flex;align-items:center;gap:12px;margin-bottom:14px;">
|
|
<div style="width:42px;height:42px;border-radius:11px;background:#fff7e6;display:flex;align-items:center;justify-content:center;flex:none;"><svg viewBox="0 0 24 24" width="22" height="22" fill="none" stroke="#d48806" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><path d="m21.7 18-8-14a2 2 0 0 0-3.5 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.7-3Z"/><line x1="12" y1="9" x2="12" y2="13"/><line x1="12" y1="17" x2="12.01" y2="17"/></svg></div>
|
|
<div><h3 style="margin:0;font-size:17px;font-weight:700;color:#1f1f1f;">Опубликовать REL-FP-v5?</h3><div style="font-size:12.5px;color:#8c8c8c;margin-top:2px;">Атомарная публикация конфигурации FirePage Sales</div></div>
|
|
</div>
|
|
<div style="background:#fffbe6;border:1px solid #ffe58f;border-radius:10px;padding:13px 15px;font-size:13px;color:#7c5a00;line-height:1.55;">Новые ответы во <b>всех активных диалогах</b> сразу будут использовать этот release. Текущий REL-FP-v4 перейдёт в архив. Действие необратимо в части уже отправленных ответов.</div>
|
|
<div style="display:flex;align-items:center;gap:10px;margin-top:16px;padding:11px 13px;background:#fafafa;border:1px solid #f0f0f0;border-radius:9px;">
|
|
<div role="checkbox" onClick="{{ onToggleConfirm }}" style="{{ confirmBox }}"><sc-if value="{{ confirmChecked }}" hint-placeholder-val="{{ false }}"><svg viewBox="0 0 24 24" width="12" height="12" fill="none" stroke="#fff" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6 9 17l-5-5"/></svg></sc-if></div>
|
|
<span onClick="{{ onToggleConfirm }}" style="font-size:12.5px;color:#262626;cursor:pointer;user-select:none;">Понимаю, что активные диалоги переключатся на новый release</span>
|
|
</div>
|
|
</div>
|
|
<div style="display:flex;justify-content:flex-end;gap:10px;padding:14px 24px;border-top:1px solid #f5f5f5;background:#fafbfc;">
|
|
<button onClick="{{ onCancelPublish }}" style="height:38px;padding:0 16px;border-radius:9px;border:1px solid #d9d9d9;background:#fff;color:#595959;font-size:13px;font-weight:500;cursor:pointer;" style-hover="border-color:#bfbfbf;color:#262626;">Отмена</button>
|
|
<button style="{{ confirmPublishBtn }}"><svg viewBox="0 0 24 24" width="15" height="15" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M22 2 11 13"/><path d="M22 2 15 22l-4-9-9-4 20-7Z"/></svg>Опубликовать release</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</sc-if>
|
|
</div>
|
|
</x-dc>
|
|
<script type="text/x-dc" data-dc-script data-props="{
|
|
"$preview": { "width": 1440, "height": 940 },
|
|
"releaseState": { "editor": "enum", "options": ["incomplete", "errors", "ready_test", "ready_publish", "published"], "default": "ready_publish", "tsType": "string" }
|
|
}">
|
|
class Component extends DCLogic {
|
|
state = { modalOpen: false, confirmChecked: false };
|
|
|
|
renderVals() {
|
|
const S = this.props.releaseState ?? 'ready_publish';
|
|
const st = {
|
|
incomplete: { label: 'Неполный candidate', color: '#8c8c8c', bg: '#f5f5f5', border: '#e8e8e8', dot: '#bfbfbf' },
|
|
errors: { label: 'Ошибки валидации', color: '#cf1322', bg: '#fff2f0', border: '#ffccc7', dot: '#ff4d4f' },
|
|
ready_test: { label: 'Готов к тестированию', color: '#0958d9', bg: '#e6f4ff', border: '#91caff', dot: '#1677ff' },
|
|
ready_publish:{ label: 'Готов к публикации', color: '#389e0d', bg: '#f6ffed', border: '#b7eb8f', dot: '#52c41a' },
|
|
published: { label: 'Published', color: '#389e0d', bg: '#f6ffed', border: '#b7eb8f', dot: '#52c41a' },
|
|
}[S];
|
|
|
|
const ok = (color) => React.createElement('svg', { viewBox: '0 0 24 24', width: 16, height: 16, fill: 'none', stroke: color || '#52c41a', strokeWidth: 2.2, strokeLinecap: 'round', strokeLinejoin: 'round' }, React.createElement('circle', { cx: 12, cy: 12, r: 10 }), React.createElement('path', { d: 'M8 12l3 3 5-6' }));
|
|
const err = React.createElement('svg', { viewBox: '0 0 24 24', width: 16, height: 16, fill: 'none', stroke: '#ff4d4f', strokeWidth: 2.2, strokeLinecap: 'round', strokeLinejoin: 'round' }, React.createElement('circle', { cx: 12, cy: 12, r: 10 }), React.createElement('line', { x1: 15, y1: 9, x2: 9, y2: 15 }), React.createElement('line', { x1: 9, y1: 9, x2: 15, y2: 15 }));
|
|
const warn = React.createElement('svg', { viewBox: '0 0 24 24', width: 16, height: 16, fill: 'none', stroke: '#faad14', strokeWidth: 2, strokeLinecap: 'round', strokeLinejoin: 'round' }, React.createElement('circle', { cx: 12, cy: 12, r: 10 }), React.createElement('line', { x1: 12, y1: 8, x2: 12, y2: 12 }), React.createElement('line', { x1: 12, y1: 16, x2: 12.01, y2: 16 }));
|
|
const pending = React.createElement('svg', { viewBox: '0 0 24 24', width: 16, height: 16, fill: 'none', stroke: '#bfbfbf', strokeWidth: 2, strokeLinecap: 'round', strokeLinejoin: 'round' }, React.createElement('circle', { cx: 12, cy: 12, r: 10 }));
|
|
|
|
const hasErrors = S === 'errors';
|
|
const checks = [
|
|
{ label: 'Системный prompt задан', icon: ok() },
|
|
{ label: 'Обязательные знания в индексе', icon: ok() },
|
|
{ label: 'Retrieval index собран', icon: ok() },
|
|
hasErrors
|
|
? { label: 'Инструменты сконфигурированы', detail: 'create_checkout: не задан Offer по умолчанию', detailColor: '#cf1322', icon: err }
|
|
: { label: 'Инструменты сконфигурированы', icon: ok() },
|
|
{ label: 'Лимиты в допустимых границах', icon: ok() },
|
|
S === 'incomplete'
|
|
? { label: 'Sales behavior заполнен', detail: 'раздел пуст', detailColor: '#d48806', icon: warn }
|
|
: { label: 'Sales behavior заполнен', icon: ok() },
|
|
];
|
|
const checksColor = hasErrors ? '#cf1322' : S === 'incomplete' ? '#d48806' : '#389e0d';
|
|
const checksSummary = hasErrors ? '1 ошибка' : S === 'incomplete' ? '1 предупреждение' : 'Все пройдены';
|
|
|
|
const vb = hasErrors
|
|
? { bg: '#fff2f0', border: '#ffccc7', titleColor: '#cf1322', title: 'Найдены ошибки валидации', note: 'Исправьте отмеченные пункты в составе release, затем перезапустите проверку.', icon: err }
|
|
: S === 'incomplete'
|
|
? { bg: '#fffbe6', border: '#ffe58f', titleColor: '#d48806', title: 'Candidate неполный', note: 'Заполните обязательные разделы, чтобы перейти к проверке.', icon: warn }
|
|
: S === 'ready_test'
|
|
? { bg: '#e6f4ff', border: '#91caff', titleColor: '#0958d9', title: 'Готов к тестированию', note: 'Проверки пройдены. Запустите test chat перед публикацией.', icon: ok('#1677ff') }
|
|
: { bg: '#f6ffed', border: '#b7eb8f', titleColor: '#389e0d', title: 'Готов к публикации', note: 'Все проверки пройдены, протестировано в test chat. Можно публиковать.', icon: ok() };
|
|
|
|
const prompts = [
|
|
{ name: 'Системный prompt', ver: 'v5', changed: true, updated: 'сегодня' },
|
|
{ name: 'Qualification', ver: 'v4', changed: false, updated: '01 июня' },
|
|
{ name: 'Sales behavior', ver: 'v5', changed: true, updated: 'сегодня' },
|
|
{ name: 'Ограничения', ver: 'v4', changed: false, updated: '01 июня' },
|
|
];
|
|
const knowledge = [
|
|
{ title: 'Что входит в коробку FirePage', ver: 'v3' },
|
|
{ title: 'Условия годовой поддержки', ver: 'v2' },
|
|
{ title: 'Частые возражения и ответы', ver: 'v2' },
|
|
];
|
|
const changes = [
|
|
{ sign: '~', bg: '#fff7e6', color: '#d48806', text: 'Системный prompt: уточнён тон и правило передачи оператору.' },
|
|
{ sign: '~', bg: '#fff7e6', color: '#d48806', text: 'Sales behavior: добавлено оформление checkout сразу после подтверждения.' },
|
|
{ sign: '+', bg: '#f6ffed', color: '#389e0d', text: 'Знания: добавлен материал «Частые возражения и ответы».' },
|
|
];
|
|
|
|
const canPublish = S === 'ready_publish';
|
|
const publishBtn = canPublish
|
|
? 'display:flex;align-items:center;gap:7px;height:38px;padding:0 18px;border-radius:9px;border:none;background:#1677ff;color:#fff;font-size:13.5px;font-weight:600;cursor:pointer;box-shadow:0 1px 2px rgba(22,119,255,0.3);'
|
|
: 'display:flex;align-items:center;gap:7px;height:38px;padding:0 18px;border-radius:9px;border:none;background:#f0f0f0;color:#bfbfbf;font-size:13.5px;font-weight:600;cursor:not-allowed;';
|
|
const publishLabel = S === 'published' ? 'Опубликован' : 'Опубликовать';
|
|
|
|
const confirmChecked = this.state.confirmChecked;
|
|
const confirmBox = confirmChecked
|
|
? 'width:18px;height:18px;border-radius:5px;border:1.5px solid #1677ff;background:#1677ff;display:flex;align-items:center;justify-content:center;flex:none;cursor:pointer;'
|
|
: 'width:18px;height:18px;border-radius:5px;border:1.5px solid #d9d9d9;background:#fff;display:flex;align-items:center;justify-content:center;flex:none;cursor:pointer;';
|
|
const confirmPublishBtn = confirmChecked
|
|
? 'display:flex;align-items:center;gap:7px;height:38px;padding:0 18px;border-radius:9px;border:none;background:#1677ff;color:#fff;font-size:13px;font-weight:600;cursor:pointer;'
|
|
: 'display:flex;align-items:center;gap:7px;height:38px;padding:0 18px;border-radius:9px;border:none;background:#f0f0f0;color:#bfbfbf;font-size:13px;font-weight:600;cursor:not-allowed;';
|
|
|
|
return {
|
|
st, vb, checks, checksColor, checksSummary, prompts, knowledge, changes,
|
|
publishBtn, publishLabel,
|
|
modalOpen: this.state.modalOpen, confirmChecked, confirmBox, confirmPublishBtn,
|
|
onPublish: () => { if (canPublish) this.setState({ modalOpen: true, confirmChecked: false }); },
|
|
onCancelPublish: () => this.setState({ modalOpen: false }),
|
|
onToggleConfirm: () => this.setState((s) => ({ confirmChecked: !s.confirmChecked })),
|
|
};
|
|
}
|
|
}
|
|
</script>
|
|
</body>
|
|
</html>
|