feat: Implement simple filters management in FilterManager with API integration for fetching, adding, and deleting filters, enhancing user experience and functionality
Publish Fast Tabler Docker image / build-and-push-fast (push) Successful in 5m46s

This commit is contained in:
2025-07-14 15:13:32 +07:00
parent e6a9c17aa0
commit c62666bd42
2 changed files with 188 additions and 16 deletions
+120 -16
View File
@@ -65,6 +65,7 @@ function FilterManager() {
useEffect(() => {
fetchServers();
fetchSimpleFilters();
}, []);
// Загружаем фильтры при выборе сервера
@@ -102,6 +103,19 @@ function FilterManager() {
}
};
const fetchSimpleFilters = async () => {
setSimpleLoading(true);
try {
const response = await axios.get(`${API_URL}/simple-filters`);
setSimpleFilters(response.data);
} catch (error) {
console.error('Error fetching simple filters:', error);
setSimpleFilters([]);
} finally {
setSimpleLoading(false);
}
};
const handleAddServer = async () => {
if (!newServer.name.trim()) {
setError('Имя сервера обязательно для заполнения.');
@@ -581,22 +595,54 @@ function FilterManager() {
};
// Функции для работы с фильтрами в упрощённом режиме
const handleSimpleAddFilter = () => {
const handleSimpleAddFilter = async () => {
if (!simpleAddFilter.community.trim() || !simpleAddFilter.gateway.trim()) {
setSimpleError('Поля Community и Gateway должны быть заполнены.');
return;
}
setSimpleFilters([...simpleFilters, { ...simpleAddFilter }]);
const updatedFilters = [...simpleFilters, { ...simpleAddFilter }];
setSimpleFilters(updatedFilters);
setSimpleAddFilter({ community: '', gateway: '', description: '' });
setSimpleError('');
// Сохраняем фильтры
try {
await axios.post(`${API_URL}/simple-filters`, { filters: updatedFilters });
setSimpleSuccess('Фильтр успешно добавлен!');
setTimeout(() => setSimpleSuccess(''), 3000);
} catch (error) {
console.error('Error saving simple filters:', error);
setSimpleError('Не удалось сохранить фильтр.');
}
};
const handleSimpleDeleteFilter = (filter) => {
setSimpleFilters(simpleFilters.filter(f => f !== filter));
const handleSimpleDeleteFilter = async (filter) => {
const updatedFilters = simpleFilters.filter(f => f !== filter);
setSimpleFilters(updatedFilters);
// Сохраняем фильтры
try {
await axios.post(`${API_URL}/simple-filters`, { filters: updatedFilters });
setSimpleSuccess('Фильтр успешно удален!');
setTimeout(() => setSimpleSuccess(''), 3000);
} catch (error) {
console.error('Error saving simple filters:', error);
setSimpleError('Не удалось удалить фильтр.');
}
};
const handleSimpleEditFilter = (index, field, value) => {
const handleSimpleEditFilter = async (index, field, value) => {
const updated = [...simpleFilters];
updated[index][field] = value;
setSimpleFilters(updated);
// Сохраняем фильтры
try {
await axios.post(`${API_URL}/simple-filters`, { filters: updated });
} catch (error) {
console.error('Error saving simple filters:', error);
setSimpleError('Не удалось сохранить изменения.');
}
};
return (
@@ -1181,9 +1227,21 @@ function FilterManager() {
{mode === 'simple' ? (
<div className="card mb-4">
<div className="card-header">
<h3 className="card-title">
<IconFilter className="me-2" /> Фильтры (упрощённый режим)
</h3>
<div className="row align-items-center">
<div className="col">
<h3 className="card-title">
<IconFilter className="me-2" /> Фильтры (упрощённый режим)
</h3>
<div className="text-muted">
Управление фильтрами community/gateway для всех серверов
</div>
</div>
<div className="col-auto">
<div className="badge bg-blue-lt text-blue">
{simpleFilters.length} фильтров
</div>
</div>
</div>
</div>
<div className="card-body">
{simpleError && (
@@ -1203,7 +1261,16 @@ function FilterManager() {
</tr>
</thead>
<tbody>
{simpleFilters.length === 0 ? (
{simpleLoading ? (
<tr>
<td colSpan={4} className="text-center text-muted py-4">
<div className="spinner-border spinner-border-sm me-2" role="status">
<span className="visually-hidden">Загрузка...</span>
</div>
Загрузка фильтров...
</td>
</tr>
) : simpleFilters.length === 0 ? (
<tr><td colSpan={4} className="text-center text-muted">Нет фильтров</td></tr>
) : (
simpleFilters.map((filter, idx) => (
@@ -1275,13 +1342,50 @@ function FilterManager() {
</button>
</div>
</div>
<button
className="btn btn-outline-success"
onClick={handleDeploySimpleFiltersToAll}
disabled={simpleFilters.length === 0 || simpleLoading}
>
<IconRocket className="me-2" /> Раскатать фильтры на все серверы
</button>
<div className="btn-list">
<button
className="btn btn-outline-success"
onClick={handleDeploySimpleFiltersToAll}
disabled={simpleFilters.length === 0 || simpleLoading}
>
<IconRocket className="me-2" /> Раскатать фильтры на все серверы
</button>
<button
className="btn btn-outline-primary"
onClick={async () => {
try {
await axios.post(`${API_URL}/simple-filters`, { filters: simpleFilters });
setSimpleSuccess('Фильтры успешно сохранены!');
setTimeout(() => setSimpleSuccess(''), 3000);
} catch (error) {
setSimpleError('Ошибка при сохранении фильтров: ' + (error.response?.data || error.message));
}
}}
disabled={simpleLoading}
>
<IconDeviceFloppy className="me-2" /> Сохранить фильтры
</button>
{simpleFilters.length > 0 && (
<button
className="btn btn-outline-danger"
onClick={async () => {
if (window.confirm('Вы уверены, что хотите очистить все фильтры?')) {
try {
await axios.post(`${API_URL}/simple-filters`, { filters: [] });
setSimpleFilters([]);
setSimpleSuccess('Все фильтры очищены!');
setTimeout(() => setSimpleSuccess(''), 3000);
} catch (error) {
setSimpleError('Ошибка при очистке фильтров: ' + (error.response?.data || error.message));
}
}
}}
disabled={simpleLoading}
>
<IconTrash className="me-2" /> Очистить все
</button>
)}
</div>
</div>
</div>
) : (