Initial commit

This commit is contained in:
Ivan Petrov
2025-12-24 19:19:01 +03:00
commit a7097c6178
19493 changed files with 94306 additions and 0 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,431 @@
var blockClose = false;
$(document).ready(function() {
loadWingman();
});
const loadWingman = () => {
consoleReport("Запускаю процессы.");
dataEditFormControl();
dataCreateFormControl();
navScrollbarControl();
editorControl();
floatingBlockCheck();
multifieldSortableControl();
hideMultifield();
searchControl();
tabsControl();
floatingBlockControl();
favoritesControl();
consoleReport("Процессы запущены.");
}
$(window).on('beforeunload', function(){
if (blockClose) return 'Are you sure you want to leave?';
});
const favoritesControl = () => {
consoleReport("Подключаем работу избранного.");
$(".favorite_button").each(function (index, el) {
$(el).unbind();
$(el).on("click", function (e) {
if($(el).hasClass("active")) removeFavoritePage(el)
else addFavoritePage(el);
});
});
}
const removeFavoritePage = (el) => {
const data = {
link: window.location.href,
}
$.ajax({
url: "/wingman/favorite_remove_page/",
method: "POST",
dataType: 'html',
data,
success: function(data){
$(el).removeClass("active");
}
});
}
const addFavoritePage = (el) => {
$(el).addClass("active");
const data = {
link: window.location.href,
name: $(el).attr("data-link-name")
}
$.ajax({
url: "/wingman/favorite_add_page/",
method: "POST",
dataType: 'html',
data,
success: function(data){}
});
}
var active_tabs = {};
const tabsControl = () => {
consoleReport("Перехватываю работу табов.");
$(".b_tabs").each(function () {
const tabs_wrapper = $(this);
const tabs_group = tabs_wrapper.attr("data-tabs-group");
tabs_wrapper.find(".b_tab[data-tabs-group='" + tabs_group + "']").each(function (index) {
const tab = $(this);
tab.unbind();
tab.on("click", function (){
consoleReport("Переключаю таб.");
activeTab(tabs_group, index);
active_tabs[tabs_group] = index;
})
});
if(active_tabs[tabs_group]) activeTab(tabs_group, active_tabs[tabs_group])
else activeTab(tabs_group, 0)
});
}
const activeTab = (tabs_group, index) => {
const tabs = $(".b_tab[data-tabs-group='" + tabs_group + "']");
const tabs_content = $(".b_tab_content[data-tabs-group='" + tabs_group + "']");
tabs.each(function () {
$(this).removeClass("active");
});
tabs_content.each(function () {
$(this).addClass("hide");
});
tabs.eq(index).addClass("active");
tabs_content.eq(index).removeClass("hide");
}
const searchControl = () => {
const search_input = $(".b-global-search > input");
search_input.unbind();
search_input.on("input", function (){
const search = $(this).val();
const page = $(".b-global-search").attr("data-page");
if(search.length > 0 && search.length < 3) return;
const data = { page, search }
$.ajax({
url: "/wingman/load_submenu_search/",
method: "POST",
dataType: 'html',
data,
success: function(data){
$(".admin-subnav > .nav-item__sub").replaceWith(data);
}
});
})
}
const dataEditFormControl = () => {
consoleReport("Перехватываю работу форм редактирования.");
$(".datatype-edit-wrapper .admin-data-form").each(function( index, el ) {
$(el).find("input").each(function( index, el ) {
$(el).unbind();
$(el).on("change", function (e) {
changeStatusBar("Не сохранено", "warning")
consoleReport("Блокирую выход.");
blockClose = true;
});
})
$(el).find("button[type=submit]").unbind();
$(el).find("button[type=submit]").click(function() {
$("button[type=submit]", $(this).parents("form")).removeAttr("clicked");
$(this).attr("clicked", "true");
});
$(this).unbind();
$(this).on("submit", function (e) {
e.preventDefault();
var form = $(el);
var formData = new FormData();
form.find('input, select, textarea').each(function() {
var field = $(this);
var fieldName = field.attr('name');
var fieldValue = field.val();
if(field.attr('type') === "checkbox" && !field.is(':checked')) return;
if(field.attr('type') === "radio" && !field.is(':checked')) return;
if(field.attr('type') === "file") {
if(!this.files.length) return;
const file = this.files[0];
formData.append(fieldName, file);
} else formData.append(fieldName, fieldValue);
});
const currentURL = getCurrentURL();
blockAllButtons(form.find("button"), "Кнопки");
blockAllButtons(form.find("input"), "Поля");
consoleReport("Отправляю форму.");
changeStatusBar("Сохраняем...", "warning")
formData.append("b_wingman", "true");
var clickedButton = $("button[type=submit][clicked=true]");
if(clickedButton && clickedButton.attr("name") && clickedButton.attr("value"))
formData.append(clickedButton.attr("name"), clickedButton.attr("value"));
$.ajax({
url: currentURL,
method: form.attr('method'),
processData: false,
contentType: false,
dataType: 'html',
data: formData,
success: function(data){
$(".datatype-edit-wrapper").replaceWith(data);
loadWingman();
changeStatusBar("Сохранено", "success")
consoleReport("Форма отправлена.");
unblockAllButtons(form.find("button"), "Кнопки");
unblockAllButtons(form.find("input"), "Поля");
blockClose = false;
}
});
});
});
}
const dataCreateFormControl = () => {
consoleReport("Перехватываю работу форм создания.");
$(".datatype-create-wrapper .admin-data-form").each(function( index, el ) {
$(el).find("input").each(function( index, el ) {
$(el).unbind();
$(el).on("change", function (e) {
changeStatusBar("Не сохранено", "warning")
consoleReport("Блокирую выход.");
blockClose = true;
});
})
$(el).find("button[type=submit]").unbind();
$(el).find("button[type=submit]").click(function() {
$("button[type=submit]", $(this).parents("form")).removeAttr("clicked");
$(this).attr("clicked", "true");
});
$(this).unbind();
$(this).on("submit", function (e) {
e.preventDefault();
var form = $(el);
var formData = new FormData();
form.find('input, select, textarea').each(function() {
var field = $(this);
var fieldName = field.attr('name');
var fieldValue = field.val();
if(field.attr('type') === "checkbox" && !field.is(':checked')) return;
if(field.attr('type') === "radio" && !field.is(':checked')) return;
if(field.attr('type') === "file") {
if(!this.files.length) return;
const file = this.files[0];
formData.append(fieldName, file);
} else formData.append(fieldName, fieldValue);
});
const currentURL = getCurrentURL();
blockAllButtons(form.find("button"), "Кнопки");
blockAllButtons(form.find("input"), "Поля");
changeStatusBar("Сохраняем...", "warning")
formData.append("b_wingman", "true");
var clickedButton = $("button[type=submit][clicked=true]");
if(clickedButton && clickedButton.attr("name") && clickedButton.attr("value"))
formData.append(clickedButton.attr("name"), clickedButton.attr("value"));
consoleReport("Отправляю форму.");
$.ajax({
url: currentURL,
method: form.attr('method'),
processData: false,
contentType: false,
data: formData,
success: function(data){
blockClose = false;
const json = JSON.parse(data);
window.location.replace(json.redirect);
}
});
});
});
}
const multifieldSortableControl = () => {
consoleReport("Возможности для сортировки списков.");
$(".bive-multifield__wrapper").each(function( index, el ) {
consoleReport("Нашел список, будем его сортировать.");
$(el).sortable({
handle: ".input-number", // Используем блок с классом "input-number" в качестве ручки для перетаскивания
update: function(event, ui) {
const row = $(ui.item[0]);
multifieldCalc(el);
changeStatusBar("Не сохранено", "warning")
consoleReport("Блокирую выход.");
blockClose = true;
row.addClass("active");
setTimeout(() => row.removeClass("active"), 3000)
}
});
});
}
const multifieldCalc = (el) => {
const multifield = $(el);
const level = multifield.attr("data-level");
multifield.children(".bive-multifield__row").each(function(index, el) {
const row = $(el);
const realNum = index;
row.children(".input-number").text(index);
row.find("input, select, textarea").each(function(index, el) {
const input = $(el)
const name = input.attr("name");
const newName = level + name.replace(level, "").replace(/\[\d+\]/, `[${realNum}]`);
input.attr("name", newName)
})
})
}
let multifieldOpen = {};
const hideMultifield = () => {
$(".bive-multifield").each(function( index, el ) {
consoleReport("Скрываю списки");
const rowsCount = $(el).children(".bive-multifield__wrapper").children(".bive-multifield__row").length;
if(!multifieldOpen[index] && rowsCount > 1) {
$(el).addClass("hide");
multifieldOpen[index] = false;
} else multifieldOpen[index] = true;
$(el).children(".bive-multifield__buttons").children(".bive-multifield__hide").unbind();
$(el).children(".bive-multifield__buttons").children(".bive-multifield__hide").on("click", function () {
$(el).addClass("hide");
multifieldOpen[index] = false;
})
$('<span>', {
class: 'bive-multifield__show',
click: function() {
$(el).removeClass("hide");
multifieldOpen[index] = true;
}
}).text('Содержимое списка скрыто. Нажмите чтобы окрыть.').appendTo(el);
});
}
const editorControl = () => {
$(".bive-textarea__content").each((index, el) => {
let editor = CKEDITOR.replace( $(el).attr("id") );
editor.on( 'change', function( evt ) {
$(el).html(evt.editor.getData());
});
})
}
const changeStatusBar = (status, name = null) => {
consoleReport("Изменяю статусбар.");
const statusBar = $(".admin-floating-status");
statusBar.removeClass("success");
statusBar.removeClass("cancel");
statusBar.removeClass("warning");
statusBar.text(status);
if (name) statusBar.addClass(name);
}
const navScrollbarControl = () => {
consoleReport("Скроллим меню относительно прокрутки страницы.");
let lastScrollTop = $(window).scrollTop();
$(window).on('scroll', function() {
let currentScrollTop = $(window).scrollTop();
let delta = currentScrollTop - lastScrollTop; // разница с прошлым значением
// двигаем меню на эту разницу
$('.admin-subnav').scrollTop(function(_, currentMenuScroll) {
return currentMenuScroll + delta;
});
lastScrollTop = currentScrollTop;
});
}
const floatingBlockControl = () => {
floatingBlockCheck();
consoleReport("Активирую плаващий блок.");
$(window).scroll(function() {
floatingBlockCheck();
});
}
const floatingBlockCheck = () => {
// consoleReport("Просчитываю плаващий блок.");
//
// var block = $('.admin-floating-block');
// var wrapper = $('.admin-floating-wrapper');
// if(!block.length || !wrapper.length) return;
//
// var windowTop = $(window).scrollTop();
// var windowHeight = $(window).height();
// var blockTop = wrapper.offset().top;
// var blockHeight = wrapper.outerHeight();
// var documentHeight = $(document).height();
//
// if (blockTop + blockHeight < windowTop || blockTop - 100 > windowTop + windowHeight) {
// // Блок вышел за пределы видимости
// block.css('position', 'fixed');
// block.css('bottom', '0');
// block.addClass("active");
// } else {
// block.removeClass("active");
// // Блок видим в окне просмотра
// block.css('position', 'static');
// }
//
// if (blockTop + blockHeight > documentHeight) {
// // Блок достиг нижней границы документа
// block.removeClass("active");
// block.css('position', 'static');
// block.css('top', documentHeight - blockHeight);
// }
}
const blockAllButtons = (selector, name) => {
consoleReport(`Блокирую ${name}.`);
selector.each(function() {
$(this).attr("disabled", true);
$(this).attr("readonly", true);
});
}
const unblockAllButtons = (selector, name) => {
consoleReport(`Разблокирую ${name}.`);
selector.each(function() {
$(this).attr("disabled", false);
$(this).attr("readonly", false);
});
}
const consoleReport = (message) => {
console.log("[Wingman] - " + message);
}
const getCurrentURL = () => {
return window.location.href;
}