Show loading animation while the fact assistant generates a draft.

Disables the form and displays a spinner overlay after clicking Entwurf generieren.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Pirmin Hinderling (fedora)
2026-07-07 21:43:31 +02:00
parent 6e14f2b266
commit b0ecdc6cfb
+108 -3
View File
@@ -19,6 +19,65 @@
border-radius: 8px;
padding: 1.25rem;
background: #fff;
position: relative;
}
.assistant-card.is-loading {
pointer-events: none;
}
.fk-assistant-loading {
position: absolute;
inset: 0;
z-index: 2;
display: flex;
align-items: center;
justify-content: center;
border-radius: 8px;
background: rgba(255, 255, 255, 0.92);
}
.fk-assistant-loading[hidden] {
display: none !important;
}
.fk-assistant-loading-inner {
text-align: center;
color: #374151;
}
.fk-assistant-loading-inner p {
margin: 0.75rem 0 0;
font-weight: 500;
}
.fk-assistant-loading-hint {
margin-top: 0.35rem !important;
font-size: 0.85rem;
font-weight: 400 !important;
color: #6b7280;
}
.fk-spinner {
display: inline-block;
width: 2.25rem;
height: 2.25rem;
border: 3px solid #d1d5db;
border-top-color: #0d9488;
border-radius: 50%;
animation: fk-spin 0.75s linear infinite;
}
@keyframes fk-spin {
to { transform: rotate(360deg); }
}
.fk-generate-btn.is-loading .fk-btn-label {
display: none;
}
.fk-generate-btn.is-loading .fk-btn-loading {
display: inline-flex;
align-items: center;
gap: 0.5rem;
}
.fk-btn-loading {
display: none;
}
.fk-btn-loading .fk-spinner {
width: 1rem;
height: 1rem;
border-width: 2px;
}
</style>
{% endblock %}
@@ -48,8 +107,15 @@
</ol>
</div>
<div class="assistant-card">
<form method="post" enctype="multipart/form-data" novalidate>
<div class="assistant-card" id="fk-assistant-card">
<div class="fk-assistant-loading" id="fk-assistant-loading" hidden>
<div class="fk-assistant-loading-inner">
<span class="fk-spinner" aria-hidden="true"></span>
<p>Entwurf wird generiert…</p>
<p class="fk-assistant-loading-hint">Die KI analysiert Ihre Eingaben. Das kann einige Sekunden dauern.</p>
</div>
</div>
<form method="post" enctype="multipart/form-data" novalidate id="fk-assistant-form">
{% csrf_token %}
{% if form.non_field_errors %}
<div class="alert alert-danger">{{ form.non_field_errors }}</div>
@@ -73,7 +139,13 @@
<div class="form-text">JPG, PNG, GIF, WebP, SVG oder PDF. SVG wird für die KI intern in PNG umgewandelt.</div>
</div>
<button type="submit" class="button default">Entwurf generieren</button>
<button type="submit" class="button default fk-generate-btn" id="fk-generate-draft-btn">
<span class="fk-btn-label">Entwurf generieren</span>
<span class="fk-btn-loading">
<span class="fk-spinner" aria-hidden="true"></span>
Wird generiert…
</span>
</button>
</form>
</div>
@@ -95,3 +167,36 @@
{% endif %}
</div>
{% endblock %}
{% block extrahead %}
{{ block.super }}
<script>
(function () {
var form = document.getElementById('fk-assistant-form');
if (!form) {
return;
}
form.addEventListener('submit', function () {
var card = document.getElementById('fk-assistant-card');
var overlay = document.getElementById('fk-assistant-loading');
var button = document.getElementById('fk-generate-draft-btn');
if (card) {
card.classList.add('is-loading');
}
if (overlay) {
overlay.hidden = false;
}
if (button) {
button.classList.add('is-loading');
button.disabled = true;
}
form.querySelectorAll('input:not([type="hidden"]), textarea, select, button').forEach(function (field) {
field.disabled = true;
});
});
})();
</script>
{% endblock %}