Files
MtoRagSystem/templates/admin/base.html.twig
2026-04-19 12:30:24 +02:00

192 lines
7.8 KiB
Twig

<!doctype html>
<html lang="de">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{% block title %}Admin{% endblock %}</title>
{% block stylesheets %}
<link href="/assets/styles/bootstrap.min.css" rel="stylesheet"/>
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.css" rel="stylesheet">
<link rel="stylesheet" href="/assets/styles/base.css">
<link rel="shortcut icon" href="https://www.mitho-media.de/media/fc/16/42/1667224106/favicon.ico?ts=1767609928">
<link rel="stylesheet" href="{{ asset('/assets/styles/admin-markdown.css') }}">
{% endblock %}
</head>
<body class="bg-dark text-light">
{# ============================= #}
{# Top Navigation #}
{# ============================= #}
{% if app.user %}
<nav class="navbar navbar-dark bg-black border-bottom border-secondary px-3">
<div class="navbar-brand fw-semibold text-info">
<div>
<img src="/assets/img/logo.png" style="max-width: 120px;">
</div>
<div class="fs-6">RAG-System</div>
</div>
<div class="small">powered by mitho®</div>
<div class="ms-auto d-flex align-items-center gap-3">
<span class="small text-light">
{{ app.user.userIdentifier }}
</span>
<a class="btn btn-sm btn-outline-light"
href="{{ path('admin_logout') }}">
Logout
</a>
</div>
</nav>
{% endif %}
{# ============================= #}
{# Layout Container #}
{# ============================= #}
<div class="container-fluid">
<div class="row flex-nowrap">
{# ============================= #}
{# Sidebar #}
{# ============================= #}
{% if app.user %}
<aside class="col-auto col-md-3 col-lg-2 bg-black border-end border-secondary min-vh-100 pt-3">
{% set route = app.request.attributes.get('_route') %}
<nav class="nav flex-column">
<a class="nav-link text-light {% if route starts with 'admin_dashboard' %}active fw-bold{% endif %}"
href="{{ path('admin_dashboard') }}">
<i class="bi bi-hdd-rack"></i> Systemübersicht
</a>
<hr class="border-secondary">
<div class="text-info text-uppercase small mb-2">
RAG Dokumente & Wissen
</div>
<a class="nav-link text-light {% if route starts with 'admin_document' %}active fw-bold{% endif %}"
href="{{ path('admin_documents') }}">
<i class="bi bi-card-list"></i> Dokumente
</a>
{# ------------------------- #}
{# Tags (Document Routing) #}
{# ------------------------- #}
<a class="nav-link text-light {% if route starts with 'admin_tags' %}active fw-bold{% endif %}"
href="{{ path('admin_tags_index') }}">
<i class="bi bi-tag-fill"></i> Tags
</a>
<a class="nav-link text-light {% if route starts with 'admin_system_agent' %}active fw-bold{% endif %}"
href="{{ path('admin_system_agent') }}">
<i class="bi bi-robot"></i> Wissensbasis (Chunk-Index)
</a>
<hr class="border-secondary">
<div class="text-info text-uppercase small mb-2">
RAG System-Profile
</div>
<a class="nav-link text-light {% if route starts with 'admin_system_prompt' %}active fw-bold{% endif %}"
href="{{ path('admin_system_prompt') }}">
<i class="bi bi-chat-right-dots-fill"></i> System Prompt
</a>
<a class="nav-link text-light {% if route starts with 'admin_ingest_profile' %}active fw-bold{% endif %}"
href="{{ path('admin_ingest_profile_list') }}">
<i class="bi bi-search"></i> Indexierungsprofile (Ingest)
</a>
<hr class="border-secondary">
<div class="text-info text-uppercase small text-glow mb-2">
KI-Endpunkte
</div>
<a class="nav-link text-light {% if route starts with 'admin_model_config' %}active fw-bold{% endif %}"
href="{{ path('admin_model_config_list') }}">
<i class="bi bi-rocket-takeoff-fill"></i> KI-/LLM-Setup
</a>
<a class="nav-link text-light {% if route starts with 'admin_model_config' %}active fw-bold{% endif %}"
href="{{ path('admin_model_config_list') }}#agentLiveTest">
<i class="bi bi-rocket-takeoff-fill"></i> KI-Agent Live-Test
</a>
<hr class="border-secondary">
<div class="text-info text-uppercase small mb-2">
System-Guiide
</div>
<a class="nav-link text-light {% if route starts with 'admin_guides_index' %}active fw-bold{% endif %}"
href="{{ path('admin_guides_index') }}">
<i class="bi bi-mortarboard-fill"></i> How-To & Leitfäden
</a>
<hr class="border-secondary">
<div class="text-info text-uppercase small mb-2">
Logs
</div>
<a class="nav-link text-light {% if route starts with 'admin_job' %}active fw-bold{% endif %}"
href="{{ path('admin_jobs') }}">
<i class="bi bi-terminal"></i> Indexierungs-Log (Ingest Jobs)
</a>
<a class="nav-link text-light {% if route starts with 'admin_job' %}active fw-bold{% endif %}"
href="{{ path('admin_vector_log') }}">
<i class="bi bi-terminal"></i> Vector-Log Python
</a>
<a class="nav-link text-light {% if route starts with 'admin_job' %}active fw-bold{% endif %}"
href="{{ path('admin_system_logs_index') }}">
<i class="bi bi-terminal"></i> System-Logs
</a>
</nav>
</aside>
{% endif %}
{# ============================= #}
{# Main Content #}
{# ============================= #}
<main class="col py-4 px-4">
{% block body %}{% endblock %}
</main>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function () {
const requiredFields = document.querySelectorAll(
'input[required], select[required], textarea[required]'
);
requiredFields.forEach(field => {
const wrapper = field.parentElement;
if (!wrapper) return;
// Suche Label im gleichen Container
const label = wrapper.querySelector('label');
if (!label) return;
// Nicht doppelt markieren
if (label.dataset.requiredMarked) return;
const star = document.createElement('span');
star.textContent = ' *';
star.style.color = '#dc3545';
star.style.marginLeft = '4px';
star.style.fontWeight = '600';
label.appendChild(star);
label.dataset.requiredMarked = 'true';
});
});
</script>
</body>
</html>