Большое обновление GUI интерфейс
Большое обновление GUI интерфейс - Добавлен фраемворr Walles - Удалена консольная версия - Проработан интерфейс и дизайн - Добавлено кеширование для быстрой реакции. - Сделан .ps1 сборщик для удобной сборки проекта. - Обновлён Readme
This commit is contained in:
101
Backend/admin/frontend/assets/js/ui/modal.js
Normal file
101
Backend/admin/frontend/assets/js/ui/modal.js
Normal file
@@ -0,0 +1,101 @@
|
||||
/* ============================================
|
||||
Modal Manager
|
||||
Управление модальными окнами
|
||||
============================================ */
|
||||
|
||||
import { $, addClass, removeClass } from '../utils/dom.js';
|
||||
|
||||
/**
|
||||
* Класс для управления модальными окнами
|
||||
*/
|
||||
export class Modal {
|
||||
constructor() {
|
||||
this.overlay = $('modalOverlay');
|
||||
this.title = $('modalTitle');
|
||||
this.content = $('modalContent');
|
||||
this.closeBtn = $('modalCloseBtn');
|
||||
this.cancelBtn = $('modalCancelBtn');
|
||||
this.saveBtn = $('modalSaveBtn');
|
||||
this.fieldEditorOverlay = $('fieldEditorOverlay');
|
||||
this.init();
|
||||
}
|
||||
|
||||
init() {
|
||||
if (this.closeBtn) {
|
||||
this.closeBtn.addEventListener('click', () => this.close());
|
||||
}
|
||||
|
||||
if (this.cancelBtn) {
|
||||
this.cancelBtn.addEventListener('click', () => this.close());
|
||||
}
|
||||
|
||||
if (this.saveBtn) {
|
||||
this.saveBtn.addEventListener('click', () => {
|
||||
if (window.saveModalData) {
|
||||
window.saveModalData();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (this.overlay) {
|
||||
this.overlay.addEventListener('click', (e) => {
|
||||
if (e.target === this.overlay) {
|
||||
this.close();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Открыть модальное окно
|
||||
* @param {string} title - Заголовок
|
||||
* @param {string} htmlContent - HTML контент
|
||||
*/
|
||||
open(title, htmlContent) {
|
||||
if (this.title) this.title.textContent = title;
|
||||
if (this.content) this.content.innerHTML = htmlContent;
|
||||
if (this.overlay) addClass(this.overlay, 'show');
|
||||
}
|
||||
|
||||
/**
|
||||
* Закрыть модальное окно
|
||||
*/
|
||||
close() {
|
||||
if (this.overlay) removeClass(this.overlay, 'show');
|
||||
}
|
||||
|
||||
/**
|
||||
* Установить обработчик сохранения
|
||||
* @param {Function} callback - Функция обратного вызова
|
||||
*/
|
||||
onSave(callback) {
|
||||
if (this.saveBtn) {
|
||||
this.saveBtn.onclick = callback;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Открыть редактор поля
|
||||
* @param {string} title - Заголовок
|
||||
* @param {string} htmlContent - HTML контент
|
||||
*/
|
||||
openFieldEditor(title, htmlContent) {
|
||||
const fieldTitle = $('fieldEditorTitle');
|
||||
const fieldContent = $('fieldEditorContent');
|
||||
|
||||
if (fieldTitle) fieldTitle.textContent = title;
|
||||
if (fieldContent) fieldContent.innerHTML = htmlContent;
|
||||
if (this.fieldEditorOverlay) addClass(this.fieldEditorOverlay, 'show');
|
||||
}
|
||||
|
||||
/**
|
||||
* Закрыть редактор поля
|
||||
*/
|
||||
closeFieldEditor() {
|
||||
if (this.fieldEditorOverlay) removeClass(this.fieldEditorOverlay, 'show');
|
||||
}
|
||||
}
|
||||
|
||||
// Глобальный экземпляр модального окна
|
||||
export const modal = new Modal();
|
||||
|
||||
67
Backend/admin/frontend/assets/js/ui/navigation.js
Normal file
67
Backend/admin/frontend/assets/js/ui/navigation.js
Normal file
@@ -0,0 +1,67 @@
|
||||
/* ============================================
|
||||
Navigation
|
||||
Управление навигацией
|
||||
============================================ */
|
||||
|
||||
import { $, $$, hide, show, removeClass, addClass } from '../utils/dom.js';
|
||||
|
||||
/**
|
||||
* Класс для управления навигацией
|
||||
*/
|
||||
export class Navigation {
|
||||
constructor() {
|
||||
this.navItems = $$('.nav-item');
|
||||
this.sections = {
|
||||
services: $('sectionServices'),
|
||||
sites: $('sectionSites'),
|
||||
proxy: $('sectionProxy'),
|
||||
settings: $('sectionSettings'),
|
||||
vaccess: $('sectionVAccessEditor')
|
||||
};
|
||||
this.init();
|
||||
}
|
||||
|
||||
init() {
|
||||
this.navItems.forEach((item, index) => {
|
||||
item.addEventListener('click', () => this.navigate(index));
|
||||
});
|
||||
}
|
||||
|
||||
navigate(index) {
|
||||
// Убираем active со всех навигационных элементов
|
||||
this.navItems.forEach(nav => removeClass(nav, 'active'));
|
||||
addClass(this.navItems[index], 'active');
|
||||
|
||||
// Скрываем все секции
|
||||
this.hideAllSections();
|
||||
|
||||
// Показываем нужные секции
|
||||
if (index === 0) {
|
||||
// Главная - всё кроме настроек
|
||||
show(this.sections.services);
|
||||
show(this.sections.sites);
|
||||
show(this.sections.proxy);
|
||||
} else if (index === 3) {
|
||||
// Настройки
|
||||
show(this.sections.settings);
|
||||
// Загружаем конфигурацию при открытии
|
||||
if (window.loadConfig) {
|
||||
window.loadConfig();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
hideAllSections() {
|
||||
Object.values(this.sections).forEach(section => {
|
||||
if (section) hide(section);
|
||||
});
|
||||
}
|
||||
|
||||
showDashboard() {
|
||||
this.hideAllSections();
|
||||
show(this.sections.services);
|
||||
show(this.sections.sites);
|
||||
show(this.sections.proxy);
|
||||
}
|
||||
}
|
||||
|
||||
81
Backend/admin/frontend/assets/js/ui/notification.js
Normal file
81
Backend/admin/frontend/assets/js/ui/notification.js
Normal file
@@ -0,0 +1,81 @@
|
||||
/* ============================================
|
||||
Notification System
|
||||
Система уведомлений
|
||||
============================================ */
|
||||
|
||||
import { $, addClass, removeClass } from '../utils/dom.js';
|
||||
|
||||
/**
|
||||
* Класс для управления уведомлениями
|
||||
*/
|
||||
export class NotificationManager {
|
||||
constructor() {
|
||||
this.container = $('notification');
|
||||
this.loader = $('appLoader');
|
||||
}
|
||||
|
||||
/**
|
||||
* Показать уведомление
|
||||
* @param {string} message - Текст сообщения
|
||||
* @param {string} type - Тип (success, error)
|
||||
* @param {number} duration - Длительность показа (мс)
|
||||
*/
|
||||
show(message, type = 'success', duration = 1000) {
|
||||
if (!this.container) return;
|
||||
|
||||
const icon = type === 'success'
|
||||
? '<i class="fas fa-check-circle"></i>'
|
||||
: '<i class="fas fa-exclamation-circle"></i>';
|
||||
|
||||
this.container.innerHTML = `
|
||||
<div class="notification-content">
|
||||
<div class="notification-icon">${icon}</div>
|
||||
<div class="notification-text">${message}</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
this.container.className = `notification show ${type}`;
|
||||
|
||||
setTimeout(() => {
|
||||
removeClass(this.container, 'show');
|
||||
}, duration);
|
||||
}
|
||||
|
||||
/**
|
||||
* Показать успешное уведомление
|
||||
* @param {string} message - Текст сообщения
|
||||
* @param {number} duration - Длительность
|
||||
*/
|
||||
success(message, duration = 1000) {
|
||||
this.show(message, 'success', duration);
|
||||
}
|
||||
|
||||
/**
|
||||
* Показать уведомление об ошибке
|
||||
* @param {string} message - Текст сообщения
|
||||
* @param {number} duration - Длительность
|
||||
*/
|
||||
error(message, duration = 2000) {
|
||||
this.show(message, 'error', duration);
|
||||
}
|
||||
|
||||
/**
|
||||
* Скрыть загрузчик приложения
|
||||
*/
|
||||
hideLoader() {
|
||||
if (!this.loader) return;
|
||||
|
||||
setTimeout(() => {
|
||||
addClass(this.loader, 'hide');
|
||||
setTimeout(() => {
|
||||
if (this.loader.parentNode) {
|
||||
this.loader.remove();
|
||||
}
|
||||
}, 500);
|
||||
}, 1500);
|
||||
}
|
||||
}
|
||||
|
||||
// Глобальный экземпляр менеджера уведомлений
|
||||
export const notification = new NotificationManager();
|
||||
|
||||
51
Backend/admin/frontend/assets/js/ui/window.js
Normal file
51
Backend/admin/frontend/assets/js/ui/window.js
Normal file
@@ -0,0 +1,51 @@
|
||||
/* ============================================
|
||||
Window Controls
|
||||
Управление окном приложения
|
||||
============================================ */
|
||||
|
||||
import { $, addClass } from '../utils/dom.js';
|
||||
|
||||
/**
|
||||
* Класс для управления окном
|
||||
*/
|
||||
export class WindowControls {
|
||||
constructor() {
|
||||
this.minimizeBtn = $('minimizeBtn');
|
||||
this.maximizeBtn = $('maximizeBtn');
|
||||
this.closeBtn = $('closeBtn');
|
||||
this.init();
|
||||
}
|
||||
|
||||
init() {
|
||||
if (this.minimizeBtn) {
|
||||
this.minimizeBtn.addEventListener('click', () => this.minimize());
|
||||
}
|
||||
|
||||
if (this.maximizeBtn) {
|
||||
this.maximizeBtn.addEventListener('click', () => this.maximize());
|
||||
}
|
||||
|
||||
if (this.closeBtn) {
|
||||
this.closeBtn.addEventListener('click', () => this.close());
|
||||
}
|
||||
}
|
||||
|
||||
minimize() {
|
||||
if (window.runtime?.WindowMinimise) {
|
||||
window.runtime.WindowMinimise();
|
||||
}
|
||||
}
|
||||
|
||||
maximize() {
|
||||
if (window.runtime?.WindowToggleMaximise) {
|
||||
window.runtime.WindowToggleMaximise();
|
||||
}
|
||||
}
|
||||
|
||||
close() {
|
||||
if (window.runtime?.Quit) {
|
||||
window.runtime.Quit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user