diff --git a/frontend/src/MikrotikBackupsManager.jsx b/frontend/src/MikrotikBackupsManager.jsx index fbcc559..4240cfa 100644 --- a/frontend/src/MikrotikBackupsManager.jsx +++ b/frontend/src/MikrotikBackupsManager.jsx @@ -6,6 +6,7 @@ import TableSkeleton from './components/TableSkeleton.jsx'; import EmptyState from './components/EmptyState.jsx'; import Tooltip from './components/Tooltip.jsx'; import ServerAutocompleteInput from './components/ServerAutocompleteInput.jsx'; +import DataTable from './components/DataTable.jsx'; import { IconRefresh, IconAlertTriangle, @@ -58,6 +59,13 @@ function MikrotikBackupsManager() { const [diffResult, setDiffResult] = useState(null); const [diffLoading, setDiffLoading] = useState(false); + // UI-состояние для таблицы выбора серверов автобэкапов + const [backupSearch, setBackupSearch] = useState(''); + const [backupSortField, setBackupSortField] = useState('ip'); + const [backupSortOrder, setBackupSortOrder] = useState('asc'); + const [backupPage, setBackupPage] = useState(1); + const backupPageSize = 10; + useEffect(() => { fetchServers(); fetchUiSettings(); @@ -91,6 +99,74 @@ function MikrotikBackupsManager() { const backupServerIdsList = useMemo(() => Array.from(backupServerIds), [backupServerIds]); + // Отфильтрованный и отсортированный список Jumphost-серверов для блока автобэкапов + const filteredBackupServers = useMemo(() => { + let list = [...jumphostInputServers]; + + if (backupSearch.trim()) { + const q = backupSearch.trim().toLowerCase(); + list = list.filter((s) => { + const fields = [ + s.id, + s.ip, + s.dns, + s.extIp, + s.internalIp, + s.country, + s.provider, + ] + .filter(Boolean) + .join(' ') + .toLowerCase(); + return fields.includes(q); + }); + } + + list.sort((a, b) => { + const field = backupSortField || 'ip'; + let av = a[field] ?? ''; + let bv = b[field] ?? ''; + if (typeof av === 'string') av = av.toLowerCase(); + if (typeof bv === 'string') bv = bv.toLowerCase(); + if (av < bv) return backupSortOrder === 'asc' ? -1 : 1; + if (av > bv) return backupSortOrder === 'asc' ? 1 : -1; + return 0; + }); + + return list; + }, [jumphostInputServers, backupSearch, backupSortField, backupSortOrder]); + + const backupTotalPages = useMemo( + () => Math.max(1, Math.ceil(filteredBackupServers.length / backupPageSize)), + [filteredBackupServers.length], + ); + + const paginatedBackupServers = useMemo(() => { + const page = Math.min(Math.max(1, backupPage), backupTotalPages); + const start = (page - 1) * backupPageSize; + return filteredBackupServers.slice(start, start + backupPageSize); + }, [filteredBackupServers, backupPage, backupTotalPages]); + + const handleBackupSort = (field) => { + setBackupSortField((prevField) => { + if (prevField === field) { + setBackupSortOrder((prevOrder) => (prevOrder === 'asc' ? 'desc' : 'asc')); + return prevField; + } + setBackupSortOrder('asc'); + return field; + }); + }; + + const handleBackupSelectAll = () => { + const allIds = filteredBackupServers.map((s) => String(s.id)); + setBackupServerIds(new Set(allIds)); + }; + + const handleBackupDeselectAll = () => { + setBackupServerIds(new Set()); + }; + const fetchServers = async () => { try { setLoadingServers(true); @@ -342,21 +418,61 @@ function MikrotikBackupsManager() { {/* Блок выбора серверов для автобэкапа */}
jumphost. Добавьте их в разделе «Серверы».
| - | Сервер | -IP / DNS | -Страна | -Провайдер | -
|---|---|---|---|---|
| - id && toggleBackupServer(String(id))} - /> - | -{s.dns || s.ip || id} | -
-
- {s.ip}
- {s.dns && s.ip ? ' · ' : ''}
- {s.dns}
-
- |
- {s.country || '-'} | -{s.provider || '-'} | -