Improve settings hierarchy conciseness

This commit is contained in:
2026-03-07 16:32:24 +00:00
parent 611de57bf8
commit 10588a18b9
21 changed files with 846 additions and 80 deletions

View File

@@ -0,0 +1,25 @@
{% extends "base.html" %}
{% block content %}
<section class="section">
<div class="container">
<h1 class="title is-4">Accessibility</h1>
<div class="box">
<h2 class="title is-6">Motion</h2>
<form method="post">
{% csrf_token %}
<div class="field">
<label class="checkbox">
<input type="checkbox" name="disable_animations"{% if accessibility_settings.disable_animations %} checked{% endif %}>
Disable animations
</label>
<p class="help is-size-7 has-text-grey mt-1">
Reduces motion by disabling most transitions and animations across the interface.
</p>
</div>
<button class="button is-link is-small" type="submit">Save</button>
</form>
</div>
</div>
</section>
{% endblock %}

View File

@@ -1,13 +1,11 @@
{% extends "base.html" %}
{% block content %}
<section class="section">
<div class="container">
<div class="level">
<div class="level-left">
<div class="level-item">
<div>
<h1 class="title is-4">AI Execution Log</h1>
<h1 class="title is-4">Traces</h1>
<p class="subtitle is-6">Tracked model calls and usage metrics for this account.</p>
</div>
</div>
@@ -159,6 +157,7 @@
<table class="table is-fullwidth is-size-7 is-striped is-hoverable">
<thead>
<tr>
<th></th>
<th>Started</th>
<th>Status</th>
<th>Operation</th>
@@ -173,6 +172,22 @@
<tbody>
{% for run in runs %}
<tr>
<td>
<button
class="button is-small is-light trace-run-expand"
type="button"
data-detail-row="trace-run-detail-{{ run.id }}"
data-detail-content="trace-run-detail-content-{{ run.id }}"
data-expanded-label="Hide"
data-collapsed-label="Show"
hx-get="{% url 'ai_execution_run_detail' run_id=run.id %}"
hx-target="#trace-run-detail-content-{{ run.id }}"
hx-swap="innerHTML"
hx-trigger="click once"
>
Show
</button>
</td>
<td>{{ run.started_at }}</td>
<td>
{% if run.status == "ok" %}
@@ -197,14 +212,90 @@
{% endif %}
</td>
</tr>
<tr id="trace-run-detail-{{ run.id }}" class="is-hidden">
<td colspan="10">
<div id="trace-run-detail-content-{{ run.id }}" class="trace-run-detail-shell is-size-7 has-text-grey">
Click Show to load run details.
</div>
</td>
</tr>
{% empty %}
<tr><td colspan="9">No runs yet.</td></tr>
<tr><td colspan="10">No runs yet.</td></tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</article>
</div>
</section>
<script>
(function () {
document.querySelectorAll(".trace-run-expand").forEach(function (button) {
button.addEventListener("click", function () {
const rowId = String(button.getAttribute("data-detail-row") || "");
const row = rowId ? document.getElementById(rowId) : null;
if (!row) {
return;
}
const isHidden = row.classList.contains("is-hidden");
row.classList.toggle("is-hidden", !isHidden);
button.textContent = isHidden
? String(button.getAttribute("data-expanded-label") || "Hide")
: String(button.getAttribute("data-collapsed-label") || "Show");
});
});
document.addEventListener("click", function (event) {
const trigger = event.target.closest(".trace-run-tab-trigger");
if (!trigger) {
return;
}
event.preventDefault();
const shell = trigger.closest(".trace-run-detail-tabs");
if (!shell) {
return;
}
const targetName = String(trigger.getAttribute("data-tab-target") || "");
if (!targetName) {
return;
}
shell.querySelectorAll(".trace-run-tab-trigger").forEach(function (item) {
item.parentElement.classList.toggle("is-active", item === trigger);
});
shell.querySelectorAll(".trace-run-tab-panel").forEach(function (panel) {
const isActive = panel.getAttribute("data-tab-panel") === targetName;
panel.classList.toggle("is-hidden", !isActive);
});
const lazyUrl = String(trigger.getAttribute("data-lazy-url") || "");
if (!lazyUrl) {
return;
}
const panel = shell.querySelector(
'.trace-run-tab-panel[data-tab-panel="' + targetName + '"]'
);
if (!panel || panel.getAttribute("data-loaded") === "1") {
return;
}
panel.setAttribute("data-loaded", "1");
panel.classList.add("is-loading");
fetch(lazyUrl, { credentials: "same-origin" })
.then(function (response) {
if (!response.ok) {
throw new Error("tab load failed");
}
return response.text();
})
.then(function (html) {
panel.innerHTML = html;
})
.catch(function () {
panel.innerHTML =
'<p class="has-text-danger">Unable to load this tab.</p>';
})
.finally(function () {
panel.classList.remove("is-loading");
});
});
})();
</script>
{% endblock %}

