mirror of
https://github.com/Terranom674/Piwigo_Bratonien_Tools.git
synced 2026-09-19 16:24:33 +00:00
Add cache build cancel button and six-worker UI
This commit is contained in:
@@ -49,12 +49,15 @@
|
|||||||
.bratonien-muted { color:#a9a9a9; }
|
.bratonien-muted { color:#a9a9a9; }
|
||||||
.bratonien-main-cache { margin-top:16px; padding-top:14px; border-top:1px solid rgba(255,255,255,.1); }
|
.bratonien-main-cache { margin-top:16px; padding-top:14px; border-top:1px solid rgba(255,255,255,.1); }
|
||||||
.bratonien-main-cache__warning { margin:10px 0; color:#d6ae62; font-size:12px; line-height:1.45; }
|
.bratonien-main-cache__warning { margin:10px 0; color:#d6ae62; font-size:12px; line-height:1.45; }
|
||||||
|
.bratonien-main-cache__controls { display:flex; flex-wrap:wrap; gap:8px; align-items:center; }
|
||||||
|
.bratonien-main-cache__cancel { display:none; }
|
||||||
.bratonien-main-cache__progress { display:none; margin-top:14px; }
|
.bratonien-main-cache__progress { display:none; margin-top:14px; }
|
||||||
.bratonien-main-cache__head { display:flex; justify-content:space-between; gap:12px; margin-bottom:7px; }
|
.bratonien-main-cache__head { display:flex; justify-content:space-between; gap:12px; margin-bottom:7px; }
|
||||||
.bratonien-main-cache__track { height:18px; overflow:hidden; border:1px solid rgba(255,255,255,.16); border-radius:4px; background:rgba(0,0,0,.25); }
|
.bratonien-main-cache__track { height:18px; overflow:hidden; border:1px solid rgba(255,255,255,.16); border-radius:4px; background:rgba(0,0,0,.25); }
|
||||||
.bratonien-main-cache__bar { width:0; height:100%; background:#66a845; transition:width .25s ease; }
|
.bratonien-main-cache__bar { width:0; height:100%; background:#66a845; transition:width .25s ease; }
|
||||||
.bratonien-main-cache__progress.is-error .bratonien-main-cache__bar { background:#c95b5b; }
|
.bratonien-main-cache__progress.is-error .bratonien-main-cache__bar { background:#c95b5b; }
|
||||||
.bratonien-main-cache__progress.is-queued .bratonien-main-cache__bar { background:#a7834d; }
|
.bratonien-main-cache__progress.is-queued .bratonien-main-cache__bar { background:#a7834d; }
|
||||||
|
.bratonien-main-cache__progress.is-cancelling .bratonien-main-cache__bar { background:#d6ae62; }
|
||||||
.bratonien-main-cache__details { margin-top:8px; color:#a9a9a9; line-height:1.45; }
|
.bratonien-main-cache__details { margin-top:8px; color:#a9a9a9; line-height:1.45; }
|
||||||
.bratonien-main-cache__current { margin-top:4px; font-size:12px; color:#8f8f8f; overflow-wrap:anywhere; }
|
.bratonien-main-cache__current { margin-top:4px; font-size:12px; color:#8f8f8f; overflow-wrap:anywhere; }
|
||||||
@media (max-width:850px) {
|
@media (max-width:850px) {
|
||||||
@@ -107,7 +110,7 @@
|
|||||||
<label>Deckkraft</label><span><input type="number" name="profile_opacity" value="{$profile.opacity}" min="1" max="100" size="3" data-watermark-opacity> %</span><span class="bratonien-label">Mindestgröße</span><span class="bratonien-inline"><input type="number" name="profile_min_width" value="{$profile.min_width}" min="0" size="5"> × <input type="number" name="profile_min_height" value="{$profile.min_height}" min="0" size="5"></span>
|
<label>Deckkraft</label><span><input type="number" name="profile_opacity" value="{$profile.opacity}" min="1" max="100" size="3" data-watermark-opacity> %</span><span class="bratonien-label">Mindestgröße</span><span class="bratonien-inline"><input type="number" name="profile_min_width" value="{$profile.min_width}" min="0" size="5"> × <input type="number" name="profile_min_height" value="{$profile.min_height}" min="0" size="5"></span>
|
||||||
</div><div class="bratonien-scale-editor"><div class="bratonien-scale-editor__title">Größe & Vorschau</div><div class="bratonien-scale-grid"><div class="bratonien-scale-fields"><span class="bratonien-label">Originalgröße</span><span data-original-size>{if $profile.original_width}{$profile.original_width} × {$profile.original_height} px{else}Keine Datei gewählt{/if}</span><label>Skalierung</label><span><input type="number" name="profile_scale_percent" value="{$profile.scale_percent}" min="1" max="1000" step="0.1" data-scale-percent> %</span><label>Breite</label><span><input type="number" min="1" step="1" data-scale-width> px</span><label>Höhe</label><span><input type="number" min="1" step="1" data-scale-height> px</span><span class="bratonien-label">Seitenverhältnis</span><span class="bratonien-lock">🔒 gesperrt</span></div><div><div class="bratonien-scale-preview__stage" data-preview-stage>{if $profile.preview_url}<img src="{$profile.preview_url|escape:html}" alt="Vorschau" data-preview-image>{else}<span class="bratonien-scale-preview__empty" data-preview-empty>Keine Wasserzeichendatei gewählt</span><img src="" alt="Vorschau" data-preview-image style="display:none">{/if}</div><div class="bratonien-scale-preview__info" data-preview-info></div></div></div></div><div class="bratonien-actions"><button class="buttonLike" type="submit" name="bratonien_tool" value="watermark_profile_save">Speichern</button><button class="buttonLike" type="submit" name="bratonien_tool" value="watermark_profile_duplicate">Duplizieren</button><button class="buttonLike" type="submit" name="bratonien_tool" value="watermark_profile_delete" onclick="return confirm('Profil wirklich löschen?');">Löschen</button></div></form></div></details>
|
</div><div class="bratonien-scale-editor"><div class="bratonien-scale-editor__title">Größe & Vorschau</div><div class="bratonien-scale-grid"><div class="bratonien-scale-fields"><span class="bratonien-label">Originalgröße</span><span data-original-size>{if $profile.original_width}{$profile.original_width} × {$profile.original_height} px{else}Keine Datei gewählt{/if}</span><label>Skalierung</label><span><input type="number" name="profile_scale_percent" value="{$profile.scale_percent}" min="1" max="1000" step="0.1" data-scale-percent> %</span><label>Breite</label><span><input type="number" min="1" step="1" data-scale-width> px</span><label>Höhe</label><span><input type="number" min="1" step="1" data-scale-height> px</span><span class="bratonien-label">Seitenverhältnis</span><span class="bratonien-lock">🔒 gesperrt</span></div><div><div class="bratonien-scale-preview__stage" data-preview-stage>{if $profile.preview_url}<img src="{$profile.preview_url|escape:html}" alt="Vorschau" data-preview-image>{else}<span class="bratonien-scale-preview__empty" data-preview-empty>Keine Wasserzeichendatei gewählt</span><img src="" alt="Vorschau" data-preview-image style="display:none">{/if}</div><div class="bratonien-scale-preview__info" data-preview-info></div></div></div></div><div class="bratonien-actions"><button class="buttonLike" type="submit" name="bratonien_tool" value="watermark_profile_save">Speichern</button><button class="buttonLike" type="submit" name="bratonien_tool" value="watermark_profile_duplicate">Duplizieren</button><button class="buttonLike" type="submit" name="bratonien_tool" value="watermark_profile_delete" onclick="return confirm('Profil wirklich löschen?');">Löschen</button></div></form></div></details>
|
||||||
{/foreach}
|
{/foreach}
|
||||||
<details class="bratonien-profile"><summary>+ Neues Profil</summary><div class="bratonien-profile__body"><form method="post" data-watermark-editor><input type="hidden" name="pwg_token" value="{$PWG_TOKEN|escape:html}"><div class="bratonien-form-grid"><label>Name</label><span class="bratonien-inline"><input name="profile_name" size="28"> <label><input type="checkbox" name="profile_active" value="1" checked> aktiv</label></span><label>Datei</label><select name="profile_file" data-watermark-file><option value="" data-width="0" data-height="0" data-url="">Keine Datei</option>{foreach from=$WATERMARK_OPTIONS item=option}<option value="{$option.file|escape:html}" data-width="{$option.width}" data-height="{$option.height}" data-url="{$option.url|escape:html}">{$option.name|escape:html}</option>{/foreach}</select><span class="bratonien-label">Position</span><span class="bratonien-inline">X <input type="number" name="profile_xpos" value="90" min="0" max="100" size="3"> Y <input type="number" name="profile_ypos" value="90" min="0" max="100" size="3"></span><span class="bratonien-label">Wiederholen</span><span class="bratonien-inline">X <input type="number" name="profile_xrepeat" value="0" min="0" max="20" size="3"> Y <input type="number" name="profile_yrepeat" value="0" min="0" max="20" size="3"></span><label>Deckkraft</label><span><input type="number" name="profile_opacity" value="35" min="1" max="100" size="3" data-watermark-opacity> %</span><span class="bratonien-label">Mindestgröße</span><span class="bratonien-inline"><input type="number" name="profile_min_width" value="10" min="0" size="5"> × <input type="number" name="profile_min_height" value="10" min="0" size="5"></span></div><div class="bratonien-scale-editor"><div class="bratonien-scale-editor__title">Größe & Vorschau</div><div class="bratonien-scale-grid"><div class="bratonien-scale-fields"><span class="bratonien-label">Originalgröße</span><span data-original-size>Keine Datei gewählt</span><label>Skalierung</label><span><input type="number" name="profile_scale_percent" value="{$WATERMARK.scale_percent}" min="1" max="1000" step="0.1" data-scale-percent> %</span><label>Breite</label><span><input type="number" min="1" step="1" data-scale-width> px</span><label>Höhe</label><span><input type="number" min="1" step="1" data-scale-height> px</span><span class="bratonien-label">Seitenverhältnis</span><span class="bratonien-lock">🔒 gesperrt</span></div><div><div class="bratonien-scale-preview__stage" data-preview-stage><span class="bratonien-scale-preview__empty" data-preview-empty>Keine Wasserzeichendatei gewählt</span><img src="" alt="Vorschau" data-preview-image style="display:none"></div><div class="bratonien-scale-preview__info" data-preview-info></div></div></div></div><div class="bratonien-actions"><button class="buttonLike" type="submit" name="bratonien_tool" value="watermark_profile_save">Profil anlegen</button></div></form></div></details>
|
<details class="bratonien-profile"><summary>+ Neues Profil</summary><div class="bratonien-profile__body"><form method="post" data-watermark-editor><input type="hidden" name="pwg_token" value="{$PWG_TOKEN|escape:html}"><div class="bratonien-form-grid"><label>Name</label><span class="bratonien-inline"><input name="profile_name" size="28"> <label><input type="checkbox" name="profile_active" value="1" checked> aktiv</label></span><label>Datei</label><select name="profile_file" data-watermark-file><option value="" data-width="0" data-height="0" data-url="">Keine Datei</option>{foreach from=$WATERMARK_OPTIONS item=option}<option value="{$option.file|escape:html}" data-width="{$option.width}" data-height="{$option.height}" data-url="{$option.url|escape:html}">{$option.name|escape:html}</option>{/foreach}</select><span class="bratonien-label">Position</span><span class="bratonien-inline">X <input type="number" name="profile_xpos" value="90" min="0" max="100" size="3"> Y <input type="number" name="profile_ypos" value="90" min="0" max="100" size="3"></span><span class="bratonien-label">Wiederholen</span><span class="bratonien-inline">X <input type="number" name="profile_xrepeat" value="0" min="0" max="20" size="3"> Y <input type="number" name="profile_yrepeat" value="0" min="0" max="20" size="3"></span><label>Deckkraft</label><span><input type="number" name="profile_opacity" value="35" min="1" max="100" size="3" data-watermark-opacity> %</span><span class="bratonien-label">Mindestgröße</span><span class="bratonien-inline"><input type="number" name="profile_min_width" value="10" min="0" size="5"> × <input type="number" name="profile_min_height" value="10" min="0" size="5"></span></div><div class="bratonien-scale-editor"><div class="bratonien-scale-editor__title">Größe & Vorschau</div><div class="bratonien-scale-grid"><div class="bratonien-scale-fields"><span class="bratonien-label">Originalgröße</span><span data-original-size>Keine Datei gewählt</span><label>Skalierung</label><span><input type="number" name="profile_scale_percent" value="{$WATERMARK.scale_percent}" min="1" max="1000" step="0.1" data-scale-percent> %</span><label>Breite</label><span><input type="number" min="1" step="1" data-scale-width> px</span><label>Höhe</label><span><input type="number" min="1" step="1" data-scale-height> px</span><span class="bratonien-label">Seitenverhältnis</span><span class="bratonien-lock">🔒 gesperrt</span></div><div><div class="bratonien-scale-preview__stage" data-preview-stage><span class="bratonien-scale-preview__empty" data-preview-empty>Keine Wasserzeichendatei gewählt</span><img src="" alt="Vorschau" data-preview-image style="display:none">{/if}</div><div class="bratonien-scale-preview__info" data-preview-info></div></div></div></div><div class="bratonien-actions"><button class="buttonLike" type="submit" name="bratonien_tool" value="watermark_profile_save">Profil anlegen</button></div></form></div></details>
|
||||||
</div></div>
|
</div></div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
@@ -117,13 +120,16 @@
|
|||||||
<h3>Wartung</h3><p class="bratonien-section__intro">Werkzeuge, die nicht zur täglichen Konfiguration gehören.</p>
|
<h3>Wartung</h3><p class="bratonien-section__intro">Werkzeuge, die nicht zur täglichen Konfiguration gehören.</p>
|
||||||
<div class="bratonien-card">
|
<div class="bratonien-card">
|
||||||
<h4>Bildcache</h4>
|
<h4>Bildcache</h4>
|
||||||
<p>Löscht alle erzeugten Piwigo- und Bratonien-Bildderivate. Originalbilder bleiben erhalten. Benötigte Varianten werden beim nächsten Aufruf automatisch neu erzeugt.</p>
|
<p>Löscht alle erzeugten Piwigo- und Bratonien-Bildderivate. Originalbilder bleiben erhalten. Ein laufender manueller Cache-Aufbau wird vorher beendet.</p>
|
||||||
<form method="post"><input type="hidden" name="pwg_token" value="{$PWG_TOKEN|escape:html}"><button class="buttonLike" type="submit" name="bratonien_tool" value="image_cache_clear" onclick="return confirm('Wirklich den gesamten Bildcache leeren? Benötigte Varianten werden anschließend bei Bedarf neu erzeugt.');">Bildcache leeren</button></form>
|
<form method="post"><input type="hidden" name="pwg_token" value="{$PWG_TOKEN|escape:html}"><button class="buttonLike" type="submit" name="bratonien_tool" value="image_cache_clear" onclick="return confirm('Wirklich den gesamten Bildcache leeren? Ein laufender Cache-Aufbau wird vorher abgebrochen.');">Bildcache leeren</button></form>
|
||||||
<div class="bratonien-main-cache">
|
<div class="bratonien-main-cache">
|
||||||
<h4>Piwigo-Bildcache vorbereiten</h4>
|
<h4>Piwigo-Bildcache vorbereiten</h4>
|
||||||
<p>Erzeugt die normalen Piwigo-Bildgrößen vorab. Bratonien-Wasserzeichen werden weiterhin nur bei Bedarf erzeugt.</p>
|
<p>Erzeugt die normalen Piwigo-Bildgrößen vorab. Bratonien-Wasserzeichen werden weiterhin nur bei Bedarf erzeugt.</p>
|
||||||
<p class="bratonien-main-cache__warning"><strong>Experimentell:</strong> Der manuelle Cache-Aufbau nutzt vier parallele Worker und kann CPU, Arbeitsspeicher und Datenträger des LXC deutlich belasten. Diese Warnung wird entfernt, sobald der Ablauf im Dauerbetrieb stabil ist.</p>
|
<p class="bratonien-main-cache__warning"><strong>Experimentell:</strong> Der manuelle Cache-Aufbau nutzt sechs parallele Worker und kann CPU, Arbeitsspeicher und Datenträger des LXC deutlich belasten. Diese Warnung wird entfernt, sobald der Ablauf im Dauerbetrieb stabil ist.</p>
|
||||||
|
<div class="bratonien-main-cache__controls">
|
||||||
<form method="post"><input type="hidden" name="pwg_token" value="{$PWG_TOKEN|escape:html}"><button class="buttonLike" type="submit" name="bratonien_tool" value="image_cache_build">Piwigo-Bildcache aufbauen</button></form>
|
<form method="post"><input type="hidden" name="pwg_token" value="{$PWG_TOKEN|escape:html}"><button class="buttonLike" type="submit" name="bratonien_tool" value="image_cache_build">Piwigo-Bildcache aufbauen</button></form>
|
||||||
|
<form method="post" class="bratonien-main-cache__cancel" data-cache-cancel-form><input type="hidden" name="pwg_token" value="{$PWG_TOKEN|escape:html}"><button class="buttonLike bratonien-delete-button" type="submit" name="bratonien_tool" value="image_cache_cancel">Cache-Aufbau abbrechen</button></form>
|
||||||
|
</div>
|
||||||
<div class="bratonien-main-cache__progress" data-main-cache-progress data-status-url="{$MAIN_CACHE_STATUS_URL|escape:html}">
|
<div class="bratonien-main-cache__progress" data-main-cache-progress data-status-url="{$MAIN_CACHE_STATUS_URL|escape:html}">
|
||||||
<div class="bratonien-main-cache__head"><strong data-cache-title>Cache-Aufbau</strong><strong data-cache-percent>0 %</strong></div>
|
<div class="bratonien-main-cache__head"><strong data-cache-title>Cache-Aufbau</strong><strong data-cache-percent>0 %</strong></div>
|
||||||
<div class="bratonien-main-cache__track" role="progressbar" aria-label="Piwigo-Bildcache" aria-valuemin="0" aria-valuemax="100" aria-valuenow="0" data-cache-track><div class="bratonien-main-cache__bar" data-cache-bar></div></div>
|
<div class="bratonien-main-cache__track" role="progressbar" aria-label="Piwigo-Bildcache" aria-valuemin="0" aria-valuemax="100" aria-valuenow="0" data-cache-track><div class="bratonien-main-cache__bar" data-cache-bar></div></div>
|
||||||
@@ -154,15 +160,16 @@ document.querySelectorAll('[data-watermark-editor]').forEach(initWatermarkEditor
|
|||||||
|
|
||||||
function initMainCacheProgress(){
|
function initMainCacheProgress(){
|
||||||
var box=document.querySelector('[data-main-cache-progress]');if(!box)return;
|
var box=document.querySelector('[data-main-cache-progress]');if(!box)return;
|
||||||
var url=box.getAttribute('data-status-url'),title=box.querySelector('[data-cache-title]'),percentEl=box.querySelector('[data-cache-percent]'),details=box.querySelector('[data-cache-details]'),current=box.querySelector('[data-cache-current]'),bar=box.querySelector('[data-cache-bar]'),track=box.querySelector('[data-cache-track]'),timer=null,hideTimer=null;
|
var url=box.getAttribute('data-status-url'),title=box.querySelector('[data-cache-title]'),percentEl=box.querySelector('[data-cache-percent]'),details=box.querySelector('[data-cache-details]'),current=box.querySelector('[data-cache-current]'),bar=box.querySelector('[data-cache-bar]'),track=box.querySelector('[data-cache-track]'),cancelForm=document.querySelector('[data-cache-cancel-form]'),timer=null,hideTimer=null;
|
||||||
function schedule(ms){if(timer)clearTimeout(timer);timer=setTimeout(load,ms);}
|
function schedule(ms){if(timer)clearTimeout(timer);timer=setTimeout(load,ms);}
|
||||||
function render(data){
|
function render(data){
|
||||||
var state=data.state||'idle',total=Math.max(0,parseInt(data.total,10)||0),completed=Math.max(0,parseInt(data.completed,10)||0),percent=total>0?Math.min(100,Math.round(completed/total*100)):(state==='complete'?100:0);
|
var state=data.state||'idle',total=Math.max(0,parseInt(data.total,10)||0),completed=Math.max(0,parseInt(data.completed,10)||0),percent=total>0?Math.min(100,Math.round(completed/total*100)):(state==='complete'?100:0);
|
||||||
box.classList.toggle('is-error',state==='error');box.classList.toggle('is-queued',state==='queued');bar.style.width=percent+'%';track.setAttribute('aria-valuenow',String(percent));percentEl.textContent=percent+' %';
|
box.classList.toggle('is-error',state==='error');box.classList.toggle('is-queued',state==='queued');box.classList.toggle('is-cancelling',state==='cancelling');bar.style.width=percent+'%';track.setAttribute('aria-valuenow',String(percent));percentEl.textContent=percent+' %';
|
||||||
var labels={queued:'Cache-Aufbau wartet',running:'Cache-Aufbau läuft',complete:'Cache-Aufbau fertig',error:'Cache-Aufbau mit Fehlern'};title.textContent=labels[state]||'Cache-Aufbau';
|
var labels={queued:'Cache-Aufbau wartet',running:'Cache-Aufbau läuft',cancelling:'Cache-Aufbau wird abgebrochen',cancelled:'Cache-Aufbau abgebrochen',complete:'Cache-Aufbau fertig',error:'Cache-Aufbau mit Fehlern'};title.textContent=labels[state]||'Cache-Aufbau';
|
||||||
details.textContent=(data.message||'')+(total>0?' · '+completed+' / '+total+' Varianten · '+(parseInt(data.generated,10)||0)+' neu · '+(parseInt(data.cached,10)||0)+' vorhanden · '+(parseInt(data.skipped,10)||0)+' übersprungen · '+(parseInt(data.errors,10)||0)+' Fehler':'');current.textContent=data.current?('Aktuell: '+data.current):'';
|
details.textContent=(data.message||'')+(total>0?' · '+completed+' / '+total+' Varianten · '+(parseInt(data.generated,10)||0)+' neu · '+(parseInt(data.cached,10)||0)+' vorhanden · '+(parseInt(data.skipped,10)||0)+' übersprungen · '+(parseInt(data.errors,10)||0)+' Fehler':'');current.textContent=data.current?('Aktuell: '+data.current):'';
|
||||||
if(state==='queued'||state==='running'||state==='error'){if(hideTimer){clearTimeout(hideTimer);hideTimer=null;}box.style.display='block';}
|
if(cancelForm)cancelForm.style.display=(state==='queued'||state==='running'||state==='cancelling')?'block':'none';
|
||||||
if(state==='queued'||state==='running'){schedule(1000);}else if(state==='complete'){box.style.display='block';if(hideTimer)clearTimeout(hideTimer);hideTimer=setTimeout(function(){box.style.display='none';},5000);}else if(state==='idle'){box.style.display='none';}
|
if(state==='queued'||state==='running'||state==='cancelling'||state==='error'){if(hideTimer){clearTimeout(hideTimer);hideTimer=null;}box.style.display='block';}
|
||||||
|
if(state==='queued'||state==='running'||state==='cancelling'){schedule(1000);}else if(state==='complete'||state==='cancelled'){box.style.display='block';if(hideTimer)clearTimeout(hideTimer);hideTimer=setTimeout(function(){box.style.display='none';},5000);}else if(state==='idle'){box.style.display='none';}
|
||||||
}
|
}
|
||||||
function load(){fetch(url+(url.indexOf('?')===-1?'?':'&')+'_='+(Date.now()),{credentials:'same-origin',cache:'no-store'}).then(function(r){if(!r.ok)throw new Error('HTTP '+r.status);return r.json();}).then(render).catch(function(){box.style.display='block';box.classList.add('is-error');details.textContent='Cache-Status konnte nicht geladen werden.';});}
|
function load(){fetch(url+(url.indexOf('?')===-1?'?':'&')+'_='+(Date.now()),{credentials:'same-origin',cache:'no-store'}).then(function(r){if(!r.ok)throw new Error('HTTP '+r.status);return r.json();}).then(render).catch(function(){box.style.display='block';box.classList.add('is-error');details.textContent='Cache-Status konnte nicht geladen werden.';});}
|
||||||
load();
|
load();
|
||||||
|
|||||||
Reference in New Issue
Block a user