refactor(DomainsNewManager): integrate LastSaved component and streamline button placement for improved UI consistency and user experience
Publish Fast Tabler Docker image / build-and-push-fast (push) Successful in 1m57s

This commit is contained in:
2026-02-16 17:18:24 +07:00
parent 571ec06522
commit cfcb44d5f0
+41 -38
View File
@@ -47,6 +47,7 @@ import FormField from './components/FormField.jsx';
import Tooltip from './components/Tooltip.jsx'; import Tooltip from './components/Tooltip.jsx';
import Pagination from './components/Pagination.jsx'; import Pagination from './components/Pagination.jsx';
import AddItemModal from './components/AddItemModal.jsx'; import AddItemModal from './components/AddItemModal.jsx';
import LastSaved from './components/LastSaved.jsx';
import { useToast } from './components/ToastContainer.jsx'; import { useToast } from './components/ToastContainer.jsx';
const API_URL = '/api'; const API_URL = '/api';
@@ -514,47 +515,39 @@ function DomainsNewManager() {
<PageHeader <PageHeader
title="Домены" title="Домены"
meta={<LastSaved timestamp={lastModified} variant="compact" />}
actions={( actions={(
<div className="d-flex align-items-center gap-2"> <PageHeaderActions
<button loading={loading}
className="btn btn-primary" onPreview={handlePreviewDiff}
onClick={() => setAddModalOpen(true)} disablePreview={loading || items.length === 0}
title="Добавить новый домен" onRefresh={fetchItems}
> disableRefresh={loading}
<IconPlus className="me-1" size={18} /> onImport={handleImport}
Добавить onExport={handleExport}
</button> disableExport={items.length === 0}
<PageHeaderActions onClear={clearInvalid}
loading={loading} disableClear={items.length === 0}
onPreview={handlePreviewDiff} onClearCommunities={() => { if (!filterCommunity) { setError('Выберите community в фильтре для очистки'); return; } setClearCommunitiesOpen(true); }}
disablePreview={loading || items.length === 0} disableClearCommunities={items.length === 0 || !filterCommunity}
onRefresh={fetchItems} onSave={handleSaveChanges}
disableRefresh={loading} disableSave={loading}
onImport={handleImport} onHistory={() => setHistoryOpen(true)}
onExport={handleExport} lastModified={lastModified}
disableExport={items.length === 0} onOnlineUpdate={() => setWsOpen(true)}
onClear={clearInvalid} onBackgroundUpdate={async () => {
disableClear={items.length === 0} try {
onClearCommunities={() => { if (!filterCommunity) { setError('Выберите community в фильтре для очистки'); return; } setClearCommunitiesOpen(true); }} const res = await fetch('/api/update-bgp/background', { method: 'POST' });
disableClearCommunities={items.length === 0 || !filterCommunity} const data = await res.json().catch(() => ({}));
onSave={handleSaveChanges} if (!res.ok || data.ok === false) {
disableSave={loading} throw new Error(data?.message || `HTTP ${res.status}`);
onHistory={() => setHistoryOpen(true)}
onOnlineUpdate={() => setWsOpen(true)}
onBackgroundUpdate={async () => {
try {
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));
} }
}} notifyMutationSuccess('Фоновое обновление запущено', data);
} catch (e) {
window.notify?.error('Не удалось запустить фоновое обновление', String(e));
}
}}
/> />
</div>
)} )}
/> />
@@ -669,6 +662,16 @@ function DomainsNewManager() {
</div> </div>
</div> </div>
</div> </div>
<div className="col-auto">
<button
className="btn btn-primary"
onClick={() => setAddModalOpen(true)}
title="Добавить новый домен"
>
<IconPlus className="me-1" size={18} />
Добавить
</button>
</div>
</div> </div>
</div> </div>
</div> </div>