feat(NetworkConfigManager, PreviewConfigModal): improve clipboard functionality for MikroTik code; add title and description props to preview modal
Publish Fast Tabler Docker image / build-and-push-fast (push) Successful in 1m37s
Publish Fast Tabler Docker image / build-and-push-fast (push) Successful in 1m37s
This commit is contained in:
@@ -552,7 +552,31 @@ function NetworkConfigManager() {
|
|||||||
|
|
||||||
// === Копирование кода MikroTik ===
|
// === Копирование кода MikroTik ===
|
||||||
const handleCopyMikrotikCode = async () => {
|
const handleCopyMikrotikCode = async () => {
|
||||||
await copyToClipboard(generatedMikrotikCode);
|
try {
|
||||||
|
if (navigator.clipboard && navigator.clipboard.writeText) {
|
||||||
|
await navigator.clipboard.writeText(generatedMikrotikCode);
|
||||||
|
notify.success('Код скопирован в буфер обмена!');
|
||||||
|
} else {
|
||||||
|
// Fallback для старых браузеров
|
||||||
|
const textArea = document.createElement('textarea');
|
||||||
|
textArea.value = generatedMikrotikCode;
|
||||||
|
textArea.style.position = 'fixed';
|
||||||
|
textArea.style.left = '-999999px';
|
||||||
|
document.body.appendChild(textArea);
|
||||||
|
textArea.focus();
|
||||||
|
textArea.select();
|
||||||
|
try {
|
||||||
|
document.execCommand('copy');
|
||||||
|
notify.success('Код скопирован в буфер обмена!');
|
||||||
|
} catch (err) {
|
||||||
|
notify.error('Не удалось скопировать код');
|
||||||
|
}
|
||||||
|
document.body.removeChild(textArea);
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Error copying to clipboard:', err);
|
||||||
|
notify.error('Не удалось скопировать код');
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// === Получение цвета провайдера ===
|
// === Получение цвета провайдера ===
|
||||||
@@ -1621,6 +1645,8 @@ function NetworkConfigManager() {
|
|||||||
show={mikrotikCodeModalOpen}
|
show={mikrotikCodeModalOpen}
|
||||||
config={generatedMikrotikCode}
|
config={generatedMikrotikCode}
|
||||||
mode="advanced"
|
mode="advanced"
|
||||||
|
title="Предварительный просмотр конфигурации"
|
||||||
|
description="Конфигурация MikroTik RouterOS для рекурсивных маршрутов"
|
||||||
onClose={() => setMikrotikCodeModalOpen(false)}
|
onClose={() => setMikrotikCodeModalOpen(false)}
|
||||||
onCopy={handleCopyMikrotikCode}
|
onCopy={handleCopyMikrotikCode}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
import { IconFilter, IconCopy } from '@tabler/icons-react';
|
import { IconFilter, IconCopy, IconEye } from '@tabler/icons-react';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Модальное окно предварительного просмотра конфигурации
|
* Модальное окно предварительного просмотра конфигурации
|
||||||
*/
|
*/
|
||||||
function PreviewConfigModal({ show, config, mode, onClose, onCopy }) {
|
function PreviewConfigModal({ show, config, mode, onClose, onCopy, title, description }) {
|
||||||
if (!show) return null;
|
if (!show) return null;
|
||||||
|
|
||||||
const getModalTitle = () => {
|
const getModalTitle = () => {
|
||||||
|
if (title) return title;
|
||||||
if (mode === 'simple') {
|
if (mode === 'simple') {
|
||||||
return 'Предварительный просмотр конфигурации MikroTik (упрощённый режим)';
|
return 'Предварительный просмотр конфигурации MikroTik (упрощённый режим)';
|
||||||
} else if (mode === 'advanced') {
|
} else if (mode === 'advanced') {
|
||||||
@@ -25,7 +26,16 @@ function PreviewConfigModal({ show, config, mode, onClose, onCopy }) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const getConfigInfo = () => {
|
const getConfigInfo = () => {
|
||||||
if (config.includes('// Сначала выберите сервер') || config.includes('// Нет фильтров для генерации конфигурации')) {
|
if (description) {
|
||||||
|
return (
|
||||||
|
<div className="alert alert-info mb-3">
|
||||||
|
<IconEye className="me-2" />
|
||||||
|
{description}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config.includes('// Сначала выберите сервер') || config.includes('// Нет фильтров для генерации конфигурации') || config.includes('// Нет рекурсивных gateway')) {
|
||||||
return <div className="alert alert-warning mb-3">Нет данных для генерации конфигурации</div>;
|
return <div className="alert alert-warning mb-3">Нет данных для генерации конфигурации</div>;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -42,9 +52,18 @@ function PreviewConfigModal({ show, config, mode, onClose, onCopy }) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return (
|
||||||
|
<div className="alert alert-info mb-3">
|
||||||
|
<IconEye className="me-2" />
|
||||||
|
Конфигурация MikroTik RouterOS для применения фильтров
|
||||||
|
</div>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const isConfigEmpty = config.includes('// Сначала выберите сервер') ||
|
||||||
|
config.includes('// Нет фильтров для генерации конфигурации') ||
|
||||||
|
config.includes('// Нет рекурсивных gateway');
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="modal show d-block" style={{ backgroundColor: 'rgba(0,0,0,0.5)' }}>
|
<div className="modal show d-block" style={{ backgroundColor: 'rgba(0,0,0,0.5)' }}>
|
||||||
<div className="modal-dialog modal-lg">
|
<div className="modal-dialog modal-lg">
|
||||||
@@ -58,26 +77,33 @@ function PreviewConfigModal({ show, config, mode, onClose, onCopy }) {
|
|||||||
</div>
|
</div>
|
||||||
<div className="modal-body">
|
<div className="modal-body">
|
||||||
{getConfigInfo()}
|
{getConfigInfo()}
|
||||||
<div className="mb-3">
|
<pre className="bg-dark text-white p-3 rounded" style={{ maxHeight: '500px', overflow: 'auto' }}>
|
||||||
<div className="btn-list">
|
|
||||||
<button
|
|
||||||
className="btn btn-outline-primary"
|
|
||||||
onClick={onCopy}
|
|
||||||
disabled={config.includes('// Сначала выберите сервер') || config.includes('// Нет фильтров для генерации конфигурации')}
|
|
||||||
>
|
|
||||||
<IconCopy className="me-2" />
|
|
||||||
Копировать в буфер обмена
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<pre className="bg-dark text-light p-3 rounded" style={{ maxHeight: '400px', overflow: 'auto' }}>
|
|
||||||
<code>{config}</code>
|
<code>{config}</code>
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
|
<div className="mt-3 text-muted small">
|
||||||
|
<p className="mb-1"><strong>Инструкция по применению:</strong></p>
|
||||||
|
<ol className="mb-0">
|
||||||
|
<li>Скопируйте конфигурацию в буфер обмена</li>
|
||||||
|
<li>Подключитесь к MikroTik через SSH или Winbox</li>
|
||||||
|
<li>Вставьте конфигурацию в терминал</li>
|
||||||
|
<li>Проверьте применение командой: <code>/routing filter print</code> или <code>/ip route print</code></li>
|
||||||
|
</ol>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="modal-footer">
|
<div className="modal-footer">
|
||||||
<button type="button" className="btn btn-secondary" onClick={onClose}>
|
<button type="button" className="btn btn-secondary" onClick={onClose}>
|
||||||
Закрыть
|
Закрыть
|
||||||
</button>
|
</button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="btn btn-primary"
|
||||||
|
onClick={onCopy}
|
||||||
|
disabled={isConfigEmpty}
|
||||||
|
>
|
||||||
|
<IconCopy className="me-2" />
|
||||||
|
Копировать в буфер
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user