Files
ave-cms/adminx/modules/Settings/assets/settings.js
T
2026-07-27 12:58:44 +03:00

699 lines
32 KiB
JavaScript

/**
* JS раздела «Настройки»: tabs, conditional fields, ajax-save и запуск
* и операций обслуживания нативной схемы.
*/
(function (window, document) {
'use strict';
var Adminx = window.Adminx || (window.Adminx = {});
Adminx.Settings = {
root: null,
form: null,
dirty: false,
layoutDrag: null,
sectionDrag: null,
init: function () {
this.root = document.querySelector('[data-settings-page]');
this.form = document.getElementById('settingsForm');
if (!this.root) { return; }
var self = this;
document.addEventListener('click', function (e) {
var tab = e.target.closest('[data-settings-tab]');
if (tab) { self.openTab(tab.getAttribute('data-settings-tab')); }
if (e.target.closest('[data-settings-reset]')) { window.location.reload(); }
if (e.target.closest('[data-pagination-new]')) { self.fillPaginationNew(); }
var paginationEdit = e.target.closest('[data-pagination-edit]');
if (paginationEdit) { self.fillPaginationEdit(paginationEdit.closest('[data-pagination-row]')); }
var paginationDelete = e.target.closest('[data-pagination-delete]');
if (paginationDelete) { self.deletePagination(paginationDelete.closest('[data-pagination-row]')); }
var cacheClear = e.target.closest('[data-cache-clear]');
if (cacheClear) { self.clearCache(cacheClear.getAttribute('data-cache-clear')); }
var maintenanceClear = e.target.closest('[data-maintenance-clear]');
if (maintenanceClear) { self.clearMaintenance(maintenanceClear.getAttribute('data-maintenance-clear')); }
var systemFile = e.target.closest('[data-system-file-edit]');
if (systemFile) { self.openSystemFile(systemFile.getAttribute('data-system-file-edit')); }
if (e.target.closest('[data-constant-new]')) { self.fillConstantNew(); }
var constantEditorTab = e.target.closest('[data-constant-editor-tab]');
if (constantEditorTab) { self.openConstantEditorTab(constantEditorTab.getAttribute('data-constant-editor-tab')); }
var constantBool = e.target.closest('[data-constant-bool]');
if (constantBool) { self.setConstantBool(constantBool.getAttribute('data-constant-bool')); }
var constantEdit = e.target.closest('[data-constant-edit]');
if (constantEdit) { self.fillConstantEdit(constantEdit.closest('[data-constant-row]')); }
var constantDelete = e.target.closest('[data-constant-delete]');
if (constantDelete) { self.deleteConstant(constantDelete.closest('[data-constant-row]')); }
if (e.target.closest('[data-thumbnail-preset-scan]')) { self.scanThumbnailPresets(); }
var layoutMove = e.target.closest('[data-layout-move]');
if (layoutMove) { self.moveLayout(layoutMove); }
var sectionMove = e.target.closest('[data-section-order-move]');
if (sectionMove) { self.moveSection(sectionMove); }
});
if (this.form) {
this.form.addEventListener('input', function () { self.markDirty(); self.applyDependencies(); });
this.form.addEventListener('change', function (e) {
self.markDirty(); self.applyDependencies(); self.updateSwitchLabels();
if (e.target.matches('[data-section-order-visible]')) {
e.target.closest('[data-section-order-item]').classList.toggle('is-disabled', !e.target.checked);
self.syncSectionOrder(e.target.closest('[data-section-order]'));
}
});
this.form.addEventListener('submit', function (e) { e.preventDefault(); self.save(); });
this.form.addEventListener('dragstart', function (e) { self.sectionDragStart(e); });
this.form.addEventListener('dragover', function (e) { self.sectionDragOver(e); });
this.form.addEventListener('drop', function (e) { if (self.sectionDrag) { e.preventDefault(); } });
this.form.addEventListener('dragend', function () { self.sectionDragEnd(); });
}
var paginationForm = document.getElementById('paginationForm');
if (paginationForm) {
paginationForm.addEventListener('submit', function (e) {
e.preventDefault();
self.savePagination(paginationForm);
});
}
var constantForm = document.getElementById('constantForm');
if (constantForm) {
constantForm.addEventListener('submit', function (e) {
e.preventDefault();
self.syncConstantValue();
self.saveConstant(constantForm);
});
constantForm.addEventListener('input', function (e) {
if (e.target.matches('[data-constant-input]')) { self.syncConstantValue(e.target); }
if (e.target.matches('[data-constant-options]')) { self.updateConstantEditor(); }
});
constantForm.addEventListener('change', function (e) {
if (e.target.matches('[data-constant-type]')) { self.updateConstantEditor(); }
if (e.target.matches('[data-constant-input]')) { self.syncConstantValue(e.target); }
});
}
var systemFileForm = document.querySelector('[data-system-file-form]');
if (systemFileForm) {
systemFileForm.addEventListener('submit', function (e) {
e.preventDefault();
self.saveSystemFile(systemFileForm);
});
}
var interfaceForm = document.querySelector('[data-interface-layout-form]');
if (interfaceForm) {
interfaceForm.addEventListener('submit', function (e) { e.preventDefault(); self.saveInterface(interfaceForm); });
interfaceForm.addEventListener('change', function (e) {
if (e.target.matches('[data-layout-visible]')) {
e.target.closest('[data-layout-item]').classList.toggle('is-disabled', !e.target.checked);
}
});
interfaceForm.addEventListener('dragstart', function (e) { self.layoutDragStart(e); });
interfaceForm.addEventListener('dragover', function (e) { self.layoutDragOver(e); });
interfaceForm.addEventListener('drop', function (e) { if (self.layoutDrag) { e.preventDefault(); } });
interfaceForm.addEventListener('dragend', function () { self.layoutDragEnd(); });
}
if (this.form) { this.applyDependencies(); this.updateSwitchLabels(); }
},
base: function () {
return (this.root ? this.root.getAttribute('data-base') : '') || Adminx.base();
},
layoutDragStart: function (event) {
var handle = event.target.closest('[data-layout-handle]');
var row = handle ? handle.closest('[data-layout-item]') : null;
if (!row || handle.getAttribute('draggable') !== 'true') { event.preventDefault(); return; }
this.layoutDrag = row;
row.classList.add('is-dragging');
if (event.dataTransfer) {
event.dataTransfer.effectAllowed = 'move';
event.dataTransfer.setData('text/plain', row.getAttribute('data-code') || '');
}
},
layoutDragOver: function (event) {
if (!this.layoutDrag) { return; }
var target = event.target.closest('[data-layout-item]');
var list = event.target.closest('[data-layout-list]');
if (!target || !list || target === this.layoutDrag || this.layoutDrag.parentNode !== list) { return; }
event.preventDefault();
var rect = target.getBoundingClientRect();
list.insertBefore(this.layoutDrag, event.clientY < rect.top + rect.height / 2 ? target : target.nextSibling);
},
layoutDragEnd: function () {
if (this.layoutDrag) { this.layoutDrag.classList.remove('is-dragging'); }
this.layoutDrag = null;
},
moveLayout: function (button) {
var row = button.closest('[data-layout-item]');
if (!row || button.disabled) { return; }
if (button.getAttribute('data-layout-move') === 'up' && row.previousElementSibling) {
row.parentNode.insertBefore(row, row.previousElementSibling);
} else if (button.getAttribute('data-layout-move') === 'down' && row.nextElementSibling) {
row.parentNode.insertBefore(row.nextElementSibling, row);
}
},
sectionDragStart: function (event) {
var handle = event.target.closest('[data-section-order-handle]');
var row = handle ? handle.closest('[data-section-order-item]') : null;
if (!row || row.getAttribute('draggable') !== 'true') { event.preventDefault(); return; }
this.sectionDrag = row;
row.classList.add('is-dragging');
if (event.dataTransfer) {
event.dataTransfer.effectAllowed = 'move';
event.dataTransfer.setData('text/plain', row.getAttribute('data-code') || '');
}
},
sectionDragOver: function (event) {
if (!this.sectionDrag) { return; }
var target = event.target.closest('[data-section-order-item]');
var list = event.target.closest('[data-section-order]');
if (!target || !list || target === this.sectionDrag || this.sectionDrag.parentNode !== list) { return; }
event.preventDefault();
var rect = target.getBoundingClientRect();
list.insertBefore(this.sectionDrag, event.clientY < rect.top + rect.height / 2 ? target : target.nextSibling);
this.syncSectionOrder(list);
},
sectionDragEnd: function () {
if (this.sectionDrag) {
var list = this.sectionDrag.closest('[data-section-order]');
this.sectionDrag.classList.remove('is-dragging');
this.syncSectionOrder(list);
}
this.sectionDrag = null;
},
moveSection: function (button) {
var row = button.closest('[data-section-order-item]');
if (!row || button.disabled) { return; }
if (button.getAttribute('data-section-order-move') === 'up' && row.previousElementSibling) {
row.parentNode.insertBefore(row, row.previousElementSibling);
} else if (button.getAttribute('data-section-order-move') === 'down' && row.nextElementSibling) {
row.parentNode.insertBefore(row.nextElementSibling, row);
}
this.syncSectionOrder(row.parentNode);
this.markDirty();
},
syncSectionOrder: function (list) {
if (!list) { return; }
var input = list.parentNode.querySelector('[data-section-order-value]');
if (!input) { return; }
input.value = JSON.stringify(Array.prototype.map.call(list.querySelectorAll('[data-section-order-item]'), function (row) {
var toggle = row.querySelector('[data-section-order-visible]');
return { code: row.getAttribute('data-code') || '', visible: !!(toggle && toggle.checked) };
}));
},
layoutValues: function (scope) {
var list = document.querySelector('[data-layout-list="' + scope + '"]');
if (!list) { return []; }
return Array.prototype.map.call(list.querySelectorAll('[data-layout-item]'), function (row) {
var toggle = row.querySelector('[data-layout-visible]');
return { code: row.getAttribute('data-code') || '', visible: !!(toggle && toggle.checked) };
});
},
saveInterface: function (form) {
var data = new FormData(form);
data.set('navigation', JSON.stringify(this.layoutValues('navigation')));
data.set('dashboard', JSON.stringify(this.layoutValues('dashboard')));
Adminx.Loader.show();
Adminx.Ajax.post(this.base() + '/settings/interface', data).then(function (payload) {
Adminx.Loader.hide();
var result = payload.data || {};
if (!result.success) {
Adminx.Toast.show(result.message || 'Не удалось сохранить интерфейс', 'error');
return;
}
Adminx.Toast.show(result.message || 'Интерфейс обновлен', 'success');
window.setTimeout(function () { window.location.reload(); }, 250);
}).catch(function () {
Adminx.Loader.hide();
Adminx.Toast.show('Ошибка сети', 'error');
});
},
openTab: function (code) {
document.querySelectorAll('[data-settings-tab]').forEach(function (tab) {
tab.setAttribute('aria-selected', tab.getAttribute('data-settings-tab') === code ? 'true' : 'false');
});
document.querySelectorAll('[data-settings-panel]').forEach(function (panel) {
panel.classList.toggle('active', panel.getAttribute('data-settings-panel') === code);
});
},
openInitialTab: function () {
var hash = (window.location.hash || '').replace(/^#/, '');
if (hash && document.querySelector('[data-settings-tab="' + hash + '"]')) {
this.openTab(hash);
}
},
markDirty: function () {
this.dirty = true;
var bar = document.getElementById('settingsSavebar');
if (bar) { bar.hidden = false; }
},
clearErrors: function () {
this.form.querySelectorAll('[data-error]').forEach(function (s) { s.textContent = ''; });
this.form.querySelectorAll('.input, .select, .textarea').forEach(function (el) { el.classList.remove('is-invalid'); });
},
save: function () {
var self = this;
this.clearErrors();
Adminx.Loader.show();
Adminx.Ajax.post(this.base() + '/settings', new FormData(this.form)).then(function (payload) {
Adminx.Loader.hide();
var d = payload.data || {};
if (d.success) {
self.dirty = false;
var bar = document.getElementById('settingsSavebar');
if (bar) { bar.hidden = true; }
Adminx.Toast.show(d.message || 'Настройки сохранены', 'success');
return;
}
var errors = d.errors || {};
Object.keys(errors).forEach(function (field) {
var span = self.form.querySelector('[data-error="' + field + '"]');
if (span) { span.textContent = errors[field]; }
var input = self.form.querySelector('[name="' + field + '"]');
if (input) { input.classList.add('is-invalid'); }
});
Adminx.Toast.show(d.message || 'Не удалось сохранить', 'error');
}).catch(function () {
Adminx.Loader.hide();
Adminx.Toast.show('Ошибка сети', 'error');
});
},
paginationForm: function () {
return document.getElementById('paginationForm');
},
fillPaginationNew: function () {
var form = this.paginationForm();
if (!form) { return; }
form.reset();
form.querySelector('[name="id"]').value = '';
document.getElementById('paginationDrawerTitle').textContent = 'Новый шаблон пагинации';
},
fillPaginationEdit: function (row) {
var form = this.paginationForm();
if (!form || !row) { return; }
var id = row.getAttribute('data-id');
this.fillPaginationNew();
document.getElementById('paginationDrawerTitle').textContent = 'Изменение: ' + row.getAttribute('data-name');
Adminx.Loader.show();
Adminx.Ajax.request(this.base() + '/settings/paginations/' + id).then(function (payload) {
Adminx.Loader.hide();
var d = payload.data || {};
if (!d.success) {
Adminx.Toast.show(d.message || 'Шаблон не найден', 'error');
return;
}
var data = d.data || {};
Object.keys(data).forEach(function (key) {
var el = form.querySelector('[name="' + key + '"]');
if (el) { el.value = data[key] == null ? '' : data[key]; }
});
}).catch(function () {
Adminx.Loader.hide();
Adminx.Toast.show('Ошибка сети', 'error');
});
},
savePagination: function (form) {
var id = (form.querySelector('[name="id"]').value || '').trim();
var url = this.base() + '/settings/paginations' + (id ? '/' + id : '');
Adminx.Loader.show();
Adminx.Ajax.post(url, new FormData(form)).then(function (payload) {
Adminx.Loader.hide();
var d = payload.data || {};
if (d.success) {
Adminx.Ajax.handle(payload);
if (!d.redirect) { window.location.reload(); }
} else {
Adminx.Toast.show(d.message || 'Не удалось сохранить шаблон', 'error');
}
}).catch(function () {
Adminx.Loader.hide();
Adminx.Toast.show('Ошибка сети', 'error');
});
},
deletePagination: function (row) {
if (!row) { return; }
var self = this;
Adminx.Confirm.open({
kind: 'error',
title: 'Удалить шаблон пагинации?',
message: '«' + row.getAttribute('data-name') + '» будет удалён.',
confirmLabel: 'Удалить',
confirmClass: 'btn-danger',
onConfirm: function () {
Adminx.Loader.show();
Adminx.Ajax.post(self.base() + '/settings/paginations/' + row.getAttribute('data-id') + '/delete').then(function (payload) {
Adminx.Loader.hide();
var d = payload.data || {};
if (d.success) {
row.remove();
Adminx.Toast.show(d.message || 'Шаблон удалён', 'success');
} else {
Adminx.Toast.show(d.message || 'Не удалось удалить', 'error');
}
}).catch(function () {
Adminx.Loader.hide();
Adminx.Toast.show('Ошибка сети', 'error');
});
}
});
},
clearCache: function (source) {
var self = this;
Adminx.Confirm.open({
kind: 'warning',
title: 'Очистить кеш?',
message: 'Будет очищен источник «' + source + '».',
confirmLabel: 'Очистить',
onConfirm: function () {
Adminx.Loader.show();
Adminx.Ajax.post(self.base() + '/settings/cache/' + encodeURIComponent(source) + '/clear').then(function (payload) {
Adminx.Loader.hide();
var d = payload.data || {};
if (d.success) {
var row = document.querySelector('[data-cache-row="' + source + '"]');
if (row && d.data && d.data.size) {
var cell = row.querySelector('[data-cache-size]');
if (cell) { cell.textContent = d.data.size; }
}
Adminx.Toast.show(d.message || 'Кеш очищен', 'success');
} else {
Adminx.Toast.show(d.message || 'Не удалось очистить кеш', 'error');
}
}).catch(function () {
Adminx.Loader.hide();
Adminx.Toast.show('Ошибка сети', 'error');
});
}
});
},
clearMaintenance: function (target) {
var self = this;
var label = target === 'revisions' ? 'все ревизии документов' : 'всю подневную статистику просмотров';
Adminx.Confirm.open({
kind: 'danger',
title: 'Очистить служебные данные?',
message: 'Будут удалены ' + label + '. Действие необратимо.',
confirmLabel: 'Очистить',
onConfirm: function () {
Adminx.Loader.show();
Adminx.Ajax.post(self.base() + '/settings/maintenance/' + encodeURIComponent(target) + '/clear').then(function (payload) {
Adminx.Loader.hide();
var d = payload.data || {};
Adminx.Toast.show(d.message || (d.success ? 'Данные очищены' : 'Не удалось очистить данные'), d.success ? 'success' : 'error');
if (d.success) { window.location.reload(); }
}).catch(function () { Adminx.Loader.hide(); Adminx.Toast.show('Ошибка сети', 'error'); });
}
});
},
openSystemFile: function (code) {
var form = document.querySelector('[data-system-file-form]');
if (!form) { return; }
Adminx.Loader.show();
Adminx.Ajax.request(this.base() + '/settings/files/' + encodeURIComponent(code)).then(function (payload) {
Adminx.Loader.hide();
var d = payload.data || {};
if (!d.success) { Adminx.Toast.show(d.message || 'Файл не найден', 'error'); return; }
var file = d.data || {};
form.elements.code.value = file.code || code;
var textarea = form.elements.content;
textarea.value = file.content || '';
textarea.setAttribute('data-code-mode', file.mode || 'text/plain');
if (textarea._adminxCodeMirror) {
textarea._adminxCodeMirror.setOption('mode', file.mode || 'text/plain');
textarea._adminxCodeMirror.setValue(file.content || '');
textarea._adminxCodeMirror.setSize('100%', '100%');
setTimeout(function () { textarea._adminxCodeMirror.refresh(); }, 80);
}
var title = document.getElementById('systemFileDrawerTitle');
var path = document.querySelector('[data-system-file-path]');
if (title) { title.textContent = file.label || 'Системный файл'; }
if (path) { path.textContent = file.path || ''; }
}).catch(function () { Adminx.Loader.hide(); Adminx.Toast.show('Ошибка сети', 'error'); });
},
saveSystemFile: function (form) {
var code = form.elements.code.value || '';
var textarea = form.elements.content;
if (textarea._adminxCodeMirror) { textarea._adminxCodeMirror.save(); }
Adminx.Loader.show();
Adminx.Ajax.post(this.base() + '/settings/files/' + encodeURIComponent(code), new FormData(form)).then(function (payload) {
Adminx.Loader.hide();
var d = payload.data || {};
Adminx.Toast.show(d.message || (d.success ? 'Файл сохранён' : 'Не удалось сохранить файл'), d.success ? 'success' : 'error');
}).catch(function () { Adminx.Loader.hide(); Adminx.Toast.show('Ошибка сети', 'error'); });
},
constantForm: function () {
return document.getElementById('constantForm');
},
fillConstantNew: function () {
var form = this.constantForm();
if (!form) { return; }
form.reset();
form.querySelector('[name="name"]').readOnly = false;
form.querySelector('[name="is_system"]').value = '0';
form.querySelector('[name="sort_order"]').value = '100';
form.querySelector('[data-constant-value]').value = '';
var presetResult = form.querySelector('[data-thumbnail-preset-result]');
if (presetResult) { presetResult.hidden = true; presetResult.textContent = ''; }
this.openConstantEditorTab('value');
this.updateConstantEditor();
document.getElementById('constantDrawerTitle').textContent = 'Новая константа';
},
fillConstantEdit: function (row) {
var form = this.constantForm();
if (!form || !row) { return; }
var self = this;
this.fillConstantNew();
var name = row.getAttribute('data-name');
document.getElementById('constantDrawerTitle').textContent = 'Изменение: ' + name;
Adminx.Loader.show();
Adminx.Ajax.request(this.base() + '/settings/constants/' + encodeURIComponent(name)).then(function (payload) {
Adminx.Loader.hide();
var d = payload.data || {};
if (!d.success) {
Adminx.Toast.show(d.message || 'Константа не найдена', 'error');
return;
}
var data = d.data || {};
Object.keys(data).forEach(function (key) {
var el = form.querySelector('[name="' + key + '"]');
if (el) { el.value = data[key] == null ? '' : data[key]; }
});
form.querySelector('[name="name"]').readOnly = true;
if (Array.isArray(data.options_array)) {
form.querySelector('[name="options"]').value = data.options_array.join('\n');
}
self.updateConstantEditor();
self.openConstantEditorTab('value');
}).catch(function () {
Adminx.Loader.hide();
Adminx.Toast.show('Ошибка сети', 'error');
});
},
saveConstant: function (form) {
Adminx.Loader.show();
Adminx.Ajax.post(this.base() + '/settings/constants', new FormData(form)).then(function (payload) {
Adminx.Loader.hide();
var d = payload.data || {};
if (d.success) {
Adminx.Ajax.handle(payload);
if (!d.redirect) { window.location.reload(); }
} else {
Adminx.Toast.show(d.message || 'Не удалось сохранить константу', 'error');
}
}).catch(function () {
Adminx.Loader.hide();
Adminx.Toast.show('Ошибка сети', 'error');
});
},
openConstantEditorTab: function (code) {
var form = this.constantForm(); if (!form) { return; }
form.querySelectorAll('[data-constant-editor-tab]').forEach(function (tab) {
var active = tab.getAttribute('data-constant-editor-tab') === code;
tab.classList.toggle('is-active', active); tab.setAttribute('aria-selected', active ? 'true' : 'false');
});
form.querySelectorAll('[data-constant-editor-panel]').forEach(function (panel) {
panel.hidden = panel.getAttribute('data-constant-editor-panel') !== code;
});
},
constantOptions: function () {
var form = this.constantForm(); if (!form) { return []; }
var raw = form.querySelector('[data-constant-options]').value || '', seen = {};
return raw.split(/[\r\n,]+/).map(function (item) { return item.trim(); }).filter(function (item) {
if (!item || seen[item]) { return false; } seen[item] = true; return true;
});
},
updateConstantEditor: function () {
var form = this.constantForm(); if (!form) { return; }
var type = form.querySelector('[data-constant-type]').value || 'string';
var value = form.querySelector('[data-constant-value]').value || '';
var name = (form.querySelector('[name="name"]').value || '').trim().toUpperCase();
var thumbnailTools = form.querySelector('[data-thumbnail-preset-tools]');
if (thumbnailTools) { thumbnailTools.hidden = name !== 'THUMBNAIL_SIZES'; }
form.querySelectorAll('[data-constant-control]').forEach(function (control) { control.hidden = control.getAttribute('data-constant-control') !== type; });
var optionsField = form.querySelector('[data-constant-options-field]');
optionsField.hidden = type !== 'select' && type !== 'tags';
var hints = { string: 'Обычная текстовая строка.', path: 'Путь относительно корня проекта или абсолютный путь.', int: 'Только целое число.', bool: 'Выберите одно из двух состояний.', select: 'Выберите один из настроенных вариантов.', tags: 'Введите значения по одному на строку.' };
form.querySelector('[data-constant-value-hint]').textContent = hints[type] || '';
if (type === 'bool') {
this.setConstantBool(value === '1' || value === 'true' ? '1' : '0'); return;
}
if (type === 'select') {
var select = form.querySelector('[data-constant-input="select"]'), options = this.constantOptions();
select.innerHTML = '';
options.forEach(function (option) { var node = document.createElement('option'); node.value = option; node.textContent = option; select.appendChild(node); });
if (options.indexOf(value) < 0 && value !== '') { var current = document.createElement('option'); current.value = value; current.textContent = value + ' (текущее)'; select.insertBefore(current, select.firstChild); }
select.value = value; select.disabled = options.length === 0 && value === '';
form.querySelector('[data-constant-select-empty]').hidden = !select.disabled;
return;
}
var input = form.querySelector('[data-constant-input="' + type + '"]');
if (input) {
input.value = type === 'tags' && name === 'THUMBNAIL_SIZES'
? value.split(/[\s,;]+/).filter(Boolean).join('\n')
: value;
}
},
scanThumbnailPresets: function () {
var form = this.constantForm();
if (!form) { return; }
var self = this;
var button = form.querySelector('[data-thumbnail-preset-scan]');
if (button) { button.disabled = true; }
Adminx.Loader.show();
Adminx.Ajax.post(this.base() + '/settings/constants/thumbnail-sizes/scan').then(function (payload) {
Adminx.Loader.hide();
if (button) { button.disabled = false; }
var response = payload.data || {};
if (!response.success) {
Adminx.Toast.show(response.message || 'Не удалось собрать размеры', 'error');
return;
}
var data = response.data || {};
var sizes = Array.isArray(data.sizes) ? data.sizes : [];
form.querySelector('[data-constant-type]').value = 'tags';
form.querySelector('[data-constant-value]').value = sizes.join(',');
self.updateConstantEditor();
var input = form.querySelector('[data-constant-input="tags"]');
if (input) { input.value = sizes.join('\n'); }
self.syncConstantValue(input);
var result = form.querySelector('[data-thumbnail-preset-result]');
if (result) {
result.hidden = false;
result.textContent = 'Найдено: ' + sizes.length + ' · файлов: ' + (data.files_scanned || 0)
+ ' · таблиц БД: ' + (data.database_tables_scanned || 0)
+ (Array.isArray(data.warnings) && data.warnings.length ? ' · предупреждений: ' + data.warnings.length : '');
}
Adminx.Toast.show(response.message || 'Размеры собраны', 'success');
}).catch(function () {
Adminx.Loader.hide();
if (button) { button.disabled = false; }
Adminx.Toast.show('Ошибка сети', 'error');
});
},
setConstantBool: function (value, sync) {
var form = this.constantForm(); if (!form) { return; }
value = String(value) === '1' ? '1' : '0';
form.querySelectorAll('[data-constant-bool]').forEach(function (button) { button.setAttribute('aria-pressed', button.getAttribute('data-constant-bool') === value ? 'true' : 'false'); });
if (sync !== false) { form.querySelector('[data-constant-value]').value = value; }
},
syncConstantValue: function (control) {
var form = this.constantForm(); if (!form) { return; }
var type = form.querySelector('[data-constant-type]').value || 'string';
if (type === 'bool') { return; }
control = control || form.querySelector('[data-constant-input="' + type + '"]');
if (control) { form.querySelector('[data-constant-value]').value = control.value; }
},
deleteConstant: function (row) {
if (!row) { return; }
var self = this;
var name = row.getAttribute('data-name');
Adminx.Confirm.open({
kind: 'error',
title: 'Удалить константу?',
message: name + ' будет удалена из управляемой БД. PHP-файл изменится только после сборки.',
confirmLabel: 'Удалить',
confirmClass: 'btn-danger',
onConfirm: function () {
Adminx.Loader.show();
Adminx.Ajax.post(self.base() + '/settings/constants/' + encodeURIComponent(name) + '/delete').then(function (payload) {
Adminx.Loader.hide();
var d = payload.data || {};
if (d.success) {
row.remove();
Adminx.Toast.show(d.message || 'Константа удалена', 'success');
} else {
Adminx.Toast.show(d.message || 'Не удалось удалить', 'error');
}
}).catch(function () {
Adminx.Loader.hide();
Adminx.Toast.show('Ошибка сети', 'error');
});
}
});
},
applyDependencies: function () {
var self = this;
this.form.querySelectorAll('[data-depends-key]').forEach(function (field) {
var key = field.getAttribute('data-depends-key');
var value = field.getAttribute('data-depends-value');
var control = self.form.querySelector('[name="' + key + '"]');
var visible = control && control.value === value;
field.hidden = !visible;
});
},
updateSwitchLabels: function () {
this.form.querySelectorAll('.settings-switch-line').forEach(function (line) {
var input = line.querySelector('input[type="checkbox"]');
var label = line.querySelector('span b');
if (input && label) { label.textContent = input.checked ? 'Включено' : 'Выключено'; }
});
}
};
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', function () { Adminx.Settings.init(); });
} else {
Adminx.Settings.init();
}
})(window, document);