From 4ce3bf4a9ffb170317629b21379ab822eae0c1cd Mon Sep 17 00:00:00 2001 From: shats Date: Mon, 16 Feb 2026 18:52:37 +0700 Subject: [PATCH] refactor(IPRangesManager): improve code readability and structure by standardizing JSX formatting and enhancing layout consistency --- frontend/src/IPRangesManager.jsx | 718 ++++++++++++------------------- 1 file changed, 277 insertions(+), 441 deletions(-) diff --git a/frontend/src/IPRangesManager.jsx b/frontend/src/IPRangesManager.jsx index cddede1..8cec35c 100644 --- a/frontend/src/IPRangesManager.jsx +++ b/frontend/src/IPRangesManager.jsx @@ -771,25 +771,27 @@ function IPRangesManager() { {error && ( setError('')} /> )} - + {success && (
-
- {success} -
+
{success}
- +
)} } - actions={( + actions={ { if (!filterCommunity) { setError('Выберите community в фильтре для очистки'); return; } setClearCommunitiesOpen(true); }} + onClearCommunities={() => { + if (!filterCommunity) { + setError('Выберите community в фильтре для очистки'); + return; + } + setClearCommunitiesOpen(true); + }} disableClearCommunities={items.length === 0 || !filterCommunity} onSave={handleSaveChanges} disableSave={loading} @@ -810,18 +818,23 @@ function IPRangesManager() { onOnlineUpdate={() => setWsOpen(true)} onBackgroundUpdate={async () => { try { - const res = await fetch('/api/update-bgp/background', { method: 'POST' }); + const res = await fetch('/api/update-bgp/background', { + method: 'POST', + }); const data = await res.json().catch(() => ({})); if (!res.ok || data.ok === false) { throw new Error(data?.message || `HTTP ${res.status}`); } notifyMutationSuccess('Фоновое обновление запущено', data); } catch (e) { - window.notify?.error('Не удалось запустить фоновое обновление', String(e)); + window.notify?.error( + 'Не удалось запустить фоновое обновление', + String(e), + ); } }} /> - )} + } /> -
-
- {/* BulkActionsBar */} - 0 ? () => { - if (confirm(`Удалить ${selectedItems.size} записей?`)) { - handleBulkDelete(); - } - } : null} - onExport={selectedItems.size > 0 ? handleBulkExport : null} - /> - -
-
-
-
-
-
- - Список - {filtered.length} -
-
- Всего записей: {filtered.length} -
-
+
+
+
+
+
+
+ + Список + + {filtered.length} +
-
-
- { - setSearchTerm(filters.searchTerm || ''); - setFilterCommunity(filters.filterCommunity || ''); - setSortField(filters.sortField || 'ipRange'); - setSortOrder(filters.sortOrder || 'asc'); - setCurrentPage(1); - }} - /> -
- {/* Фильтр по community */} - - {/* Поиск */} -
- - - - { setSearchTerm(e.target.value); setCurrentPage(1); }} - aria-label="Поиск IP-диапазона" - /> -
-
-
- - - - +
+ Всего записей: {filtered.length}
-
- {/* Таблица на лёгкой карточной подложке */} - {loading ? ( - - ) : paginatedItems.length === 0 ? ( - - Импорт} - secondaryAction={} +
+
+
+ +
+ + + + { + setSearchTerm(e.target.value); + setCurrentPage(1); + }} + aria-label="Поиск IP-диапазона" /> - - ) : ( -
- - - - - - - - - - - {paginatedItems.map((item, idx) => ( - - - - - - - ))} - -
- 0 && paginatedItems.every(i => selectedItems.has(i.ipRange))} - onChange={(e) => { - if (e.target.checked) { - selectAll(); - } else { - deselectAll(); - } - }} - title="Выбрать все на странице" - /> - handleSort('ipRange')}> -
- - IP-диапазон - {sortField === 'ipRange' && ( - - {sortOrder === 'asc' ? : } - - )} -
-
handleSort('community')}> -
- - Community - {sortField === 'community' && ( - - {sortOrder === 'asc' ? : } - - )} -
-
Действия
- toggleSelectItem(item.ipRange)} - onClick={(e) => e.stopPropagation()} - /> - -
- - {item.ipRange} - - - -
-
{renderCommunityBadge(item.community)} -
- - - - - - -
-
- )} -
-
- +
+
+ +
+ +
+ {loading ? ( + + ) : paginatedItems.length === 0 ? ( + + + Импорт + + } + secondaryAction={ + + } + /> + + ) : ( +
+ + + + + + + + + + + {paginatedItems.map((item) => ( + + + + + + + ))} + +
+ 0 && + paginatedItems.every((i) => selectedItems.has(i.ipRange)) + } + onChange={(e) => { + if (e.target.checked) { + selectAll(); + } else { + deselectAll(); + } + }} + title="Выбрать все на странице" + /> + handleSort('ipRange')} + > +
+ + IP-диапазон + {sortField === 'ipRange' && ( + + {sortOrder === 'asc' ? ( + + ) : ( + + )} + + )} +
+
handleSort('community')} + > +
+ + Community + {sortField === 'community' && ( + + {sortOrder === 'asc' ? ( + + ) : ( + + )} + + )} +
+
Действия
+ toggleSelectItem(item.ipRange)} + onClick={(e) => e.stopPropagation()} + /> + +
+ + {item.ipRange} + + + +
+
{renderCommunityBadge(item.community)} +
+ + + + + + +
+
+
+ )} +
+ +
+ +
setShowDeleteModal(false)} /> + setConfirmSaveOpen(false)} /> + setImportOpen(false)} - sampleHeader={['ipRange','community']} + sampleHeader={['ipRange', 'community']} placeholder={'192.168.1.0/24 65000:100'} /> - {/* Модальное окно редактирования community */} +

