ver. 0.301: Collapsible table filters and mobile-responsive order details

- Table filters hidden by default with toggle button (icon + active count badge)
- Filter state persisted in localStorage; auto-show when filters active
- Order details mobile layout: icon-only action bar, full-width stacking,
  compact product list (image + name + qty x price = total), bottom-sheet
  dropdown for integrations menu

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-22 13:53:43 +01:00
parent b409806f02
commit f2b2629d49
7 changed files with 348 additions and 13 deletions

View File

@@ -19,6 +19,14 @@ $totalPages = max(1, (int)($list->pagination['total_pages'] ?? 1));
$total = (int)($list->pagination['total'] ?? 0);
$perPage = (int)($list->pagination['per_page'] ?? 15);
$hasActiveFilters = false;
foreach ($list->filters as $filter) {
if (isset($filter['value']) && (string)$filter['value'] !== '') {
$hasActiveFilters = true;
break;
}
}
$isCompactColumn = function(array $column): bool {
$key = strtolower(trim((string)($column['key'] ?? '')));
$label = strtolower(trim((string)($column['label'] ?? '')));
@@ -48,6 +56,14 @@ $isCompactColumn = function(array $column): bool {
<div class="col-sm-4 text-right">
<div class="table-list-header-actions">
<span class="text-muted">Wyników: <?= $total; ?></span>
<?php if (!empty($list->filters)): ?>
<button type="button" class="btn btn-default btn-sm js-filter-toggle-btn<?= $hasActiveFilters ? ' active' : ''; ?>" title="Filtry">
<i class="fa fa-filter"></i>
<?php if ($hasActiveFilters): ?>
<span class="badge badge-primary table-filter-badge"><?= count(array_filter($list->filters, function($f) { return isset($f['value']) && (string)$f['value'] !== ''; })); ?></span>
<?php endif; ?>
</button>
<?php endif; ?>
<div class="table-col-toggle-wrapper">
<button type="button" class="btn btn-default btn-sm js-col-toggle-btn" title="Widoczność kolumn">
<i class="fa fa-columns"></i>
@@ -75,6 +91,7 @@ $isCompactColumn = function(array $column): bool {
</div>
<div class="panel-body">
<div class="js-table-filters-wrapper table-filters-wrapper<?= $hasActiveFilters ? ' open' : ''; ?>">
<form method="get" action="<?= htmlspecialchars($list->basePath, ENT_QUOTES, 'UTF-8'); ?>" class="row mb15 js-table-filters-form">
<?php foreach ($list->filters as $filter): ?>
<?php
@@ -148,6 +165,7 @@ $isCompactColumn = function(array $column): bool {
<a href="<?= htmlspecialchars($list->basePath, ENT_QUOTES, 'UTF-8'); ?>" class="btn btn-default btn-sm">Wyczyść</a>
</div>
</form>
</div>
<div class="table-responsive">
<table class="table table-hover table-striped table-bordered mbn table-list-table">
@@ -469,5 +487,47 @@ $isCompactColumn = function(array $column): bool {
saveHiddenCols([]);
applyColumnVisibility([]);
});
// --- Filter toggle ---
var filterStorageKey = 'tableListFilters_' + <?= json_encode($list->basePath); ?>;
function isFilterVisible() {
try {
return localStorage.getItem(filterStorageKey) === '1';
} catch (e) {}
return false;
}
function saveFilterState(visible) {
try {
localStorage.setItem(filterStorageKey, visible ? '1' : '0');
} catch (e) {}
}
var $filterWrapper = $('.js-table-filters-wrapper');
var $filterBtn = $('.js-filter-toggle-btn');
var hasActiveFilters = $filterWrapper.hasClass('open');
if (!hasActiveFilters && isFilterVisible()) {
$filterWrapper.addClass('open');
$filterBtn.addClass('active');
}
$(document).off('click.filterToggle', '.js-filter-toggle-btn');
$(document).on('click.filterToggle', '.js-filter-toggle-btn', function() {
var $wrapper = $('.js-table-filters-wrapper');
var $btn = $(this);
var isOpen = $wrapper.hasClass('open');
if (isOpen) {
$wrapper.removeClass('open');
$btn.removeClass('active');
saveFilterState(false);
} else {
$wrapper.addClass('open');
$btn.addClass('active');
saveFilterState(true);
}
});
})(window.jQuery);
</script>