Owner agenda: hide cancelled bookings by default, with a toggle
Test backoffice (smb-crm) / test (push) Successful in 1m35s
Test backoffice (smb-crm) / test (push) Successful in 1m35s
Cancelled bookings previously stayed visible (struck-through) in the week view permanently, cluttering it over time. Adds a "Stornierte anzeigen" checkbox next to the Filiale toggles -- unchecked by default so cancelled rows are hidden, checkable to bring them back for history/audit purposes. Client-side filter, remembered via localStorage like the Filiale toggle. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -55,14 +55,15 @@
|
|||||||
<body>
|
<body>
|
||||||
<h1>{{ client.business_name if client else 'Kalender' }}</h1>
|
<h1>{{ client.business_name if client else 'Kalender' }}</h1>
|
||||||
|
|
||||||
{% if resources|length > 1 %}
|
|
||||||
<div class="filiale-filter" id="filialeFilter">
|
<div class="filiale-filter" id="filialeFilter">
|
||||||
|
{% if resources|length > 1 %}
|
||||||
<p class="flabel">Filialen:</p>
|
<p class="flabel">Filialen:</p>
|
||||||
{% for r in resources %}
|
{% for r in resources %}
|
||||||
<label><input type="checkbox" class="res-toggle" value="{{ r.resource_id }}" checked> {{ r.name }}</label>
|
<label><input type="checkbox" class="res-toggle" value="{{ r.resource_id }}" checked> {{ r.name }}</label>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
<label><input type="checkbox" id="showCancelled"> Stornierte anzeigen</label>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% if error == "missing_fields" %}
|
{% if error == "missing_fields" %}
|
||||||
<div class="error">Bitte alle Felder ausfüllen.</div>
|
<div class="error">Bitte alle Felder ausfüllen.</div>
|
||||||
@@ -122,7 +123,7 @@
|
|||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<p class="day-no-match">Keine Buchungen für die ausgewählten Filialen.</p>
|
<p class="day-no-match">Keine Buchungen für die aktuelle Filter-Auswahl.</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
@@ -168,25 +169,37 @@
|
|||||||
<p class="muted" style="margin-top:20px;"><a href="{{ url_for('owner_auth.dashboard') }}">Zurück</a></p>
|
<p class="muted" style="margin-top:20px;"><a href="{{ url_for('owner_auth.dashboard') }}">Zurück</a></p>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
// Per-Filiale show/hide (#toggle both/either), remembered across
|
// Per-Filiale show/hide + hide-cancelled-by-default, remembered across
|
||||||
// week navigation via localStorage since each week is a full page load.
|
// week navigation via localStorage since each week is a full page load.
|
||||||
(function () {
|
(function () {
|
||||||
var STORAGE_KEY = 'ownerAgendaFilialeFilter';
|
var RES_KEY = 'ownerAgendaFilialeFilter';
|
||||||
|
var CANCELLED_KEY = 'ownerAgendaShowCancelled';
|
||||||
var checkboxes = document.querySelectorAll('.res-toggle');
|
var checkboxes = document.querySelectorAll('.res-toggle');
|
||||||
if (!checkboxes.length) return;
|
var showCancelledCb = document.getElementById('showCancelled');
|
||||||
|
if (!checkboxes.length && !showCancelledCb) return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
var saved = JSON.parse(localStorage.getItem(STORAGE_KEY) || 'null');
|
var saved = JSON.parse(localStorage.getItem(RES_KEY) || 'null');
|
||||||
if (saved && saved.length) {
|
if (saved && saved.length) {
|
||||||
checkboxes.forEach(function (cb) { cb.checked = saved.indexOf(cb.value) !== -1; });
|
checkboxes.forEach(function (cb) { cb.checked = saved.indexOf(cb.value) !== -1; });
|
||||||
}
|
}
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (showCancelledCb) {
|
||||||
|
showCancelledCb.checked = localStorage.getItem(CANCELLED_KEY) === '1';
|
||||||
|
}
|
||||||
|
} catch (e) {}
|
||||||
|
|
||||||
function applyFilter() {
|
function applyFilter() {
|
||||||
var active = [];
|
var active = [];
|
||||||
checkboxes.forEach(function (cb) { if (cb.checked) active.push(cb.value); });
|
checkboxes.forEach(function (cb) { if (cb.checked) active.push(cb.value); });
|
||||||
|
var showCancelled = !!(showCancelledCb && showCancelledCb.checked);
|
||||||
|
|
||||||
document.querySelectorAll('table tbody tr[data-resource]').forEach(function (tr) {
|
document.querySelectorAll('table tbody tr[data-resource]').forEach(function (tr) {
|
||||||
tr.classList.toggle('res-hidden', active.indexOf(tr.getAttribute('data-resource')) === -1);
|
var resOk = !checkboxes.length || active.indexOf(tr.getAttribute('data-resource')) !== -1;
|
||||||
|
var statusOk = showCancelled || !tr.classList.contains('status-cancelled');
|
||||||
|
tr.classList.toggle('res-hidden', !(resOk && statusOk));
|
||||||
});
|
});
|
||||||
document.querySelectorAll('.day').forEach(function (dayEl) {
|
document.querySelectorAll('.day').forEach(function (dayEl) {
|
||||||
var table = dayEl.querySelector('table');
|
var table = dayEl.querySelector('table');
|
||||||
@@ -198,10 +211,12 @@
|
|||||||
table.style.display = anyVisible ? '' : 'none';
|
table.style.display = anyVisible ? '' : 'none';
|
||||||
if (noMatch) noMatch.style.display = anyVisible ? 'none' : 'block';
|
if (noMatch) noMatch.style.display = anyVisible ? 'none' : 'block';
|
||||||
});
|
});
|
||||||
try { localStorage.setItem(STORAGE_KEY, JSON.stringify(active)); } catch (e) {}
|
try { localStorage.setItem(RES_KEY, JSON.stringify(active)); } catch (e) {}
|
||||||
|
try { localStorage.setItem(CANCELLED_KEY, showCancelled ? '1' : '0'); } catch (e) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
checkboxes.forEach(function (cb) { cb.addEventListener('change', applyFilter); });
|
checkboxes.forEach(function (cb) { cb.addEventListener('change', applyFilter); });
|
||||||
|
if (showCancelledCb) showCancelledCb.addEventListener('change', applyFilter);
|
||||||
applyFilter();
|
applyFilter();
|
||||||
})();
|
})();
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
Reference in New Issue
Block a user