Добавить редактор конфигурационных файлов XLX
Этот коммит содержится в:
@@ -5,6 +5,15 @@ const adminResult = document.querySelector('#adminResult');
|
||||
const loadButton = document.querySelector('#loadSettings');
|
||||
const saveButton = document.querySelector('#saveSettings');
|
||||
const applyButton = document.querySelector('#applySettings');
|
||||
const loadConfigFilesButton = document.querySelector('#loadConfigFiles');
|
||||
const saveConfigFileButton = document.querySelector('#saveConfigFile');
|
||||
const reloadConfigFileButton = document.querySelector('#reloadConfigFile');
|
||||
const fileTabs = document.querySelector('#fileTabs');
|
||||
const fileMeta = document.querySelector('#fileMeta');
|
||||
const fileEditor = document.querySelector('#fileEditor');
|
||||
const fileResult = document.querySelector('#fileResult');
|
||||
let configFiles = [];
|
||||
let selectedFileKey = null;
|
||||
|
||||
function token() {
|
||||
return tokenInput.value.trim();
|
||||
@@ -67,6 +76,105 @@ loadButton?.addEventListener('click', loadSettings);
|
||||
saveButton?.addEventListener('click', () => saveSettings(false));
|
||||
applyButton?.addEventListener('click', () => saveSettings(true));
|
||||
|
||||
function selectedFile() {
|
||||
return configFiles.find((file) => file.key === selectedFileKey) || null;
|
||||
}
|
||||
|
||||
function setFileResult(text) {
|
||||
fileResult.textContent = text;
|
||||
}
|
||||
|
||||
function renderFileTabs() {
|
||||
fileTabs.innerHTML = '';
|
||||
for (const file of configFiles) {
|
||||
const button = document.createElement('button');
|
||||
button.type = 'button';
|
||||
button.className = `file-tab${file.key === selectedFileKey ? ' active' : ''}`;
|
||||
button.textContent = file.name;
|
||||
button.addEventListener('click', () => selectFile(file.key));
|
||||
fileTabs.append(button);
|
||||
}
|
||||
}
|
||||
|
||||
function renderFileMeta(file) {
|
||||
if (!file) {
|
||||
fileMeta.innerHTML = '<span>Файл не выбран</span>';
|
||||
return;
|
||||
}
|
||||
|
||||
const writable = file.writable ? 'доступен для записи' : 'нет прав на запись';
|
||||
const exists = file.exists ? 'существует' : 'будет создан при сохранении';
|
||||
fileMeta.innerHTML = `
|
||||
<span>${file.path}</span>
|
||||
<span>${exists}</span>
|
||||
<span>${writable}</span>
|
||||
<span>${file.updated_at || 'без даты'}</span>
|
||||
`;
|
||||
}
|
||||
|
||||
function selectFile(key) {
|
||||
selectedFileKey = key;
|
||||
const file = selectedFile();
|
||||
renderFileTabs();
|
||||
renderFileMeta(file);
|
||||
fileEditor.value = file?.content || '';
|
||||
setFileResult(file ? file.description : '');
|
||||
}
|
||||
|
||||
async function loadConfigFiles() {
|
||||
setFileResult('Загружаем файлы XLX...');
|
||||
const response = await fetch('/api/admin/xlxd/config-files', {
|
||||
headers: { 'X-Admin-Token': token() },
|
||||
});
|
||||
const payload = await response.json();
|
||||
if (!payload.ok) {
|
||||
setFileResult(payload.error || 'Ошибка загрузки файлов');
|
||||
return;
|
||||
}
|
||||
|
||||
configFiles = payload.data;
|
||||
selectedFileKey = selectedFileKey || configFiles[0]?.key || null;
|
||||
renderFileTabs();
|
||||
selectFile(selectedFileKey);
|
||||
}
|
||||
|
||||
async function saveConfigFile() {
|
||||
const file = selectedFile();
|
||||
if (!file) {
|
||||
setFileResult('Сначала выбери файл.');
|
||||
return;
|
||||
}
|
||||
|
||||
setFileResult(`Сохраняем ${file.filename}...`);
|
||||
const response = await fetch('/api/admin/xlxd/config-files', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-Admin-Token': token(),
|
||||
},
|
||||
body: JSON.stringify({ file: file.key, content: fileEditor.value }),
|
||||
});
|
||||
const payload = await response.json();
|
||||
if (!payload.ok) {
|
||||
setFileResult(payload.error || 'Ошибка сохранения файла');
|
||||
return;
|
||||
}
|
||||
|
||||
configFiles = configFiles.map((item) => item.key === payload.data.key ? payload.data : item);
|
||||
selectFile(payload.data.key);
|
||||
setFileResult(`${payload.data.filename} сохранен.`);
|
||||
}
|
||||
|
||||
loadConfigFilesButton?.addEventListener('click', loadConfigFiles);
|
||||
saveConfigFileButton?.addEventListener('click', saveConfigFile);
|
||||
reloadConfigFileButton?.addEventListener('click', () => {
|
||||
const file = selectedFile();
|
||||
if (file) {
|
||||
fileEditor.value = file.content || '';
|
||||
setFileResult('Изменения в редакторе отменены.');
|
||||
}
|
||||
});
|
||||
|
||||
form?.addEventListener('input', () => {
|
||||
const data = formData();
|
||||
const lines = {
|
||||
|
||||
Ссылка в новой задаче
Block a user