feat: Integrate Pagination component into ASNsNewManager, DomainsNewManager, IPRangesManager, and FilterManager for improved navigation and user experience across multiple pages of data.
Publish Fast Tabler Docker image / build-and-push-fast (push) Successful in 1m46s

This commit is contained in:
2025-12-24 15:29:46 +07:00
parent f4a6ceed08
commit 6dfcaa584d
6 changed files with 162 additions and 261 deletions
+8 -52
View File
@@ -42,6 +42,7 @@ import AccordionCard from './components/AccordionCard.jsx';
import SavedFilters from './components/SavedFilters.jsx';
import BulkActionsBar from './components/BulkActionsBar.jsx';
import Tooltip from './components/Tooltip.jsx';
import Pagination from './components/Pagination.jsx';
const API_URL = '/api';
@@ -1132,58 +1133,13 @@ function IPRangesManager() {
</div>
)}
{/* Пагинация */}
{totalPages > 1 && (
<div className="card-footer">
<div className="d-flex align-items-center justify-content-between flex-wrap gap-2">
<div className="text-muted small">
Показано <strong>{((currentPage - 1) * pageSize) + 1}</strong> - <strong>{((currentPage - 1) * pageSize) + paginatedItems.length}</strong> из <strong>{totalItems || filtered.length}</strong>
</div>
<ul className="pagination m-0">
<li className={`page-item${currentPage === 1 ? ' disabled' : ''}`}>
<button className="page-link" onClick={() => setCurrentPage(1)} disabled={currentPage === 1} aria-label="Первая страница">
<IconArrowUp size={14} style={{ transform: 'rotate(-90deg)' }} />
</button>
</li>
<li className={`page-item${currentPage === 1 ? ' disabled' : ''}`}>
<button className="page-link" onClick={() => setCurrentPage(currentPage - 1)} disabled={currentPage === 1} aria-label="Предыдущая страница">
<IconArrowUp size={14} style={{ transform: 'rotate(-90deg)' }} />
<span className="d-none d-sm-inline ms-1">Назад</span>
</button>
</li>
{(() => {
const pages = [];
let start = Math.max(1, currentPage - 2);
let end = Math.min(totalPages, currentPage + 2);
if (currentPage <= 3) end = Math.min(totalPages, 5);
if (currentPage >= totalPages - 2) start = Math.max(1, totalPages - 4);
if (start > 1) pages.push('start-ellipsis');
for (let p = start; p <= end; p++) pages.push(p);
if (end < totalPages) pages.push('end-ellipsis');
return pages.map((p) => (
p === 'start-ellipsis' || p === 'end-ellipsis' ? (
<li key={p} className="page-item disabled"><span className="page-link"></span></li>
) : (
<li key={p} className={`page-item${currentPage === p ? ' active' : ''}`}>
<button className="page-link" onClick={() => setCurrentPage(p)} aria-label={`Страница ${p}`} aria-current={currentPage === p ? 'page' : undefined}>{p}</button>
</li>
)
));
})()}
<li className={`page-item${currentPage === totalPages ? ' disabled' : ''}`}>
<button className="page-link" onClick={() => setCurrentPage(currentPage + 1)} disabled={currentPage === totalPages} aria-label="Следующая страница">
<span className="d-none d-sm-inline me-1">Вперед</span>
<IconArrowDown size={14} style={{ transform: 'rotate(-90deg)' }} />
</button>
</li>
<li className={`page-item${currentPage === totalPages ? ' disabled' : ''}`}>
<button className="page-link" onClick={() => setCurrentPage(totalPages)} disabled={currentPage === totalPages} aria-label="Последняя страница">
<IconArrowDown size={14} style={{ transform: 'rotate(-90deg)' }} />
</button>
</li>
</ul>
</div>
</div>
)}
<Pagination
currentPage={currentPage}
totalPages={totalPages}
totalItems={totalItems || filtered.length}
pageSize={pageSize}
onPageChange={setCurrentPage}
/>
<S3MetaBar keys={["ipRanges"]} />
</div>
</div>