diff --git a/admin/setup.php b/admin/setup.php
index 373d94a..eb6ee86 100644
--- a/admin/setup.php
+++ b/admin/setup.php
@@ -146,7 +146,7 @@ if (empty($templates)) {
print '
'.dol_print_size(filesize($path)).' | ';
print '';
print ''.$langs->trans("Delete").'';
+ .'data-dolconfirm="Vorlage löschen?" class="button-small">'.$langs->trans("Delete").'';
print ' | ';
print '';
}
diff --git a/bericht_card.php b/bericht_card.php
index d7a385a..41974a3 100644
--- a/bericht_card.php
+++ b/bericht_card.php
@@ -243,7 +243,7 @@ if (!$bericht) {
}
if ($mode !== 'from_order' && $user->hasRight('bericht', 'delete')) {
print 'trans("BerichtConfirmDelete")).'\')" '
+ .'data-dolconfirm="'.dol_escape_htmltag($langs->trans("BerichtConfirmDelete")).'" '
.'class="button-small button-delete">'.$langs->trans("Delete").'';
}
print '';
@@ -548,12 +548,12 @@ if (!$bericht) {
print '';
print '';
print 'version + 1).') erstellen? Der aktuelle Bericht bleibt unverändert.\')" '
+ .'data-dolconfirm="Neue Version (v'.((int)$bericht->version + 1).') erstellen? Der aktuelle Bericht bleibt unverändert." '
.'class="butAction" title="Neue Version des Berichts anlegen, aktueller bleibt erhalten">🔀 Neue Version';
- print '';
+ print '';
if ($user->hasRight('bericht', 'delete')) {
print 'trans("BerichtConfirmDelete")).'\')" '
+ .'data-dolconfirm="'.dol_escape_htmltag($langs->trans("BerichtConfirmDelete")).'" '
.'class="butActionDelete">🗑️ '.$langs->trans("Delete").'';
}
print '';
diff --git a/css/bericht.css b/css/bericht.css
index c802313..1b32fb0 100644
--- a/css/bericht.css
+++ b/css/bericht.css
@@ -494,3 +494,48 @@
.qr-url-display { word-break: break-all; }
.qr-url-display a { color: var(--colortextlink, #7aa2f7); }
.qr-status { padding: 8px; background: var(--colorbackbody, #1a1a1f); border-radius: 4px; margin-top: 12px; }
+
+/* ---------- dolModal (alert/confirm/prompt Ersatz) ---------- */
+.bericht-dolmodal-overlay {
+ position: fixed; inset: 0;
+ background: rgba(0,0,0,0.55);
+ z-index: 100000;
+ display: flex; align-items: center; justify-content: center;
+}
+.bericht-dolmodal {
+ background: var(--colorbackbody, #22222a);
+ color: var(--colortext, #eee);
+ border: 1px solid var(--colorboxbordertitle1, #444);
+ border-radius: 6px;
+ min-width: 320px; max-width: 520px;
+ box-shadow: 0 10px 40px rgba(0,0,0,0.6);
+ font-size: 14px;
+}
+.bericht-dolmodal-title {
+ padding: 10px 14px;
+ font-weight: bold;
+ background: var(--colorbacktitle1, #2d2d38);
+ border-bottom: 1px solid var(--colorboxbordertitle1, #444);
+ border-radius: 6px 6px 0 0;
+}
+.bericht-dolmodal-body {
+ padding: 16px 14px;
+ line-height: 1.5;
+ white-space: pre-wrap;
+}
+.bericht-dolmodal-input {
+ display: block;
+ width: 100%;
+ margin-top: 10px;
+ padding: 6px 8px;
+ background: var(--colorbackbody, #1a1a1f);
+ color: var(--colortext, #eee);
+ border: 1px solid var(--colorboxbordertitle1, #555);
+ border-radius: 3px;
+ box-sizing: border-box;
+}
+.bericht-dolmodal-foot {
+ padding: 10px 14px;
+ display: flex; gap: 8px; justify-content: flex-end;
+ border-top: 1px solid var(--colorboxbordertitle1, #444);
+}
diff --git a/js/editor.js b/js/editor.js
index 476d111..f595414 100644
--- a/js/editor.js
+++ b/js/editor.js
@@ -865,7 +865,7 @@
const tplBtn = document.getElementById('btn-save-as-template');
if (tplBtn) {
tplBtn.addEventListener('click', async () => {
- const label = prompt('Label für die Vorlage:\n(z. B. "PV-Anlage Standard" oder "Wallbox 11kW")');
+ const label = await dolPrompt('Label für die Vorlage (z. B. "PV-Anlage Standard" oder "Wallbox 11kW")');
if (!label) return;
await savePageAnnotations(false);
const fd = new FormData();
@@ -875,12 +875,12 @@
const r = await fetch(cfg.urls.save_as_template, { method: 'POST', body: fd });
const data = await r.json();
if (data.success) toast('✓ Vorlage "' + label + '" gespeichert');
- else alert('Fehler: ' + (data.error || ''));
+ else dolAlert('Fehler: ' + (data.error || ''));
});
}
document.getElementById('btn-finalize').addEventListener('click', async () => {
- if (!confirm('Bericht jetzt finalisieren und PDF erzeugen?')) return;
+ if (!(await dolConfirm('Bericht jetzt finalisieren und PDF erzeugen?'))) return;
toast('Speichere aktuelle Seite…');
await savePageAnnotations(false);
toast('PDF wird erzeugt…');
@@ -918,7 +918,7 @@
btn.addEventListener('click', async () => {
const checks = document.querySelectorAll('.att-check:checked');
if (!checks.length) {
- alert('Bitte zuerst Bilder ankreuzen');
+ dolAlert('Bitte zuerst Bilder ankreuzen');
return;
}
const layout = layoutSel ? layoutSel.value : 'single';
@@ -942,7 +942,7 @@
const slotCount = { grid_2: 2, grid_2v: 2, grid_4: 4, grid_6: 6, before_after: 2 }[layout] || 4;
const imageChecks = Array.from(checks).filter(c => c.dataset.mime.startsWith('image'));
if (!imageChecks.length) {
- alert('Bitte mindestens ein Bild ankreuzen (PDFs nicht in Grids unterstützt)');
+ dolAlert('Bitte mindestens ein Bild ankreuzen (PDFs nicht in Grids unterstützt)');
return;
}
// In Gruppen à slotCount aufteilen
@@ -956,7 +956,7 @@
const r = await fetch(cfg.urls.create_grid_page, { method: 'POST', body: fd });
const data = await r.json().catch(() => ({}));
if (!data.success) {
- alert('Fehler bei Gruppe '+(Math.floor(i/slotCount)+1)+': '+(data.error || 'unbekannt'));
+ dolAlert('Fehler bei Gruppe '+(Math.floor(i/slotCount)+1)+': '+(data.error || 'unbekannt'));
return;
}
}
@@ -972,7 +972,7 @@
const rel = btn.dataset.relpath;
const ref = btn.dataset.sourceRef || '';
const name = btn.parentElement.querySelector('.att-name')?.textContent || rel;
- if (!confirm('Datei "' + name + '" aus ' + (ref ? ref : 'dem Anhang') + ' wirklich löschen?\n\nDiese Aktion kann nicht rückgängig gemacht werden.')) return;
+ if (!(await dolConfirm('Datei "' + name + '" aus ' + (ref ? ref : 'dem Anhang') + ' wirklich löschen? Diese Aktion kann nicht rückgängig gemacht werden.'))) return;
const fd = new FormData();
fd.append('token', cfg.token);
fd.append('relpath', rel);
@@ -982,7 +982,7 @@
btn.parentElement.remove();
toast('Datei gelöscht');
} else {
- alert('Löschen fehlgeschlagen: ' + (data.error || 'unbekannt'));
+ dolAlert('Löschen fehlgeschlagen: ' + (data.error || 'unbekannt'));
}
});
});
@@ -1000,7 +1000,7 @@
const r = await fetch(cfg.urls.upload_extra, { method: 'POST', body: fd });
const data = await r.json();
if (data.success) location.reload();
- else alert('Upload fehlgeschlagen: ' + (data.error || ''));
+ else dolAlert('Upload fehlgeschlagen: ' + (data.error || ''));
});
}
@@ -1023,7 +1023,7 @@
const r = await fetch(cfg.urls.create_upload_token, { method: 'POST', body: fd });
const data = await r.json();
if (!data.success) {
- alert('Token-Erstellung fehlgeschlagen: ' + (data.error || ''));
+ dolAlert('Token-Erstellung fehlgeschlagen: ' + (data.error || ''));
return;
}
const url = data.url;
@@ -1080,7 +1080,7 @@
const del = t.querySelector('.thumb-del');
if (del) del.addEventListener('click', async (e) => {
e.stopPropagation();
- if (!confirm(cfg.lang.confirm_del)) return;
+ if (!(await dolConfirm(cfg.lang.confirm_del))) return;
const fd = new FormData();
fd.append('token', cfg.token);
fd.append('pageid', t.dataset.pageid);
@@ -1111,13 +1111,13 @@
const data = await r.json();
btn.textContent = '🔍';
if (!data.success) {
- alert('Fehler: ' + (data.error || 'unbekannt'));
+ dolAlert('Fehler: ' + (data.error || 'unbekannt'));
return;
}
showSignatureVerifyResult(data);
} catch (err) {
btn.textContent = '🔍';
- alert('Netzwerkfehler: ' + err.message);
+ dolAlert('Netzwerkfehler: ' + err.message);
}
});
});
@@ -1261,5 +1261,97 @@
setTimeout(() => t.remove(), 2000);
}
+ /* ---------- Dolibarr-Style Modal-Dialoge (ersetzen alert/confirm/prompt) ---------- */
+ function dolModal(opts) {
+ // opts: { title, body, buttons:[{label, value, primary}], input:boolean, defaultValue }
+ return new Promise((resolve) => {
+ const ov = document.createElement('div');
+ ov.className = 'bericht-dolmodal-overlay';
+ const box = document.createElement('div');
+ box.className = 'bericht-dolmodal';
+ const h = document.createElement('div');
+ h.className = 'bericht-dolmodal-title';
+ h.textContent = opts.title || 'Bericht';
+ const b = document.createElement('div');
+ b.className = 'bericht-dolmodal-body';
+ b.textContent = opts.body || '';
+ let inputEl = null;
+ if (opts.input) {
+ inputEl = document.createElement('input');
+ inputEl.type = 'text';
+ inputEl.className = 'bericht-dolmodal-input';
+ inputEl.value = opts.defaultValue || '';
+ b.appendChild(document.createElement('br'));
+ b.appendChild(inputEl);
+ }
+ const foot = document.createElement('div');
+ foot.className = 'bericht-dolmodal-foot';
+ (opts.buttons || [{label:'OK', value:true, primary:true}]).forEach(btn => {
+ const el = document.createElement('button');
+ el.type = 'button';
+ el.className = btn.primary ? 'butAction butActionConfirm' : 'butAction';
+ el.textContent = btn.label;
+ el.addEventListener('click', () => {
+ const val = opts.input ? (btn.value ? (inputEl.value || null) : null) : btn.value;
+ ov.remove();
+ resolve(val);
+ });
+ foot.appendChild(el);
+ });
+ box.appendChild(h); box.appendChild(b); box.appendChild(foot);
+ ov.appendChild(box);
+ document.body.appendChild(ov);
+ if (inputEl) { inputEl.focus(); inputEl.select(); }
+ ov.addEventListener('click', (e) => {
+ if (e.target === ov) { ov.remove(); resolve(opts.input ? null : false); }
+ });
+ });
+ }
+ async function dolAlert(msg, title) {
+ return dolModal({
+ title: title || 'Hinweis',
+ body: msg,
+ buttons: [{label:'OK', value:true, primary:true}],
+ });
+ }
+ async function dolConfirm(msg, title) {
+ return dolModal({
+ title: title || 'Bestätigen',
+ body: msg,
+ buttons: [
+ {label:'Abbrechen', value:false},
+ {label:'OK', value:true, primary:true},
+ ],
+ });
+ }
+ async function dolPrompt(msg, defaultValue, title) {
+ return dolModal({
+ title: title || 'Eingabe',
+ body: msg,
+ input: true,
+ defaultValue: defaultValue || '',
+ buttons: [
+ {label:'Abbrechen', value:false},
+ {label:'OK', value:true, primary:true},
+ ],
+ });
+ }
+ // Globaler Handler: Links/Buttons mit data-dolconfirm abfangen
+ document.addEventListener('click', async (e) => {
+ const el = e.target.closest('[data-dolconfirm]');
+ if (!el) return;
+ if (el.dataset._dolconfirmed === '1') return; // schon durchgelaufen
+ e.preventDefault();
+ e.stopPropagation();
+ const ok = await dolConfirm(el.getAttribute('data-dolconfirm'));
+ if (!ok) return;
+ el.dataset._dolconfirmed = '1';
+ if (el.tagName === 'A') {
+ window.location.href = el.getAttribute('href');
+ } else {
+ el.click();
+ }
+ }, true);
+
document.addEventListener('DOMContentLoaded', init);
})();