mirror of
https://github.com/avecms/AVE.cms.git
synced 2026-08-26 03:11:51 +00:00
182 lines
7.4 KiB
JavaScript
182 lines
7.4 KiB
JavaScript
(function (window, document) {
|
|
'use strict';
|
|
|
|
var Adminx = window.Adminx || (window.Adminx = {});
|
|
|
|
Adminx.ViewOverrides = {
|
|
root: null,
|
|
form: null,
|
|
field: null,
|
|
clean: '',
|
|
dirty: false,
|
|
|
|
init: function () {
|
|
this.root = document.querySelector('[data-view-overrides]');
|
|
this.form = document.querySelector('[data-view-override-form]');
|
|
this.field = this.form ? this.form.elements.content : null;
|
|
if (!this.root || !this.form || !this.field) { return; }
|
|
this.clean = this.field.value || '';
|
|
this.bind();
|
|
},
|
|
|
|
base: function () { return this.root.getAttribute('data-base') || Adminx.base(); },
|
|
route: function () { return this.root.getAttribute('data-route') || ''; },
|
|
code: function () { return this.form.getAttribute('data-code') || ''; },
|
|
|
|
bind: function () {
|
|
var self = this;
|
|
this.form.addEventListener('submit', function (event) {
|
|
event.preventDefault();
|
|
self.save();
|
|
});
|
|
this.form.addEventListener('input', function () { self.setDirty((self.field.value || '') !== self.clean); });
|
|
this.form.addEventListener('click', function (event) {
|
|
if (event.target.closest('[data-view-override-lint]')) { self.lint(); return; }
|
|
if (event.target.closest('[data-view-override-fullscreen]')) { self.fullscreen(); return; }
|
|
if (event.target.closest('[data-view-override-delete]')) { self.removeOverride(); }
|
|
});
|
|
window.addEventListener('beforeunload', function (event) {
|
|
if (!self.dirty) { return; }
|
|
event.preventDefault();
|
|
event.returnValue = '';
|
|
});
|
|
document.addEventListener('keydown', function (event) {
|
|
if (event.key !== 'Escape' || !self.form.classList.contains('is-fullscreen')) { return; }
|
|
event.preventDefault();
|
|
self.fullscreen(false);
|
|
});
|
|
window.setTimeout(function () { self.bindEditorKeys(); }, 0);
|
|
},
|
|
|
|
request: function (url, data) {
|
|
return Adminx.Ajax.post(url, data).then(function (response) {
|
|
var payload = response.data || {};
|
|
if (!response.ok || !payload.success) {
|
|
var error = new Error(payload.message || 'Не удалось выполнить действие');
|
|
error.payload = payload;
|
|
throw error;
|
|
}
|
|
return payload;
|
|
});
|
|
},
|
|
|
|
sync: function () {
|
|
if (Adminx.CodeEditor) { Adminx.CodeEditor.syncAll(this.form); }
|
|
},
|
|
|
|
save: function () {
|
|
var self = this;
|
|
this.sync();
|
|
Adminx.Loader.show();
|
|
this.request(this.base() + this.route() + '/' + encodeURIComponent(this.code()), new FormData(this.form))
|
|
.then(function (payload) {
|
|
self.clean = self.field.value || '';
|
|
self.setDirty(false);
|
|
Adminx.Toast.show(payload.message || 'Шаблон сохранён', 'success');
|
|
window.setTimeout(function () { window.location.reload(); }, 350);
|
|
})
|
|
.catch(function (error) { self.fail(error); })
|
|
.finally(function () { Adminx.Loader.hide(); });
|
|
},
|
|
|
|
lint: function () {
|
|
var self = this;
|
|
var result = this.form.querySelector('[data-view-override-lint-result]');
|
|
this.sync();
|
|
var data = new FormData();
|
|
data.set('_csrf', this.form.elements._csrf.value);
|
|
data.set('content', this.field.value || '');
|
|
if (result) { result.className = 'field-hint view-override-lint'; result.textContent = 'Проверяем Twig...'; }
|
|
this.request(this.base() + this.route() + '/lint', data)
|
|
.then(function (payload) {
|
|
if (result) { result.classList.add('is-ok'); result.textContent = payload.message || 'Twig-синтаксис корректен'; }
|
|
})
|
|
.catch(function (error) {
|
|
if (result) { result.classList.add('is-error'); result.textContent = error.message; }
|
|
self.fail(error, false);
|
|
});
|
|
},
|
|
|
|
bindEditorKeys: function () {
|
|
var self = this;
|
|
var editor = this.field._adminxCodeMirror;
|
|
if (!editor) { return; }
|
|
var keys = editor.getOption('extraKeys') || {};
|
|
keys.F11 = function () { self.fullscreen(); };
|
|
keys['Cmd-F11'] = function () { self.fullscreen(); };
|
|
keys.Esc = function () { self.fullscreen(false); };
|
|
editor.setOption('extraKeys', keys);
|
|
},
|
|
|
|
fullscreen: function (force) {
|
|
var editor = this.field._adminxCodeMirror;
|
|
if (!editor) { return; }
|
|
var active = this.form.classList.contains('is-fullscreen');
|
|
var next = typeof force === 'boolean' ? force : !active;
|
|
if (next === active) { return; }
|
|
|
|
if (Adminx.CodeEditor) { Adminx.CodeEditor.closeFullscreen(editor); }
|
|
this.form.classList.toggle('is-fullscreen', next);
|
|
document.body.classList.toggle('view-override-fullscreen-open', next);
|
|
this.updateFullscreenButton(next);
|
|
window.setTimeout(function () {
|
|
editor.refresh();
|
|
if (next) { editor.focus(); }
|
|
}, 0);
|
|
},
|
|
|
|
updateFullscreenButton: function (active) {
|
|
var button = this.form.querySelector('[data-view-override-fullscreen]');
|
|
if (!button) { return; }
|
|
var label = active ? 'Вернуться к обычному размеру' : 'На весь экран';
|
|
var icon = button.querySelector('i');
|
|
button.setAttribute('aria-label', label);
|
|
button.setAttribute('data-tooltip', label);
|
|
button.setAttribute('title', label);
|
|
button.setAttribute('aria-pressed', active ? 'true' : 'false');
|
|
if (icon) { icon.className = active ? 'ti ti-arrows-minimize' : 'ti ti-arrows-maximize'; }
|
|
},
|
|
|
|
removeOverride: function () {
|
|
var self = this;
|
|
Adminx.Confirm.open({
|
|
kind: 'warning',
|
|
title: 'Вернуться к резервному шаблону?',
|
|
message: 'Файл активной темы будет удалён. Его последняя версия останется в ревизиях темы, а сайт сразу начнёт использовать резерв компонента.',
|
|
confirmLabel: 'Вернуться к резерву',
|
|
onConfirm: function () {
|
|
var data = new FormData();
|
|
data.set('_csrf', self.form.elements._csrf.value);
|
|
Adminx.Loader.show();
|
|
self.request(self.base() + self.route() + '/' + encodeURIComponent(self.code()) + '/delete', data)
|
|
.then(function (payload) {
|
|
self.setDirty(false);
|
|
Adminx.Toast.show(payload.message || 'Переопределение удалено', 'success');
|
|
window.setTimeout(function () { window.location.reload(); }, 350);
|
|
})
|
|
.catch(function (error) { self.fail(error); })
|
|
.finally(function () { Adminx.Loader.hide(); });
|
|
}
|
|
});
|
|
},
|
|
|
|
setDirty: function (dirty) {
|
|
this.dirty = !!dirty;
|
|
var state = this.form.querySelector('[data-view-override-save-state]');
|
|
if (!state) { return; }
|
|
state.classList.toggle('is-dirty', this.dirty);
|
|
state.textContent = this.dirty ? 'Есть несохранённые изменения' : '';
|
|
},
|
|
|
|
fail: function (error, toast) {
|
|
if (toast !== false) { Adminx.Toast.show(error && error.message ? error.message : 'Не удалось выполнить действие', 'error'); }
|
|
}
|
|
};
|
|
|
|
if (document.readyState === 'loading') {
|
|
document.addEventListener('DOMContentLoaded', function () { Adminx.ViewOverrides.init(); });
|
|
} else {
|
|
Adminx.ViewOverrides.init();
|
|
}
|
|
})(window, document);
|