- IP-диапазон: {itemBeingEdited.ipRange} + IP-диапазон:{' '} + {itemBeingEdited.ipRange}

@@ -1108,7 +1146,9 @@ function IPRangesManager() { onChange={setEditingValue} communities={communities} onKeyDown={handleEditKeyDown} - className={`form-control${isValidCommunity(editingValue) ? '' : ' is-invalid'}`} + className={`form-control${ + isValidCommunity(editingValue) ? '' : ' is-invalid' + }`} useShortValue={true} /> {!isValidCommunity(editingValue) && ( @@ -1120,240 +1160,36 @@ function IPRangesManager() { )} + setHistoryOpen(false)} onRolledBack={() => fetchItems()} /> + setWsOpen(false)} /> + { setItems(prev => prev.filter(i => i != null && i.community !== filterCommunity)); setClearCommunitiesOpen(false); }} + onConfirm={() => { + setItems((prev) => + prev.filter((i) => i != null && i.community !== filterCommunity), + ); + setClearCommunitiesOpen(false); + }} onCancel={() => setClearCommunitiesOpen(false)} /> - {/* Analyze Settings Modal */} - {analyzeOpen && ( -
-
-
- -
-

Анализ IP-диапазонов

-
-
-
-
- - -
Анализ выполняется в рамках одного выбранного community.
-
-
-
- -
-
- от -
-
- { - const v = Math.max(0, Math.min(32, Number(e.target.value))); - setAnalyzeFilters(f => ({ ...f, minMask: Math.min(v, f.maxMask) })); - }} /> -
-
- до -
-
- { - const v = Math.max(0, Math.min(32, Number(e.target.value))); - setAnalyzeFilters(f => ({ ...f, maxMask: Math.max(v, f.minMask) })); - }} /> -
-
-
Учитываются только CIDR внутри выбранного диапазона масок.
-
-
- -
- - - - -
-
Определение типа по первому IP в CIDR.
-
-
- - -
Например: 157.240.12.0/23, 157.240.15.0/24, 157.240.16.0/23 → 157.240.0.0/16
-
-
-
-
-
- - -
-
-
-
- )} - {/* Analyze Confirm */} - { setAnalyzeConfirmOpen(false); runAnalysis(); }} - onCancel={() => setAnalyzeConfirmOpen(false)} - /> - {/* Analysis Results Modal */} - {analysisResultsOpen && ( -
-
-
- -
-

Результаты анализа

-
-
- {!analysisPreview ? ( -
Нет данных по заданным фильтрам
- ) : ( - <> -
- Community: {renderCommunityBadge(analysisPreview.community)} -
-
-
-
-
Было (всего в community)
-
{analysisPreview.totalBefore}
-
-
-
-
-
Обработано (по фильтрам)
-
{analysisPreview.processedBefore}
-
-
-
-
-
Станет (после суммаризации)
-
{analysisPreview.totalAfter}
-
-
-
-
-
-
-

Исходные (учтенные по фильтрам) — {analysisPreview.processedBefore}

-
- {analysisPreview.beforeCidrs.length === 0 ? ( -
- ) : ( -
    - {analysisPreview.beforeCidrs.map(c => (
  • {c}
  • ))} -
- )} -
-
-
-
-
-

После суммаризации — {analysisPreview.processedAfter}

-
- {analysisPreview.afterCidrs.length === 0 ? ( -
- ) : ( -
    - {analysisPreview.afterCidrs.map(c => (
  • {c}
  • ))} -
- )} -
-
-
-
-
Неизменные (вне фильтров): {analysisPreview.unchangedCount}
- - )} -
-
- - -
-
-
-
- )} - {/* Overwrite confirm */} - setOverwriteConfirmOpen(false)} - /> - {/* Diff Modal */} - {showDiff && ( -
-
-
- -

Изменения

-
-
-
Добавлено
{diff.added.length}
-
Удалено
{diff.removed.length}
-
Изменено
{diff.changed.length}
-
-
-
- -
-
-
-
- )} - {/* datalist больше не нужен, т.к. используем кастомный автокомплит */}
); } -export default IPRangesManager; \ No newline at end of file +export default IPRangesManager; \ No newline at end of file