Initial commit
This commit is contained in:
@@ -0,0 +1,247 @@
|
||||
{% extends "base.html" %}
|
||||
{% block content %}
|
||||
{% set env_items = env_status.items() | list %}
|
||||
{% set missing_env = env_items | selectattr("1", "equalto", false) | list %}
|
||||
|
||||
<header class="dw-page-header dw-settings-header">
|
||||
<div>
|
||||
<h1>Settings</h1>
|
||||
<p>Read-only runtime configuration and operational posture.</p>
|
||||
</div>
|
||||
<code>{{ config_path }}</code>
|
||||
</header>
|
||||
|
||||
<section class="dw-settings-metrics" aria-label="Settings summary">
|
||||
<article class="dw-metric-card">
|
||||
<span class="dw-kicker">Application</span>
|
||||
<strong>{{ settings.app.name }}</strong>
|
||||
<span class="dw-card-note">{{ settings.app.base_url }}</span>
|
||||
</article>
|
||||
<article class="dw-metric-card">
|
||||
<span class="dw-kicker">Polling</span>
|
||||
<strong>{{ settings.app.poll_interval_minutes }} min</strong>
|
||||
<span class="dw-card-note">{{ settings.app.timezone }}</span>
|
||||
</article>
|
||||
<article class="dw-metric-card">
|
||||
<span class="dw-kicker">LLM</span>
|
||||
<strong>{{ settings.llm.model }}</strong>
|
||||
<span class="dw-card-note">{{ settings.llm.provider }}</span>
|
||||
</article>
|
||||
<article class="dw-metric-card {{ 'dw-metric-card-critical' if missing_env else '' }}">
|
||||
<span class="dw-kicker">Environment</span>
|
||||
<strong>{{ env_items | length - missing_env | length }}/{{ env_items | length }}</strong>
|
||||
<span class="dw-card-note">{{ missing_env | length }} missing</span>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<section class="dw-settings-board">
|
||||
<section class="dw-settings-panel">
|
||||
<h2 class="dw-panel-title">Runtime</h2>
|
||||
<div class="dw-info-card">
|
||||
<div class="dw-info-row">
|
||||
<span>Database</span>
|
||||
<code>{{ settings.app.database_url }}</code>
|
||||
</div>
|
||||
<div class="dw-info-row">
|
||||
<span>Log Level</span>
|
||||
<strong>{{ settings.app.log_level }}</strong>
|
||||
</div>
|
||||
<div class="dw-info-row">
|
||||
<span>Max Attachment Size</span>
|
||||
<strong>{{ settings.app.max_attachment_decompressed_mb }} MB</strong>
|
||||
</div>
|
||||
<div class="dw-info-row">
|
||||
<span>Max Reports Per Poll</span>
|
||||
<strong>{{ settings.app.max_reports_per_poll }}</strong>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="dw-settings-panel">
|
||||
<h2 class="dw-panel-title">Inboxes</h2>
|
||||
<div class="dw-inbox-grid">
|
||||
{% for inbox in settings.inboxes %}
|
||||
<article class="dw-settings-card">
|
||||
<div class="dw-settings-card-head">
|
||||
<div>
|
||||
<h3>{{ inbox.label }}</h3>
|
||||
<code>{{ inbox.id }}</code>
|
||||
</div>
|
||||
<span class="dw-chip {{ 'dw-chip-pass' if inbox.enabled else 'dw-chip-warning' }}">{{ "Enabled" if inbox.enabled else "Disabled" }}</span>
|
||||
</div>
|
||||
<div class="dw-info-list">
|
||||
<div><span>Domain</span><strong>{{ inbox.domain }}</strong></div>
|
||||
<div><span>Folder</span><strong>{{ inbox.folder }}</strong></div>
|
||||
<div><span>Recipient</span><strong>{{ inbox.recipient }}</strong></div>
|
||||
<div><span>IMAP</span><strong>{{ inbox.imap_host }}:{{ inbox.imap_port }} · {{ "SSL" if inbox.imap_ssl else "plain" }}</strong></div>
|
||||
</div>
|
||||
</article>
|
||||
{% else %}
|
||||
<div class="dw-list-empty">No inboxes configured.</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="dw-settings-panel dw-settings-panel-wide">
|
||||
<h2 class="dw-panel-title">Known Senders</h2>
|
||||
<div class="dw-sender-domain-grid">
|
||||
{% for domain, senders in settings.known_senders.items() %}
|
||||
<article class="dw-settings-card dw-sender-domain">
|
||||
<div class="dw-sender-domain-head">
|
||||
<h3>{{ domain }}</h3>
|
||||
<span>{{ senders | length }} senders</span>
|
||||
</div>
|
||||
<div class="dw-sender-list">
|
||||
{% for sender in senders %}
|
||||
<article class="dw-sender-row">
|
||||
<div>
|
||||
<strong>{{ sender.name }}</strong>
|
||||
<code>{{ sender.id }}</code>
|
||||
</div>
|
||||
<div class="dw-sender-values">
|
||||
<div>
|
||||
<span>IP ranges</span>
|
||||
<ul>
|
||||
{% for item in sender.ip_allowlist %}
|
||||
<li><code>{{ item }}</code></li>
|
||||
{% else %}
|
||||
<li class="dw-muted">None</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<span>DKIM domains</span>
|
||||
<ul>
|
||||
{% for item in sender.dkim_domains %}
|
||||
<li><code>{{ item }}</code></li>
|
||||
{% else %}
|
||||
<li class="dw-muted">None</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<span>SPF domains</span>
|
||||
<ul>
|
||||
{% for item in sender.spf_domains %}
|
||||
<li><code>{{ item }}</code></li>
|
||||
{% else %}
|
||||
<li class="dw-muted">None</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</article>
|
||||
{% else %}
|
||||
<div class="dw-list-empty">No known senders configured.</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="dw-settings-panel">
|
||||
<h2 class="dw-panel-title">Security</h2>
|
||||
<div class="dw-list-card">
|
||||
<div class="dw-list-row">
|
||||
<span>Dashboard Basic Auth</span>
|
||||
<span class="dw-chip {{ 'dw-chip-pass' if settings.security.dashboard_auth_enabled else 'dw-chip-warning' }}">{{ "Enabled" if settings.security.dashboard_auth_enabled else "Disabled" }}</span>
|
||||
</div>
|
||||
<div class="dw-list-row">
|
||||
<span>Homepage Token</span>
|
||||
<span class="dw-chip {{ 'dw-chip-pass' if settings.security.api_token_required else 'dw-chip-warning' }}">{{ "Required" if settings.security.api_token_required else "Not required" }}</span>
|
||||
</div>
|
||||
<div class="dw-list-row">
|
||||
<span>Email Alerts</span>
|
||||
<span class="dw-chip {{ 'dw-chip-pass' if settings.alerts.email.enabled else 'dw-chip-warning' }}">{{ "Enabled" if settings.alerts.email.enabled else "Disabled" }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="dw-settings-panel">
|
||||
<h2 class="dw-panel-title">LLM Data Controls</h2>
|
||||
<div class="dw-list-card">
|
||||
<div class="dw-list-row">
|
||||
<span>Alert Explanations</span>
|
||||
<span class="dw-chip {{ 'dw-chip-pass' if settings.llm.generate_alert_explanations else 'dw-chip-warning' }}">{{ "On" if settings.llm.generate_alert_explanations else "Off" }}</span>
|
||||
</div>
|
||||
<div class="dw-list-row">
|
||||
<span>Daily Summary</span>
|
||||
<span class="dw-chip {{ 'dw-chip-pass' if settings.llm.generate_daily_summary else 'dw-chip-warning' }}">{{ "On" if settings.llm.generate_daily_summary else "Off" }}</span>
|
||||
</div>
|
||||
<div class="dw-list-row">
|
||||
<span>Weekly Summary</span>
|
||||
<span class="dw-chip {{ 'dw-chip-pass' if settings.llm.generate_weekly_summary else 'dw-chip-warning' }}">{{ "On" if settings.llm.generate_weekly_summary else "Off" }}</span>
|
||||
</div>
|
||||
<div class="dw-list-row">
|
||||
<span>Raw XML to LLM</span>
|
||||
<span class="dw-chip {{ 'dw-chip-warning' if settings.llm.send_raw_xml_to_llm else 'dw-chip-pass' }}">{{ "On" if settings.llm.send_raw_xml_to_llm else "Off" }}</span>
|
||||
</div>
|
||||
<div class="dw-list-row">
|
||||
<span>Raw Email to LLM</span>
|
||||
<span class="dw-chip {{ 'dw-chip-warning' if settings.llm.send_raw_email_to_llm else 'dw-chip-pass' }}">{{ "On" if settings.llm.send_raw_email_to_llm else "Off" }}</span>
|
||||
</div>
|
||||
<div class="dw-list-row">
|
||||
<span>System Prompt</span>
|
||||
<code>{{ settings.llm.system_prompt_path }}</code>
|
||||
</div>
|
||||
<div class="dw-list-row">
|
||||
<span>Alert Prompt</span>
|
||||
<code>{{ settings.llm.alert_prompt_path }}</code>
|
||||
</div>
|
||||
<div class="dw-list-row">
|
||||
<span>Digest Prompt</span>
|
||||
<code>{{ settings.llm.digest_prompt_path }}</code>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="dw-settings-panel">
|
||||
<h2 class="dw-panel-title">Alert Thresholds</h2>
|
||||
<div class="dw-list-card">
|
||||
{% for name, value in settings.alerts.thresholds.model_dump().items() %}
|
||||
<div class="dw-list-row">
|
||||
<span>{{ name.replace("_", " ") }}</span>
|
||||
<code>{{ value }}</code>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<section class="dw-settings-env">
|
||||
<div class="dw-sidebar-head">
|
||||
<h2>LLM Prompts</h2>
|
||||
<span class="dw-kicker">Read From Disk</span>
|
||||
</div>
|
||||
<div class="dw-prompt-grid">
|
||||
{% for prompt in prompts %}
|
||||
<article class="dw-prompt-card">
|
||||
<div class="dw-settings-card-head">
|
||||
<div>
|
||||
<h3>{{ prompt.label }}</h3>
|
||||
<code>{{ prompt.path }}</code>
|
||||
</div>
|
||||
<span class="dw-chip {{ 'dw-chip-pass' if prompt.exists else 'dw-chip-warning' }}">{{ "Loaded" if prompt.exists else "Fallback" }}</span>
|
||||
</div>
|
||||
<pre>{{ prompt.content or "Using built-in fallback prompt." }}</pre>
|
||||
</article>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="dw-settings-env">
|
||||
<div class="dw-sidebar-head">
|
||||
<h2>Environment</h2>
|
||||
<span class="dw-kicker">{{ missing_env | length }} Missing</span>
|
||||
</div>
|
||||
<div class="dw-env-grid">
|
||||
{% for name, present in env_items | sort %}
|
||||
<div class="dw-env-item {{ 'is-missing' if not present else '' }}">
|
||||
<code>{{ name }}</code>
|
||||
<span class="dw-chip {{ 'dw-chip-pass' if present else 'dw-chip-fail' }}">{{ "Set" if present else "Missing" }}</span>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</section>
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user