feat: enhance various components with useCallback for performance optimization and improve chunk size warning limit in Vite config
Frontend CI / frontend (push) Has been cancelled
Publish Docker image / build-and-push (push) Failing after 56s

This commit is contained in:
2026-03-16 00:07:25 +07:00
parent 972f3ab5ca
commit 50a7edd50f
25 changed files with 360 additions and 364 deletions
+21 -27
View File
@@ -1,4 +1,4 @@
import { useState, useEffect, useRef } from 'react';
import { useState, useEffect, useRef, useCallback } from 'react';
import api from './lib/api.js';
import CommunityAutocompleteInput from './components/CommunityAutocompleteInput.jsx';
import CommunityBadge from './components/CommunityBadge.jsx';
@@ -121,7 +121,7 @@ function DomainsNewManager() {
const [wsOpen, setWsOpen] = useState(false);
const [wsUrl, setWsUrl] = useState('');
const fetchItems = async (abortSignal) => {
const fetchItems = useCallback(async (abortSignal) => {
setLoading(true);
const opts = abortSignal ? { signal: abortSignal } : {};
try {
@@ -143,7 +143,7 @@ function DomainsNewManager() {
} finally {
setLoading(false);
}
};
}, []);
useEffect(() => {
if (!didInit.current) {
@@ -152,7 +152,7 @@ function DomainsNewManager() {
fetchItems(controller.signal);
return () => controller.abort();
}
}, []);
}, [fetchItems]);
const handleAddItem = (item) => {
// Если item передан (из модалки), используем его, иначе из state (старый способ)
@@ -273,27 +273,7 @@ function DomainsNewManager() {
setShowDiff(true);
};
const handleSaveChanges = async () => {
// подготовим diff и спросим подтверждение только при массовых изменениях (>10)
const valid = items.filter(i => i != null && isValidDomain(i.domain) && isValidCommunity(i.community))
.map(i => ({ domain: i.domain.trim().toLowerCase(), community: String(i.community).trim() }));
const unique = deduplicate(valid);
const diffData = computeDiff(originalItems, unique);
setDiff(diffData);
// Умное подтверждение: показываем модалку только при массовых изменениях
const totalChanges = (diffData.added?.length || 0) + (diffData.removed?.length || 0) + (diffData.changed?.length || 0);
if (totalChanges > 10) {
// Массовое изменение - требуется подтверждение
setConfirmSaveOpen(true);
} else {
// Малое изменение - сохраняем сразу
performSave();
}
};
const performSave = async () => {
const performSave = useCallback(async () => {
setConfirmSaveOpen(false);
setLoading(true);
try {
@@ -336,7 +316,21 @@ function DomainsNewManager() {
} finally {
setLoading(false);
}
};
}, [items, originalItems, etag, fetchItems]);
const handleSaveChanges = useCallback(async () => {
const valid = items.filter(i => i != null && isValidDomain(i.domain) && isValidCommunity(i.community))
.map(i => ({ domain: i.domain.trim().toLowerCase(), community: String(i.community).trim() }));
const unique = deduplicate(valid);
const diffData = computeDiff(originalItems, unique);
setDiff(diffData);
const totalChanges = (diffData.added?.length || 0) + (diffData.removed?.length || 0) + (diffData.changed?.length || 0);
if (totalChanges > 10) {
setConfirmSaveOpen(true);
} else {
performSave();
}
}, [items, originalItems, performSave]);
// Drag&Drop импорт
const _onDropImport = async (e) => {
@@ -456,7 +450,7 @@ function DomainsNewManager() {
};
window.addEventListener('keydown', onKey);
return () => window.removeEventListener('keydown', onKey);
}, [loading, items, originalItems, etag, sortField, sortOrder, filterCommunity]);
}, [loading, handleSaveChanges]);
const handleEditKeyDown = (e) => {
if (e.key === 'Enter') {