325 lines
23 KiB
HTML
325 lines
23 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="ru" class="h-full bg-slate-100">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>SCUD Orion AI Assistant</title>
|
||
<script src="https://cdn.tailwindcss.com"></script>
|
||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
||
<link rel="icon" href="/favicon.ico" type="image/x-icon">
|
||
<style>
|
||
* { overflow-anchor: none !important; }
|
||
#chat-messages-container, main { overflow-anchor: none !important; }
|
||
#chat-messages-container { padding-bottom: clamp(400px, 85vh, 900px) !important; }
|
||
|
||
/* ⭐️ Комфортный размер шрифта в стиле Gemini */
|
||
#chat-messages-container .message-content,
|
||
#chat-messages-container .text-sm,
|
||
#chat-messages-container .text-xs,
|
||
#chat-messages-container p,
|
||
#chat-messages-container li {
|
||
font-size: 16px !important;
|
||
line-height: 1.65 !important;
|
||
color: #1e293b !important; /* slate-800 */
|
||
}
|
||
|
||
#chat-messages-container .user-chat-bubble .text-sm,
|
||
#chat-messages-container .user-chat-bubble p,
|
||
#chat-messages-container .user-chat-bubble div {
|
||
font-size: 16px !important;
|
||
line-height: 1.6 !important;
|
||
color: #ffffff !important;
|
||
}
|
||
|
||
#chat-messages-container pre,
|
||
#chat-messages-container code {
|
||
font-size: 14.5px !important;
|
||
line-height: 1.5 !important;
|
||
}
|
||
|
||
.user-chat-bubble { scroll-margin-top: 24px !important; }
|
||
</style>
|
||
</head>
|
||
<body class="h-full flex flex-col font-sans antialiased text-slate-800 bg-slate-100 selection:bg-indigo-500 selection:text-white">
|
||
|
||
<div id="app-container" class="flex-1 flex overflow-hidden w-full h-full">
|
||
|
||
<!-- ЛЕВАЯ КОЛОНКА (САЙДБАР) -->
|
||
<aside class="w-[420px] md:w-[500px] bg-white border-r border-slate-200 flex flex-col shrink-0 h-full shadow-sm z-10 select-none">
|
||
|
||
<!-- НАВИГАЦИОННЫЙ ТАБ-БАР -->
|
||
<div class="flex items-center justify-between border-b border-slate-200 bg-white px-1 py-1 shrink-0">
|
||
<button data-tab="tasks" class="sidebar-tab-btn flex-1 py-2 text-center text-xs border-b-2 border-transparent text-slate-500 hover:text-indigo-600 transition">
|
||
<i class="fa-solid fa-list-check block text-sm mb-0.5"></i> Задачи
|
||
</button>
|
||
<button data-tab="snapshots" class="sidebar-tab-btn flex-1 py-2 text-center text-xs border-b-2 border-transparent text-slate-500 hover:text-indigo-600 transition">
|
||
<i class="fa-solid fa-camera block text-sm mb-0.5"></i> Срезы
|
||
</button>
|
||
<button data-tab="registries" class="sidebar-tab-btn flex-1 py-2 text-center text-xs border-b-2 border-transparent text-slate-500 hover:text-indigo-600 transition">
|
||
<i class="fa-solid fa-address-book block text-sm mb-0.5"></i> Реестры
|
||
</button>
|
||
<button data-tab="prompts" class="sidebar-tab-btn flex-1 py-2 text-center text-xs border-b-2 border-transparent text-slate-500 hover:text-indigo-600 transition">
|
||
<i class="fa-solid fa-terminal block text-sm mb-0.5"></i> Промпт
|
||
</button>
|
||
<button data-tab="context" class="sidebar-tab-btn flex-1 py-2 text-center text-xs border-b-2 border-transparent text-slate-500 hover:text-indigo-600 transition">
|
||
<i class="fa-solid fa-comments block text-sm mb-0.5"></i> Контекст
|
||
</button>
|
||
</div>
|
||
|
||
<!-- РАБОЧИЕ ОБЛАСТИ ВКЛАДОК -->
|
||
<div class="flex-1 overflow-y-auto p-2 flex flex-col gap-2">
|
||
<!-- 1. ЗАДАЧИ -->
|
||
<div id="sidebar-view-tasks" class="sidebar-view w-full h-full flex flex-col">
|
||
<div id="tasks-list" class="space-y-2 flex-1"></div>
|
||
</div>
|
||
|
||
<!-- 2. СРЕЗЫ И ОТЧЕТЫ -->
|
||
<div id="sidebar-view-snapshots" class="sidebar-view w-full space-y-3 hidden">
|
||
|
||
<!-- ПЕРИОД ВЫБОРКИ СРЕЗОВ -->
|
||
<div class="p-2.5 bg-slate-50 rounded-xl border border-slate-200 shadow-xs space-y-2">
|
||
<div class="flex items-center justify-between">
|
||
<span class="text-[11px] font-bold text-slate-600 uppercase flex items-center gap-1.5">
|
||
<i class="fa-regular fa-calendar text-indigo-500"></i> Период срезов:
|
||
</span>
|
||
<button onclick="loadSnapshotsView()" class="text-xs text-indigo-600 hover:text-indigo-800 font-semibold flex items-center gap-1 transition">
|
||
<i class="fa-solid fa-rotate-right text-[10px]"></i> Найти
|
||
</button>
|
||
</div>
|
||
<div class="grid grid-cols-2 gap-2">
|
||
<div>
|
||
<label class="text-[10px] text-slate-400 block mb-0.5">С даты:</label>
|
||
<input type="date" id="snapshots-date-from" onchange="loadSnapshotsView()"
|
||
class="w-full text-xs px-2 py-1.5 bg-white border border-slate-200 rounded-lg text-slate-700 font-mono focus:outline-none focus:border-indigo-500 cursor-pointer">
|
||
</div>
|
||
<div>
|
||
<label class="text-[10px] text-slate-400 block mb-0.5">По дату:</label>
|
||
<input type="date" id="snapshots-date-to" onchange="loadSnapshotsView()"
|
||
class="w-full text-xs px-2 py-1.5 bg-white border border-slate-200 rounded-lg text-slate-700 font-mono focus:outline-none focus:border-indigo-500 cursor-pointer">
|
||
</div>
|
||
</div>
|
||
<div class="flex items-center gap-1.5 pt-1 border-t border-slate-200/60">
|
||
<button onclick="setSnapshotDatePreset('today')" class="px-2 py-0.5 text-[11px] bg-white border border-slate-200 hover:bg-slate-100 rounded-md text-slate-600 font-medium transition shadow-2xs">
|
||
Сегодня
|
||
</button>
|
||
<button onclick="setSnapshotDatePreset('yesterday')" class="px-2 py-0.5 text-[11px] bg-white border border-slate-200 hover:bg-slate-100 rounded-md text-slate-600 font-medium transition shadow-2xs">
|
||
Вчера
|
||
</button>
|
||
<button onclick="setSnapshotDatePreset('days3')" class="px-2 py-0.5 text-[11px] bg-white border border-slate-200 hover:bg-slate-100 rounded-md text-slate-600 font-medium transition shadow-2xs">
|
||
3 дня
|
||
</button>
|
||
<button onclick="setSnapshotDatePreset('days7')" class="px-2 py-0.5 text-[11px] bg-white border border-slate-200 hover:bg-slate-100 rounded-md text-slate-600 font-medium transition shadow-2xs">
|
||
7 дней
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Панель создания срезов -->
|
||
<div class="p-3 bg-white rounded-xl border border-slate-200 shadow-xs space-y-2">
|
||
<div class="text-[11px] font-bold text-slate-600 uppercase flex items-center gap-1.5">
|
||
<i class="fa-regular fa-clock text-indigo-500"></i> Создать срез на дату/время:
|
||
</div>
|
||
<div class="grid grid-cols-2 gap-2">
|
||
<input type="text" id="manual-snapshot-date" placeholder="ДД.ММ.ГГГГ" class="text-xs px-2.5 py-1.5 border border-slate-200 rounded-lg text-center font-mono">
|
||
<input type="text" id="manual-snapshot-time" placeholder="ЧЧ:ММ" class="text-xs px-2.5 py-1.5 border border-slate-200 rounded-lg text-center font-mono">
|
||
</div>
|
||
<button id="btn-create-snapshot" onclick="createSnapshotManual()" class="w-full py-2 bg-indigo-600 hover:bg-indigo-700 text-white rounded-lg text-xs font-bold transition flex items-center justify-center gap-1.5">
|
||
<i class="fa-solid fa-camera"></i> Сделать срез
|
||
</button>
|
||
</div>
|
||
|
||
<!-- Панель On-Demand генерации отчетов -->
|
||
<div class="p-3 bg-white rounded-xl border border-slate-200 shadow-xs space-y-2">
|
||
<div class="text-[11px] font-bold text-slate-700 uppercase flex items-center gap-1.5">
|
||
<i class="fa-solid fa-file-excel text-emerald-600"></i> Сформировать отчет:
|
||
</div>
|
||
<div class="grid grid-cols-3 gap-1.5">
|
||
<button onclick="generateReportDirect('SVODKA')" class="py-2 bg-emerald-50 hover:bg-emerald-100 text-emerald-700 border border-emerald-200 rounded-lg text-[10px] font-bold transition flex items-center justify-center gap-1">
|
||
<i class="fa-solid fa-table-list"></i> Сводка
|
||
</button>
|
||
<button onclick="generateReportDirect('SIMPLIFIED')" class="py-2 bg-indigo-50 hover:bg-indigo-100 text-indigo-700 border border-indigo-200 rounded-lg text-[10px] font-bold transition flex items-center justify-center gap-1">
|
||
<i class="fa-solid fa-file-lines"></i> Упрощ.
|
||
</button>
|
||
<button onclick="generateReportDirect('DETAILED')" class="py-2 bg-purple-50 hover:bg-purple-100 text-purple-700 border border-purple-200 rounded-lg text-[10px] font-bold transition flex items-center justify-center gap-1">
|
||
<i class="fa-solid fa-chart-column"></i> Детальн.
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="flex items-center justify-between pt-1">
|
||
<span id="snapshots-count-badge" class="text-xs font-bold text-slate-700">Срезы в базе: 0</span>
|
||
<button onclick="loadSnapshotsView()" class="text-slate-400 hover:text-indigo-600 text-xs transition" title="Обновить список">
|
||
<i class="fa-solid fa-rotate-right"></i>
|
||
</button>
|
||
</div>
|
||
<div id="snapshots-list" class="space-y-2"></div>
|
||
</div>
|
||
|
||
<!-- 3. РЕЕСТРЫ -->
|
||
<div id="sidebar-view-registries" class="sidebar-view w-full space-y-3 hidden">
|
||
<div class="grid grid-cols-2 gap-1 p-1 bg-slate-200/60 rounded-xl">
|
||
<button data-subtab="exceptions" onclick="switchRegistrySubTab('exceptions')" class="registry-subtab-btn py-1 text-[11px] rounded-lg transition text-center flex items-center justify-center gap-1">
|
||
<i class="fa-solid fa-user-shield text-[10px]"></i> Исключения
|
||
</button>
|
||
<button data-subtab="remote" onclick="switchRegistrySubTab('remote')" class="registry-subtab-btn py-1 text-[11px] rounded-lg transition text-center flex items-center justify-center gap-1">
|
||
<i class="fa-solid fa-house-laptop text-[10px]"></i> Удаленщики
|
||
</button>
|
||
<button data-subtab="local_trip" onclick="switchRegistrySubTab('local_trip')" class="registry-subtab-btn py-1 text-[11px] rounded-lg transition text-center flex items-center justify-center gap-1">
|
||
<i class="fa-solid fa-location-dot text-[10px]"></i> Мест. командир.
|
||
</button>
|
||
<button data-subtab="other" onclick="switchRegistrySubTab('other')" class="registry-subtab-btn py-1 text-[11px] rounded-lg transition text-center flex items-center justify-center gap-1">
|
||
<i class="fa-solid fa-clipboard-question text-[10px]"></i> Иное
|
||
</button>
|
||
</div>
|
||
<div id="registry-content-container" class="space-y-3"></div>
|
||
</div>
|
||
|
||
<!-- 4. ПРОМПТ -->
|
||
<div id="sidebar-view-prompts" class="sidebar-view w-full space-y-3 hidden">
|
||
<div class="flex items-center justify-between pb-1 border-b border-slate-200">
|
||
<span class="text-xs font-bold text-slate-800">Системный промпт (Ollama)</span>
|
||
<button onclick="loadPromptsView()" class="text-slate-400 hover:text-indigo-600 text-xs transition" title="Обновить">
|
||
<i class="fa-solid fa-rotate-right"></i>
|
||
</button>
|
||
</div>
|
||
<div id="prompts-content-container" class="space-y-2"></div>
|
||
</div>
|
||
|
||
<!-- 5. КОНТЕКСТ -->
|
||
<div id="sidebar-view-context" class="sidebar-view w-full space-y-3 hidden">
|
||
<div class="flex items-center justify-between pb-1 border-b border-slate-200">
|
||
<span class="text-xs font-bold text-slate-800">Мониторинг сессии</span>
|
||
<button onclick="loadContextView()" class="text-slate-400 hover:text-indigo-600 text-xs transition" title="Обновить">
|
||
<i class="fa-solid fa-rotate-right"></i>
|
||
</button>
|
||
</div>
|
||
<div id="context-content-container" class="space-y-2"></div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ПОДВАЛ -->
|
||
<div class="p-3 border-t border-slate-200 bg-slate-50 flex items-center justify-between shrink-0">
|
||
<div class="flex items-center gap-2.5 min-w-0">
|
||
<div class="w-8 h-8 rounded-full bg-indigo-600 text-white flex items-center justify-center font-bold text-xs shadow-sm shrink-0">
|
||
<i class="fa-solid fa-user"></i>
|
||
</div>
|
||
<div class="min-w-0 flex flex-col">
|
||
<span id="user-display-name" class="text-xs font-bold text-slate-800 truncate">Пользователь</span>
|
||
<span id="user-display-role" class="text-[10px] text-slate-400">Оператор</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="flex items-center gap-1">
|
||
<button id="admin-panel-btn" type="button" onclick="openAdminModal()" class="hidden p-1.5 text-slate-400 hover:text-indigo-600 hover:bg-slate-200 rounded-lg transition" title="Управление пользователями">
|
||
<i class="fa-solid fa-users-gear text-sm"></i>
|
||
</button>
|
||
<button type="button" onclick="openProfileModal()" class="p-1.5 text-slate-400 hover:text-slate-700 hover:bg-slate-200 rounded-lg transition" title="Сменить пароль">
|
||
<i class="fa-solid fa-gear text-sm"></i>
|
||
</button>
|
||
<button type="button" onclick="AuthManager.logout()" class="p-1.5 text-slate-400 hover:text-rose-600 hover:bg-rose-50 rounded-lg transition" title="Выйти из системы">
|
||
<i class="fa-solid fa-arrow-right-from-bracket text-sm"></i>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</aside>
|
||
|
||
<!-- ПРАВАЯ ОБЛАСТЬ (ЧАТ И ИИ-АССИСТЕНТ) -->
|
||
<main class="flex-1 flex flex-col h-full min-w-0 bg-slate-50 relative">
|
||
<header class="h-14 bg-white border-b border-slate-200 px-4 flex items-center justify-between shrink-0 shadow-sm z-10">
|
||
<div class="flex items-center gap-2.5">
|
||
<div class="w-7 h-7 rounded-lg bg-indigo-600 text-white flex items-center justify-center shadow-sm">
|
||
<i class="fa-solid fa-robot text-xs"></i>
|
||
</div>
|
||
<div>
|
||
<div class="flex items-center gap-2">
|
||
<h1 class="text-sm font-bold text-slate-800">SCUD Orion AI Assistant</h1>
|
||
<span class="inline-flex items-center px-1.5 py-0.5 rounded text-[9px] font-semibold bg-emerald-50 text-emerald-700 border border-emerald-200">Online</span>
|
||
</div>
|
||
<p class="text-[10px] text-slate-400">Система интеллектуального аудита и контроля СКУД / 1С</p>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="flex items-center gap-2">
|
||
<button onclick="window.openPresenceModal()" class="flex items-center gap-1.5 px-3 py-1.5 rounded-xl bg-emerald-50 hover:bg-emerald-100 text-emerald-700 text-xs font-bold border border-emerald-200 transition shadow-xs">
|
||
<i class="fa-solid fa-building-user text-xs"></i>
|
||
<span>Кто в здании</span>
|
||
</button>
|
||
</div>
|
||
</header>
|
||
|
||
<!-- ЛЕНТА ЧАТА -->
|
||
<div id="chat-messages-container" class="flex-1 overflow-y-auto p-4 md:p-6 flex flex-col gap-4">
|
||
<div class="flex gap-3 max-w-4xl mx-auto w-full">
|
||
<div class="w-8 h-8 rounded-lg bg-indigo-600 text-white flex items-center justify-center shrink-0 shadow-sm mt-0.5">
|
||
<i class="fa-solid fa-robot text-sm"></i>
|
||
</div>
|
||
<div class="flex-1 bg-white border border-slate-200 rounded-2xl rounded-tl-none p-4 shadow-sm">
|
||
<div class="text-[11px] font-bold text-indigo-600 uppercase tracking-wider mb-1">ИИ-ассистент SCUD Orion AI</div>
|
||
<div class="text-sm text-slate-700 leading-relaxed">
|
||
Привет! Вы можете задавать вопросы ассистенту, управлять системным промптом, сверять кадровые нестыковки СКУД и 1С или формировать срезы и отчеты.
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- БЕЙДЖ ПРИКРЕПЛЕННОГО ФАЙЛА -->
|
||
<div id="file-attachment-preview" class="hidden max-w-4xl mx-auto w-full px-4 pt-2">
|
||
<div class="inline-flex items-center gap-2 px-3 py-1 bg-indigo-50 border border-indigo-200 rounded-xl text-xs text-indigo-700 shadow-sm">
|
||
<i class="fa-solid fa-file text-indigo-600"></i>
|
||
<span id="file-attachment-name" class="font-medium truncate max-w-xs"></span>
|
||
<button type="button" onclick="clearAttachedFile()" class="text-indigo-400 hover:text-rose-600 ml-1">
|
||
<i class="fa-solid fa-xmark"></i>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- СТРОКА ВВОДА -->
|
||
<div class="px-4 py-3 bg-white border-t border-slate-200">
|
||
<div id="chat-input-box" class="max-w-4xl mx-auto w-full flex items-end gap-3 bg-slate-50 border border-slate-300 rounded-2xl px-4 py-2.5 transition focus-within:border-indigo-500 focus-within:bg-white focus-within:ring-2 focus-within:ring-indigo-100 shadow-xs">
|
||
<button type="button" onclick="document.getElementById('file-upload-input').click()" class="text-slate-400 hover:text-indigo-600 p-1.5 transition shrink-0 mb-0.5" title="Прикрепить файл">
|
||
<i class="fa-solid fa-paperclip text-base"></i>
|
||
</button>
|
||
<input type="file" id="file-upload-input" class="hidden" />
|
||
|
||
<textarea id="user-input" rows="1" placeholder="Задайте вопрос, отправьте команду (Enter — отправить, Shift+Enter — перенос)..."
|
||
class="flex-1 bg-transparent border-0 focus:outline-none text-[15.5px] text-slate-800 placeholder:text-slate-400 resize-none py-1 leading-6 min-h-[32px] max-h-36" style="height: 32px;"></textarea>
|
||
|
||
<button type="button" onclick="window.sendMessage()" class="w-8 h-8 rounded-xl bg-indigo-600 hover:bg-indigo-700 active:bg-indigo-800 text-white flex items-center justify-center shrink-0 shadow-sm transition mb-0.5">
|
||
<i class="fa-solid fa-paper-plane text-xs"></i>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</main>
|
||
</div>
|
||
|
||
<!-- ПОЛНОЭКРАННЫЙ ОВЕРЛЕЙ DRAG & DROP -->
|
||
<div id="global-drag-overlay" class="fixed inset-0 bg-indigo-950/70 backdrop-blur-xs z-50 flex items-center justify-center p-8 hidden pointer-events-none transition-all">
|
||
<div class="border-3 border-dashed border-indigo-300 rounded-3xl w-full h-full flex flex-col items-center justify-center text-white gap-4 bg-indigo-900/40">
|
||
<div class="w-20 h-20 rounded-2xl bg-white/10 flex items-center justify-center shadow-lg backdrop-blur-md border border-white/20">
|
||
<i class="fa-solid fa-cloud-arrow-up text-4xl text-indigo-200"></i>
|
||
</div>
|
||
<div class="text-xl font-bold tracking-wide">Перетащите файл в окно для загрузки</div>
|
||
<div class="text-sm text-indigo-200">Поддерживаются PDF (документы и сканы), изображения, Excel, CSV, TXT</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- КОНТЕЙНЕР ДИНАМИЧЕСКИХ МОДАЛЬНЫХ ОКОН -->
|
||
<div id="modals-container"></div>
|
||
|
||
<script src="/static/js/auth.js?v=2.6.0"></script>
|
||
<script src="/static/js/tasks.js?v=2.6.0"></script>
|
||
<script src="/static/js/manual_absences.js?v=2.6.0"></script>
|
||
<script src="/static/js/snapshot_inspector.js?v=2.6.0"></script>
|
||
|
||
<script src="/static/js/sidebar/core.js?v=2.6.0"></script>
|
||
<script src="/static/js/sidebar/registries.js?v=2.6.0"></script>
|
||
<script src="/static/js/sidebar/snapshots.js?v=2.6.0"></script>
|
||
<script src="/static/js/sidebar/prompts_context.js?v=2.6.0"></script>
|
||
|
||
<script src="/static/js/presence.js?v=2.6.0"></script>
|
||
|
||
<script src="/static/js/chat/task_widget.js?v=2.6.0"></script>
|
||
<script src="/static/js/chat/core.js?v=2.6.0"></script>
|
||
<script src="/static/js/app.js?v=2.6.0"></script>
|
||
</body>
|
||
</html> |