Fix: Verlauf-Tab kein Endlos-Spinner + Save-422 bei null-Feldern
- Verlauf: _verlaufLoading-Flag verhindert parallele Loads - Verlauf: el nach await neu holen (stale DOM-Referenz nach Re-Render) - Verlauf: bei _renderContent() Shell nur rendern wenn keine Sessions im Cache - Backend: hund_stimmung/zufriedenheit als Optional[str/int] → akzeptiert null
This commit is contained in:
parent
cc841ef6d7
commit
738571d958
2 changed files with 21 additions and 6 deletions
|
|
@ -323,8 +323,8 @@ class SessionCreate(BaseModel):
|
|||
datum: Optional[str] = None
|
||||
wiederholungen: int = 1
|
||||
erfolgsquote: int = 50
|
||||
hund_stimmung: str = "aufmerksam"
|
||||
zufriedenheit: int = 3
|
||||
hund_stimmung: Optional[str] = "aufmerksam"
|
||||
zufriedenheit: Optional[int] = 3
|
||||
notiz: Optional[str] = None
|
||||
tagebuch_eintrag: bool = False # ignoriert — Training hat eigenes Protokoll
|
||||
|
||||
|
|
|
|||
|
|
@ -549,6 +549,7 @@ window.Page_uebungen = (() => {
|
|||
_exerciseStats = {};
|
||||
_verlaufSessions = [];
|
||||
_verlaufOffset = 0;
|
||||
_verlaufLoading = false;
|
||||
_render();
|
||||
_loadStatsAndBadges();
|
||||
_loadVirtualTrainer();
|
||||
|
|
@ -994,7 +995,6 @@ window.Page_uebungen = (() => {
|
|||
if (trainerEl) trainerEl.style.display = showIf(isExerciseTab);
|
||||
if (suggestEl) suggestEl.style.display = showIf(isExerciseTab);
|
||||
if (bannerEl) bannerEl.style.display = showIf(isExerciseTab);
|
||||
if (isVerlauf) _loadVerlauf();
|
||||
|
||||
switch (_activeTab) {
|
||||
case 'grundkommandos':
|
||||
|
|
@ -1016,7 +1016,16 @@ window.Page_uebungen = (() => {
|
|||
break;
|
||||
}
|
||||
case 'grundlagen': el.innerHTML = _renderGrundlagen(); break;
|
||||
case 'verlauf': el.innerHTML = _renderVerlaufShell(); break;
|
||||
case 'verlauf': {
|
||||
if (_verlaufSessions.length > 0) {
|
||||
el.innerHTML = `<div id="verlauf-wrap" style="padding:var(--space-4);display:flex;flex-direction:column;gap:var(--space-3)"><div id="verlauf-list"></div></div>`;
|
||||
_renderVerlaufList(el.querySelector('#verlauf-list'));
|
||||
} else {
|
||||
el.innerHTML = _renderVerlaufShell();
|
||||
_loadVerlauf();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'ki-trainer':
|
||||
if (!App.hasPro(_appState?.user)) {
|
||||
el.innerHTML = `<div style="padding:var(--space-6);text-align:center;color:var(--c-text-muted)">
|
||||
|
|
@ -1977,6 +1986,7 @@ window.Page_uebungen = (() => {
|
|||
let _verlaufSessions = [];
|
||||
let _verlaufOffset = 0;
|
||||
let _verlaufHasMore = false;
|
||||
let _verlaufLoading = false;
|
||||
const _VERLAUF_LIMIT = 30;
|
||||
|
||||
const _ERFOLG_EMOJI = { 0: '😓', 25: '😐', 50: '🙂', 75: '😊', 100: '🎉' };
|
||||
|
|
@ -2001,19 +2011,24 @@ window.Page_uebungen = (() => {
|
|||
}
|
||||
|
||||
async function _loadVerlauf(append = false) {
|
||||
if (_verlaufLoading) return;
|
||||
const dogId = _dogId();
|
||||
if (!dogId) return;
|
||||
const el = _container.querySelector('#verlauf-list');
|
||||
if (!el) return;
|
||||
|
||||
if (!append) {
|
||||
_verlaufSessions = [];
|
||||
_verlaufOffset = 0;
|
||||
}
|
||||
|
||||
_verlaufLoading = true;
|
||||
const data = await _apiGet(
|
||||
`/api/training/sessions?dog_id=${dogId}&limit=${_VERLAUF_LIMIT + 1}&offset=${_verlaufOffset}`
|
||||
).catch(() => null);
|
||||
_verlaufLoading = false;
|
||||
|
||||
// Element nach await neu holen — könnte durch Re-Render veraltet sein
|
||||
const el = _container?.querySelector('#verlauf-list');
|
||||
if (!el) return;
|
||||
|
||||
if (!data) {
|
||||
if (!append) el.innerHTML = `<div style="padding:var(--space-6);text-align:center;color:var(--c-text-muted);font-size:var(--text-sm)">Fehler beim Laden.</div>`;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue