feat: Introduce cursor utility class for pointer interactions and refactor action buttons into PageHeaderActions component across multiple managers for improved UI consistency
Publish Fast Tabler Docker image / build-and-push-fast (push) Successful in 5m54s
Publish Fast Tabler Docker image / build-and-push-fast (push) Successful in 5m54s
This commit is contained in:
@@ -15,11 +15,13 @@ import {
|
||||
IconDeviceFloppy,
|
||||
IconHash,
|
||||
IconClock,
|
||||
IconFileText
|
||||
IconFileText,
|
||||
IconEye
|
||||
} from '@tabler/icons-react';
|
||||
import LockBanner from './components/LockBanner.jsx';
|
||||
import TableSkeleton from './components/TableSkeleton.jsx';
|
||||
import S3MetaBar from './components/S3MetaBar.jsx';
|
||||
import PageHeaderActions from './components/PageHeaderActions.jsx';
|
||||
import ConfirmDiffModal from './components/ConfirmDiffModal.jsx';
|
||||
import HistoryModal from './components/HistoryModal.jsx';
|
||||
|
||||
@@ -409,9 +411,21 @@ function IPRangesManager() {
|
||||
<div className="page-pretitle">Главная / Данные / IP ranges</div>
|
||||
</div>
|
||||
<div className="col-auto ms-auto d-print-none">
|
||||
<div className="btn-list">
|
||||
<button className="btn btn-outline-secondary" onClick={() => setHistoryOpen(true)}>История</button>
|
||||
</div>
|
||||
<PageHeaderActions
|
||||
loading={loading}
|
||||
onPreview={handlePreviewDiff}
|
||||
disablePreview={loading || items.length === 0}
|
||||
onRefresh={fetchItems}
|
||||
disableRefresh={loading}
|
||||
onImport={handleImport}
|
||||
onExport={handleExport}
|
||||
disableExport={items.length === 0}
|
||||
onClear={clearInvalid}
|
||||
disableClear={items.length === 0}
|
||||
onSave={handleSaveChanges}
|
||||
disableSave={loading}
|
||||
onHistory={() => setHistoryOpen(true)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -483,73 +497,7 @@ function IPRangesManager() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Actions Card */}
|
||||
<div className="card card-md">
|
||||
<div className="card-header">
|
||||
<h3 className="card-title">
|
||||
<IconDatabase className="icon me-2" />
|
||||
Действия
|
||||
</h3>
|
||||
</div>
|
||||
<div className="card-body">
|
||||
<div className="d-grid gap-2">
|
||||
<button
|
||||
className="btn btn-primary"
|
||||
onClick={handleSaveChanges}
|
||||
disabled={loading}
|
||||
>
|
||||
{loading ? (
|
||||
<>
|
||||
<span className="spinner-border spinner-border-sm me-2" role="status"></span>
|
||||
Сохранение...
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<IconDeviceFloppy className="icon me-2" />
|
||||
Сохранить в S3
|
||||
</>
|
||||
)}
|
||||
</button>
|
||||
<button
|
||||
className="btn btn-outline-secondary"
|
||||
onClick={fetchItems}
|
||||
disabled={loading}
|
||||
>
|
||||
<IconRefresh className="icon me-2" />
|
||||
Обновить
|
||||
</button>
|
||||
<button
|
||||
className="btn btn-outline-primary"
|
||||
onClick={handleImport}
|
||||
>
|
||||
<IconUpload className="icon me-2" />
|
||||
Импорт из буфера
|
||||
</button>
|
||||
<button
|
||||
className="btn btn-outline-primary"
|
||||
onClick={handleExport}
|
||||
disabled={items.length === 0}
|
||||
>
|
||||
<IconDownload className="icon me-2" />
|
||||
Экспорт CSV
|
||||
</button>
|
||||
<button
|
||||
className="btn btn-outline-secondary"
|
||||
onClick={handlePreviewDiff}
|
||||
disabled={loading}
|
||||
>
|
||||
Предпросмотр изменений
|
||||
</button>
|
||||
<button
|
||||
className="btn btn-outline-secondary"
|
||||
onClick={clearInvalid}
|
||||
disabled={items.length === 0}
|
||||
>
|
||||
Очистить пустые/невалидные
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* Карточка действий больше не нужна — действия перенесены в page-header */}
|
||||
</div>
|
||||
|
||||
<div className="col-lg-9">
|
||||
@@ -588,7 +536,7 @@ function IPRangesManager() {
|
||||
<table className="table card-table table-vcenter table-nowrap mb-0">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style={{cursor:'pointer'}} onClick={() => handleSort('ipRange')}>
|
||||
<th className="cursor-pointer" onClick={() => handleSort('ipRange')}>
|
||||
IP-диапазон
|
||||
{sortField === 'ipRange' && (
|
||||
<span className="ms-1">
|
||||
@@ -596,7 +544,7 @@ function IPRangesManager() {
|
||||
</span>
|
||||
)}
|
||||
</th>
|
||||
<th style={{cursor:'pointer'}} onClick={() => handleSort('community')}>
|
||||
<th className="cursor-pointer" onClick={() => handleSort('community')}>
|
||||
Community
|
||||
{sortField === 'community' && (
|
||||
<span className="ms-1">
|
||||
|
||||
Reference in New Issue
Block a user