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:
@@ -19,6 +19,65 @@
|
|||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
padding: 1.25rem;
|
padding: 1.25rem;
|
||||||
background: #fff;
|
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>
|
</style>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
@@ -48,8 +107,15 @@
|
|||||||
</ol>
|
</ol>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="assistant-card">
|
<div class="assistant-card" id="fk-assistant-card">
|
||||||
<form method="post" enctype="multipart/form-data" novalidate>
|
<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 %}
|
{% csrf_token %}
|
||||||
{% if form.non_field_errors %}
|
{% if form.non_field_errors %}
|
||||||
<div class="alert alert-danger">{{ form.non_field_errors }}</div>
|
<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 class="form-text">JPG, PNG, GIF, WebP, SVG oder PDF. SVG wird für die KI intern in PNG umgewandelt.</div>
|
||||||
</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>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -95,3 +167,36 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% 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 %}
|
||||||
|
|||||||
Reference in New Issue
Block a user