feat(NetworkConfigManager, server): update IPSec password handling; return password ID in response and enhance modal behavior for better user experience
Publish Fast Tabler Docker image / build-and-push-fast (push) Successful in 1m19s

This commit is contained in:
2026-01-22 19:17:24 +07:00
parent d223981a93
commit a77ba76ff8
2 changed files with 24 additions and 51 deletions
+1 -1
View File
@@ -137,7 +137,7 @@ async function createIpsecPassword(req, res) {
// Сохраняем в S3
const meta = await writeS3JsonObject(S3_KEY, passwords);
// Возвращаем без расшифрованного пароля
// Возвращаем без расшифрованного пароля, но с ID
res.json({
id: newPassword.id,
name: newPassword.name,
+23 -50
View File
@@ -885,13 +885,16 @@ function NetworkConfigManager() {
}
try {
let savedPasswordId = null;
if (ipsecPasswordModalMode === 'add') {
await api.post('/ipsec-passwords', {
const response = await api.post('/ipsec-passwords', {
name: editingIpsecPassword.name,
password: editingIpsecPassword.password,
description: editingIpsecPassword.description || ''
});
notify.success('IPSec пароль создан');
// Получаем ID созданного пароля из ответа
savedPasswordId = response.data?.id || null;
} else {
await api.put(`/ipsec-passwords/${editingIpsecPassword.id}`, {
name: editingIpsecPassword.name,
@@ -899,10 +902,29 @@ function NetworkConfigManager() {
description: editingIpsecPassword.description || ''
});
notify.success('IPSec пароль обновлён');
savedPasswordId = editingIpsecPassword.id;
}
await fetchIpsecPasswords();
// Закрываем модал создания/редактирования пароля
setIpsecPasswordModalOpen(false);
setEditingIpsecPassword(null);
// Если модал списка паролей открыт, закрываем его
if (ipsecPasswordsListModalOpen) {
setIpsecPasswordsListModalOpen(false);
}
// Если создан новый пароль и открыт шаблон интерфейса, автоматически выбираем его
if (savedPasswordId && interfaceTemplateModalOpen && templateType === 'IPSec') {
setTemplateIpsecPasswordId(savedPasswordId);
}
// Если создан новый пароль и открыт модал интерфейса с типом IPSec, автоматически выбираем его
if (savedPasswordId && interfaceModalOpen && editingInterface?.type === 'IPSec') {
setEditingInterface({ ...editingInterface, ipsecPasswordId: savedPasswordId });
}
} catch (error) {
console.error('Error saving IPSec password:', error);
notify.error('Не удалось сохранить пароль');
@@ -3136,55 +3158,6 @@ function NetworkConfigManager() {
)}
</FormModal>
{/* IPSec Password Modal */}
<FormModal
show={ipsecPasswordModalOpen}
onClose={() => {
setIpsecPasswordModalOpen(false);
setEditingIpsecPassword(null);
}}
onSubmit={handleSaveIpsecPassword}
title={ipsecPasswordModalMode === 'add' ? 'Добавить IPSec пароль' : 'Редактировать IPSec пароль'}
submitLabel={ipsecPasswordModalMode === 'add' ? 'Создать' : 'Сохранить'}
submitIcon={ipsecPasswordModalMode === 'add' ? IconPlus : IconEdit}
>
{editingIpsecPassword && (
<div className="row g-3">
<div className="col-12">
<FormField
label="Название"
name="name"
value={editingIpsecPassword.name}
onChange={(val) => setEditingIpsecPassword({ ...editingIpsecPassword, name: val })}
placeholder="Основной IPSec пароль"
required
/>
</div>
<div className="col-12">
<FormField
label="Пароль"
name="password"
type="password"
value={editingIpsecPassword.password}
onChange={(val) => setEditingIpsecPassword({ ...editingIpsecPassword, password: val })}
placeholder="Введите пароль"
required
/>
<div className="form-text">Пароль будет зашифрован перед сохранением в S3</div>
</div>
<div className="col-12">
<FormField
label="Описание"
name="description"
value={editingIpsecPassword.description || ''}
onChange={(val) => setEditingIpsecPassword({ ...editingIpsecPassword, description: val })}
placeholder="Описание использования пароля"
/>
</div>
</div>
)}
</FormModal>
{/* IPSec Passwords List Modal */}
{ipsecPasswordsListModalOpen && (
<div className="modal show d-block" style={{ backgroundColor: 'rgba(0,0,0,0.5)' }}>