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:
@@ -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>
|
||||
|
||||
@@ -4,23 +4,23 @@ $orderId = (int)($this -> order['id'] ?? 0);
|
||||
|
||||
<div class="site-title">Szczegóły zamówienia: <?= htmlspecialchars((string)($this -> order['number'] ?? ''), ENT_QUOTES, 'UTF-8');?></div>
|
||||
|
||||
<div class="mb15">
|
||||
<a href="/admin/shop_order/list/" class="btn btn-dark btn-sm mr5">
|
||||
<i class="fa fa-reply"></i> Wstecz
|
||||
<div class="od-actions mb15">
|
||||
<a href="/admin/shop_order/list/" class="btn btn-dark btn-sm">
|
||||
<i class="fa fa-reply"></i> <span class="od-actions-label">Wstecz</span>
|
||||
</a>
|
||||
<a href="/admin/shop_order/order_edit/order_id=<?= $orderId;?>" class="btn btn-danger btn-sm mr5">
|
||||
<i class="fa fa-pencil"></i> Edytuj zamówienie
|
||||
<a href="/admin/shop_order/order_edit/order_id=<?= $orderId;?>" class="btn btn-danger btn-sm">
|
||||
<i class="fa fa-pencil"></i> <span class="od-actions-label">Edytuj</span>
|
||||
</a>
|
||||
|
||||
<? if ( $this -> prev_order_id ):?>
|
||||
<a href="/admin/shop_order/order_details/order_id=<?= (int)$this -> prev_order_id;?>" class="btn btn-success btn-sm mr5">
|
||||
<i class="fa fa-arrow-left"></i> Poprzednie zamówienie
|
||||
<a href="/admin/shop_order/order_details/order_id=<?= (int)$this -> prev_order_id;?>" class="btn btn-success btn-sm">
|
||||
<i class="fa fa-arrow-left"></i> <span class="od-actions-label">Poprzednie</span>
|
||||
</a>
|
||||
<? endif;?>
|
||||
|
||||
<? if ( $this -> next_order_id ):?>
|
||||
<a href="/admin/shop_order/order_details/order_id=<?= (int)$this -> next_order_id;?>" class="btn btn-success btn-sm mr5">
|
||||
<i class="fa fa-arrow-right"></i> Następne zamówienie
|
||||
<a href="/admin/shop_order/order_details/order_id=<?= (int)$this -> next_order_id;?>" class="btn btn-success btn-sm">
|
||||
<i class="fa fa-arrow-right"></i> <span class="od-actions-label">Następne</span>
|
||||
</a>
|
||||
<? endif;?>
|
||||
|
||||
@@ -183,6 +183,9 @@ $orderId = (int)($this -> order['id'] ?? 0);
|
||||
<div class="product-message">
|
||||
<?= $product[ 'message' ] != '' ? '<strong>Wiadomość:</strong> ' . $product['message'] : '';?>
|
||||
</div>
|
||||
<div class="od-mobile-price-line">
|
||||
<?= (int)$product['quantity'];?> × <?= \Shared\Helpers\Helpers::decimal( $product['price_brutto_promo'] );?> = <?= \Shared\Helpers\Helpers::decimal( $product['price_brutto_promo'] * $product['quantity'] );?> zł
|
||||
</div>
|
||||
</td>
|
||||
<td class="tab-center"><?= $product[ 'quantity' ];?></td>
|
||||
<td class="tab-right"><?= \Shared\Helpers\Helpers::decimal( $product[ 'price_brutto' ] );?> zł</td>
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
<script type="text/javascript" src="/admin/js/functions.js"></script>
|
||||
<link rel="stylesheet" href="/admin/layout/style-css/style.css" />
|
||||
<link rel="stylesheet" href="/admin/layout/style-css/table-list.css" />
|
||||
<link rel="stylesheet" href="/admin/layout/style-css/order-details-mobile.css" />
|
||||
</head>
|
||||
<body>
|
||||
<div class="admin-page">
|
||||
|
||||
Reference in New Issue
Block a user