View File

@@ -3,8 +3,7 @@
{% block content %}
<section class="section">
<div class="container">
<h1 class="title is-4">Security</h1>
{% if show_encryption %}
<div class="columns is-desktop is-variable is-8">
<div class="column">
<div class="box">
@@ -102,7 +101,9 @@
</div>
</div>
</div>
{% endif %}
{% if show_permission %}
<div class="box">
<h2 class="title is-6">Global Scope Override</h2>
<p class="is-size-7 has-text-grey mb-3">
@@ -194,14 +195,24 @@
<label class="label is-size-7 mb-1">Require OMEMO</label>
<div class="is-flex is-align-items-center" style="gap:0.5rem;">
<span class="tag is-size-7" data-global-mode-label="require_omemo"></span>
<button type="button" class="button is-small is-light" data-global-change-toggle="require_omemo">Change Global</button>
<button
type="button"
class="button is-small is-light"
data-global-change-toggle="require_omemo"
{% if security_settings.require_omemo %}disabled title="Disable 'Require OMEMO encryption' in Encryption settings to edit this override."{% endif %}
>
Change Global
</button>
</div>
</div>
<div class="buttons has-addons is-hidden" data-global-mode-picker="require_omemo">
<button class="button is-small" type="button" data-global-mode-set="require_omemo" data-mode="per_scope">Per Scope</button>
<button class="button is-small" type="button" data-global-mode-set="require_omemo" data-mode="on">Force On</button>
<button class="button is-small" type="button" data-global-mode-set="require_omemo" data-mode="off">Force Off</button>
<button class="button is-small" type="button" data-global-mode-set="require_omemo" data-mode="per_scope"{% if security_settings.require_omemo %} disabled{% endif %}>Per Scope</button>
<button class="button is-small" type="button" data-global-mode-set="require_omemo" data-mode="on"{% if security_settings.require_omemo %} disabled{% endif %}>Force On</button>
<button class="button is-small" type="button" data-global-mode-set="require_omemo" data-mode="off"{% if security_settings.require_omemo %} disabled{% endif %}>Force Off</button>
</div>
{% if security_settings.require_omemo %}
<p class="help is-size-7 has-text-grey">Locked by Encryption setting: disable "Require OMEMO encryption" to edit this override.</p>
{% endif %}
</div>
<div class="field mb-3">
<div class="is-flex is-justify-content-space-between is-align-items-center">
@@ -263,7 +274,7 @@
</div>
<div class="box">
<h2 class="title is-6">Command Security Scopes</h2>
<h2 class="title is-6">Fine-Grained Security Scopes</h2>
<p class="is-size-7 has-text-grey mb-3">
Choose a top-level category, expand a scope, then click <strong>Change</strong> to edit that scope.
</p>
@@ -319,7 +330,7 @@
<input class="scope-editable" data-lock-state="{% if row.enabled_locked %}locked{% else %}free{% endif %}" type="checkbox" name="policy_enabled"{% if row.enabled %} checked{% endif %}{% if row.enabled_locked %} disabled{% endif %}>
Scope Enabled
</label>
<label class="checkbox mr-4" title="{% if row.require_omemo_locked %}{{ row.lock_help }}{% endif %}">
<label class="checkbox mr-4" title="{% if row.require_omemo_locked %}{{ row.require_omemo_lock_help }}{% endif %}">
<input class="scope-editable" data-lock-state="{% if row.require_omemo_locked %}locked{% else %}free{% endif %}" type="checkbox" name="policy_require_omemo"{% if row.require_omemo %} checked{% endif %}{% if row.require_omemo_locked %} disabled{% endif %}>
Require OMEMO
</label>
@@ -380,7 +391,9 @@
</div>
{% endfor %}
</div>
{% endif %}
{% if show_encryption %}
<div class="box">
<h2 class="title is-6">OMEMO Enablement Plan</h2>
<p class="is-size-7 has-text-grey mb-3">Complete each step to achieve end-to-end encrypted messaging with the gateway.</p>
@@ -402,6 +415,7 @@
</tbody>
</table>
</div>
{% endif %}
</div>
</section>

View File

@@ -0,0 +1,22 @@
{% extends "base.html" %}
{% block content %}
<section class="section">
<div class="container">
<h1 class="title is-4">{{ category_title }}</h1>
<p class="subtitle is-6">{{ category_description }}</p>
<div class="tabs is-boxed is-small mb-4 security-page-tabs">
<ul>
{% for tab in category_tabs %}
<li class="{% if tab.active %}is-active{% endif %}">
<a href="{{ tab.href }}">{{ tab.label }}</a>
</li>
{% endfor %}
</ul>
</div>
<div class="box">
<p class="is-size-7 has-text-grey">Choose a tab above to open settings in this category.</p>
</div>
</div>
</section>
{% endblock %}