refactor(ServerManager): integrate PageHeaderActions for enhanced action handling and UI consistency in server management
Publish Fast Tabler Docker image / build-and-push-fast (push) Successful in 1m57s

This commit is contained in:
2026-02-16 19:39:28 +07:00
parent cf6d8b61a3
commit a6cf9f7130
+47 -24
View File
@@ -34,6 +34,7 @@ import {
ServerBulkActions
} from './components/server/index.js';
import PageHeader from './components/PageHeader.jsx';
import PageHeaderActions from './components/PageHeaderActions.jsx';
const API_URL = '/api';
@@ -550,6 +551,11 @@ function ServerManager() {
}
};
const handleRefreshAll = () => {
fetchServers();
fetchConnections();
};
// === Connections ===
const addConnectionInternal = (draft) => {
if (!draft.from || !draft.to || !draft.tunnelType || !draft.ipA || !draft.ipB) {
@@ -587,36 +593,53 @@ function ServerManager() {
return (
<div className="server-manager-layout">
<PageHeader
title="Управление серверами"
pretitle="Управление"
title="Серверы"
icon={<IconServer size={24} />}
meta={
<span className="text-muted">
Всего серверов: <strong>{servers.length}</strong>
</span>
}
actions={
<div className="btn-list">
<div className="btn-group me-2" role="group">
<>
<PageHeaderActions
loading={loading}
onRefresh={handleRefreshAll}
disableRefresh={loading}
onExport={exportAllLinks}
disableExport={servers.length === 0}
onSave={handleSaveChanges}
disableSave={loading}
/>
<div className="mt-2 d-flex flex-wrap gap-2 justify-content-end">
<div className="btn-group" role="group" aria-label="Переключение режимов">
<button
className={`btn ${activeTab === 'servers' ? 'btn-primary' : 'btn-outline-primary'}`}
onClick={() => setActiveTab('servers')}
type="button"
>
<IconServer size={16} className="me-1" />
Серверы
</button>
<button
className={`btn ${activeTab === 'connections' ? 'btn-primary' : 'btn-outline-primary'}`}
onClick={() => setActiveTab('connections')}
type="button"
>
<IconGitBranch size={16} className="me-1" />
Связи
</button>
</div>
<button
className={`btn ${activeTab === 'servers' ? 'btn-primary' : 'btn-outline-primary'}`}
onClick={() => setActiveTab('servers')}
type="button"
className="btn btn-primary"
onClick={handleOpenAddServerModal}
>
<IconServer size={16} className="me-1" />
Серверы
</button>
<button
className={`btn ${activeTab === 'connections' ? 'btn-primary' : 'btn-outline-primary'}`}
onClick={() => setActiveTab('connections')}
>
<IconGitBranch size={16} className="me-1" />
Связи
<IconPlus size={16} className="me-1" /> Добавить
</button>
</div>
<button type="button" className="btn btn-outline-secondary" onClick={exportAllLinks} disabled={servers.length === 0}>
<IconDownload size={16} className="me-1" /> Экспорт
</button>
<button type="button" className="btn btn-outline-primary" onClick={handleSaveChanges} disabled={loading}>
<IconDatabase size={16} className={loading ? 'spin me-1' : 'me-1'} /> Сохранить
</button>
<button type="button" className="btn btn-primary" onClick={handleOpenAddServerModal}>
<IconPlus size={16} className="me-1" /> Добавить
</button>
</div>
</>
}
/>