DRY: Notiz-Modal zentral in UI.noteModal (11 divergierte Kopien entfernt, ~750 Z. weniger); Fix: Founder-Race in jobs.py atomar + founder_number, SW v1133
This commit is contained in:
parent
a356626d39
commit
7b3041fc94
18 changed files with 124 additions and 776 deletions
|
|
@ -1327,9 +1327,91 @@ const UI = (() => {
|
|||
});
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------
|
||||
// NOTE-MODAL — Notiz zu einem beliebigen Objekt (parentType/parentId)
|
||||
// erstellen/bearbeiten. Zentral, damit nicht jede Seite eine eigene Kopie hat.
|
||||
// ----------------------------------------------------------
|
||||
async function noteModal(parentType, parentId, parentLabel, locationName) {
|
||||
document.getElementById('by-note-modal')?.remove();
|
||||
|
||||
const overlay = document.createElement('div');
|
||||
overlay.id = 'by-note-modal';
|
||||
overlay.style.cssText = 'position:fixed;inset:0;z-index:2000;background:rgba(0,0,0,.55);display:flex;align-items:flex-end;justify-content:center';
|
||||
|
||||
overlay.innerHTML = `
|
||||
<div style="background:var(--c-surface);border-radius:var(--radius-xl) var(--radius-xl) 0 0;
|
||||
width:100%;max-width:640px;max-height:90vh;display:flex;flex-direction:column;
|
||||
padding-bottom:env(safe-area-inset-bottom,0px)">
|
||||
<div style="padding:var(--space-4) var(--space-5);border-bottom:1px solid var(--c-border);
|
||||
display:flex;align-items:center;justify-content:space-between;flex-shrink:0">
|
||||
<div>
|
||||
<div style="font-weight:var(--weight-semibold);font-size:var(--text-base)">${_svgIcon('note-pencil')} Notiz</div>
|
||||
<div style="font-size:var(--text-xs);color:var(--c-text-muted);margin-top:2px">${escape(parentLabel)}</div>
|
||||
</div>
|
||||
<button id="by-note-close" style="background:none;border:none;cursor:pointer;font-size:1.4rem;color:var(--c-text-muted);padding:4px 8px" aria-label="Schließen">×</button>
|
||||
</div>
|
||||
<div style="padding:var(--space-4) var(--space-5);flex:1;overflow-y:auto">
|
||||
<form id="by-note-form">
|
||||
<textarea id="by-note-text" class="form-control" rows="5"
|
||||
placeholder="Notiz eingeben…"
|
||||
style="width:100%;resize:vertical"></textarea>
|
||||
</form>
|
||||
</div>
|
||||
<div style="padding:var(--space-3) var(--space-5);border-top:1px solid var(--c-border);
|
||||
display:flex;gap:var(--space-2);flex-shrink:0">
|
||||
<button type="button" id="by-note-cancel" class="btn btn-secondary flex-1">Abbrechen</button>
|
||||
<button type="submit" form="by-note-form" id="by-note-save" class="btn btn-primary flex-1">Speichern</button>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
document.body.appendChild(overlay);
|
||||
|
||||
const textarea = document.getElementById('by-note-text');
|
||||
const saveBtn = document.getElementById('by-note-save');
|
||||
const cancelBtn = document.getElementById('by-note-cancel');
|
||||
const closeBtn = document.getElementById('by-note-close');
|
||||
|
||||
let existingNoteId = null;
|
||||
try {
|
||||
const existing = await API.notes.get(parentType, parentId);
|
||||
if (existing?.id) {
|
||||
existingNoteId = existing.id;
|
||||
textarea.value = existing.text || '';
|
||||
}
|
||||
} catch (_) { /* keine Notiz vorhanden — ok */ }
|
||||
|
||||
setTimeout(() => textarea.focus(), 100);
|
||||
|
||||
const _close = () => overlay.remove();
|
||||
closeBtn.addEventListener('click', _close);
|
||||
cancelBtn.addEventListener('click', _close);
|
||||
overlay.addEventListener('click', e => { if (e.target === overlay) _close(); });
|
||||
|
||||
document.getElementById('by-note-form').addEventListener('submit', async e => {
|
||||
e.preventDefault();
|
||||
const text = textarea.value.trim();
|
||||
setLoading(saveBtn, true);
|
||||
try {
|
||||
const payload = { text, parent_label: parentLabel, location_name: locationName || null, client_time: API.clientNow() };
|
||||
if (existingNoteId) {
|
||||
await API.notes.update(existingNoteId, payload);
|
||||
} else {
|
||||
await API.notes.create(parentType, parentId, payload);
|
||||
}
|
||||
toast.success('Notiz gespeichert.');
|
||||
_close();
|
||||
} catch (err) {
|
||||
toast.error(err.message || 'Fehler beim Speichern.');
|
||||
setLoading(saveBtn, false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Öffentliche API
|
||||
return {
|
||||
toast, modal,
|
||||
noteModal,
|
||||
setLoading, asyncButton,
|
||||
formData, setFormError, clearFormErrors,
|
||||
emptyState, errorState, time, text, money,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue