Files
oai-web/server/web/templates/base.html
Rune Olsen 7b0a9ccc2b Settings: add dedicated DAV/Pushover tabs, fix CalDAV/CardDAV bugs
- Add admin DAV tab (rename from CalDAV/CardDAV) and Pushover tab
  - Add per-user Pushover tab (User Key only; App Token stays admin-managed)
  - Remove system-wide CalDAV/CardDAV fallback — per-user config only
  - Rewrite contacts_tool.py using httpx directly (caldav 2.x dropped AddressBook)
  - Fix CardDAV REPORT/PROPFIND using SOGo URL pattern
  - Fix CalDAV/CardDAV test endpoints (POST method, URL scheme normalization)
  - Fix Show Password button — API now returns actual credential values
  - Convert Credentials tab to generic key-value store; dedicated keys
    (CalDAV, Pushover, trusted_proxy) excluded via _DEDICATED_CRED_KEYS
2026-04-10 12:06:23 +02:00

110 lines
6.3 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% block title %}{{ brand_name }}{% endblock %}</title>
<link rel="icon" type="image/png" href="/static/icon.png">
<link rel="stylesheet" href="/static/style.css?v={{ sv }}">
{% if theme_css %}<style>{{ theme_css | safe }}</style>{% endif %}
</head>
<body>
<!-- ── Sidebar ── -->
<nav class="sidebar">
<div class="sidebar-logo">
<img src="{{ logo_url }}" alt="logo" class="sidebar-logo-img">
<div class="sidebar-logo-text">
<div class="sidebar-logo-name">{{ brand_name }}</div>
<div class="sidebar-logo-app">oAI-Web <span class="sidebar-logo-version">v1.2</span></div>
</div>
</div>
<a class="nav-item" data-page="/" href="/">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><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>
Chat
</a>
<a class="nav-item" data-page="/chats" href="/chats">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/><line x1="9" y1="10" x2="15" y2="10"/><line x1="9" y1="14" x2="13" y2="14"/></svg>
Chats
</a>
<a class="nav-item" data-page="/agents" href="/agents">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="8" r="4"/><path d="M20 21a8 8 0 1 0-16 0"/><circle cx="19" cy="6" r="3"/><circle cx="5" cy="6" r="3"/></svg>
Agents
</a>
<a class="nav-item" data-page="/models" href="/models">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="4" y="4" width="16" height="16" rx="2"/><rect x="9" y="9" width="6" height="6"/><line x1="9" y1="1" x2="9" y2="4"/><line x1="15" y1="1" x2="15" y2="4"/><line x1="9" y1="20" x2="9" y2="23"/><line x1="15" y1="20" x2="15" y2="23"/><line x1="20" y1="9" x2="23" y2="9"/><line x1="20" y1="14" x2="23" y2="14"/><line x1="1" y1="9" x2="4" y2="9"/><line x1="1" y1="14" x2="4" y2="14"/></svg>
Models
</a>
<a class="nav-item" data-page="/files" href="/files">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"/></svg>
Files
</a>
<a class="nav-item" data-page="/monitors" href="/monitors">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="3"/><path d="M20.188 10.934a8.002 8.002 0 0 1 0 2.132M3.812 13.066a8.002 8.002 0 0 1 0-2.132M15.536 17.121a8 8 0 0 1-1.506.643M9.97 6.236A8 8 0 0 1 11.5 6M17.657 7.757a8 8 0 0 1 .879 1.506M6.343 16.243a8 8 0 0 1-.879-1.506M17.121 15.536a8 8 0 0 1-1.506.879M8.464 6.879A8 8 0 0 1 9.97 6.236"/></svg>
Monitors
</a>
<a class="nav-item" data-page="/audit" href="/audit">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><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"/><line x1="16" y1="13" x2="8" y2="13"/><line x1="16" y1="17" x2="8" y2="17"/><polyline points="10 9 9 9 8 9"/></svg>
Audit Log
</a>
<a class="nav-item" data-page="/help" href="/help">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3"/><line x1="12" y1="17" x2="12.01" y2="17"/></svg>
Help
</a>
{% if current_user and current_user.is_admin %}
<a class="nav-item" data-page="/admin/users" href="/admin/users">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M23 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 3.13a4 4 0 0 1 0 7.75"/></svg>
Users
</a>
{% endif %}
<a class="nav-item" data-page="/settings" href="/settings">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83-2.83l.06-.06A1.65 1.65 0 0 0 4.68 15a1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 2.83-2.83l.06.06A1.65 1.65 0 0 0 9 4.68a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 2.83l-.06.06A1.65 1.65 0 0 0 19.4 9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z"/></svg>
Settings
</a>
<div class="sidebar-bottom">
{% if current_user and current_user.is_admin %}
<button id="pause-btn" onclick="togglePause()" title="Pause agent">
<span class="btn-icon"></span>
<span class="btn-label">Pause</span>
</button>
{% endif %}
{% if current_user %}
<div class="sidebar-user">
<span class="sidebar-user-name" title="{{ current_user.username }}">{{ current_user.username }}</span>
<a href="/logout" class="sidebar-user-logout" title="Sign out">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="14" height="14"><path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"/><polyline points="16 17 21 12 16 7"/><line x1="21" y1="12" x2="9" y2="12"/></svg>
</a>
</div>
<div class="sidebar-logo-app">
<span style="padding-left: 10%;">&copy 2026 Rune Olsen</span>
{% endif %}
</div>
</nav>
<!-- ── Main column (nag + content) ── -->
<div style="flex:1;display:flex;flex-direction:column;overflow:hidden">
{% if needs_personality_setup %}
<div class="nag-banner" id="nag-banner">
<span>Your profile isn't set up yet — the assistant doesn't know who you are.
<a href="/settings?tab=personality" class="nag-link">Set it up now</a>
</span>
<button class="nag-dismiss" onclick="dismissNag()" title="Dismiss">×</button>
</div>
{% endif %}
<!-- ── Main content ── -->
<main class="main" id="main">
{% block content %}{% endblock %}
</main>
</div>
<script>window.AGENT_NAME = "{{ agent_name }}";</script>
<script src="/static/app.js?v={{ sv }}"></script>
{% block extra_scripts %}{% endblock %}
</body>
</html>