uiManager.js

12.23 KB
12/10/2025 04:51
JS
uiManager.js
/**
 * UI Manager - จัดการคอมโพเนนต์ UI และแผงต่างๆ
 */
(function(global) {
  'use strict';

  /**
   * คลาส UIManager
   * จัดการคอมโพเนนต์ UI และแผงต่างๆ
   */
  class UIManager {
    constructor(editor) {
      this.editor = editor;
      this.panels = {};
      this.toolbars = {};
      this.modals = {};
      this.notifications = [];
      this.activePanel = null;
    }

    /**
     * ลงทะเบียนแผง
     * @param {string} name - ชื่อแผง
     * @param {HTMLElement} element - อิลิเมนต์แผง
     */
    registerPanel(name, element) {
      this.panels[name] = element;

      // เพิ่มคลาสพื้นฐาน
      element.classList.add('editor-panel');

      // ซ่อนแผงเริ่มต้น
      element.style.display = 'none';
    }

    /**
     * ลงทะเบียนแถบเครื่องมือ
     * @param {string} name - ชื่อแถบเครื่องมือ
     * @param {HTMLElement} element - อิลิเมนต์แถบเครื่องมือ
     */
    registerToolbar(name, element) {
      this.toolbars[name] = element;

      // เพิ่มคลาสพื้นฐาน
      element.classList.add('editor-toolbar');
    }

    /**
     * ลงทะเบียนโมดัล
     * @param {string} name - ชื่อโมดัล
     * @param {HTMLElement} element - อิลิเมนต์โมดัล
     */
    registerModal(name, element) {
      this.modals[name] = element;

      // เพิ่มคลาสพื้นฐาน
      element.classList.add('editor-modal');

      // ซ่อนโมดัลเริ่มต้น
      element.style.display = 'none';

      // เพิ่มปุ่มปิด
      const closeButton = document.createElement('button');
      closeButton.className = 'editor-modal-close';
      closeButton.innerHTML = '×';
      closeButton.addEventListener('click', () => {
        this.hideModal(name);
      });

      element.appendChild(closeButton);
    }

    /**
     * แสดงแผง
     * @param {string} name - ชื่อแผง
     */
    showPanel(name) {
      if (!this.panels[name]) {
        console.error(`Panel '${name}' is not registered`);
        return;
      }

      // ซ่อนแผงที่ใช้งานอยู่ก่อนหน้า
      if (this.activePanel && this.activePanel !== name) {
        this.hidePanel(this.activePanel);
      }

      const panel = this.panels[name];
      panel.style.display = 'block';

      // เพิ่มคลาสที่ใช้งาน
      setTimeout(() => {
        panel.classList.add('editor-panel-active');
      }, 10);

      this.activePanel = name;

      // ส่งเหตุการณ์
      this.editor.emit('ui:panel-shown', {name});
    }

    /**
     * ซ่อนแผง
     * @param {string} name - ชื่อแผง
     */
    hidePanel(name) {
      if (!this.panels[name]) {
        console.error(`Panel '${name}' is not registered`);
        return;
      }

      const panel = this.panels[name];
      panel.classList.remove('editor-panel-active');

      // ซ่อนหลังจากแอนิเมชัน
      setTimeout(() => {
        panel.style.display = 'none';
      }, 300);

      if (this.activePanel === name) {
        this.activePanel = null;
      }

      // ส่งเหตุการณ์
      this.editor.emit('ui:panel-hidden', {name});
    }

    /**
     * สลับการแสดงแผง
     * @param {string} name - ชื่อแผง
     */
    togglePanel(name) {
      if (this.activePanel === name) {
        this.hidePanel(name);
      } else {
        this.showPanel(name);
      }
    }

    /**
     * แสดงแถบเครื่องมือ
     * @param {string} name - ชื่อแถบเครื่องมือ
     */
    showToolbar(name) {
      if (!this.toolbars[name]) {
        console.error(`Toolbar '${name}' is not registered`);
        return;
      }

      const toolbar = this.toolbars[name];
      toolbar.style.display = 'flex';

      // ส่งเหตุการณ์
      this.editor.emit('ui:toolbar-shown', {name});
    }

    /**
     * ซ่อนแถบเครื่องมือ
     * @param {string} name - ชื่อแถบเครื่องมือ
     */
    hideToolbar(name) {
      if (!this.toolbars[name]) {
        console.error(`Toolbar '${name}' is not registered`);
        return;
      }

      const toolbar = this.toolbars[name];
      toolbar.style.display = 'none';

      // ส่งเหตุการณ์
      this.editor.emit('ui:toolbar-hidden', {name});
    }

    /**
     * แสดงโมดัล
     * @param {string} name - ชื่อโมดัล
     * @param {Object} options - ตัวเลือก (optional)
     */
    showModal(name, options = {}) {
      if (!this.modals[name]) {
        console.error(`Modal '${name}' is not registered`);
        return;
      }

      const modal = this.modals[name];

      // ตั้งค่าตัวเลือก
      if (options.title) {
        const titleElement = modal.querySelector('.editor-modal-title');
        if (titleElement) {
          titleElement.textContent = options.title;
        }
      }

      if (options.content) {
        const contentElement = modal.querySelector('.editor-modal-content');
        if (contentElement) {
          contentElement.innerHTML = options.content;
        }
      }

      // สร้าง overlay
      let overlay = document.querySelector('.editor-modal-overlay');
      if (!overlay) {
        overlay = document.createElement('div');
        overlay.className = 'editor-modal-overlay';
        document.body.appendChild(overlay);

        // เพิ่ม event listener สำหรับคลิก overlay
        overlay.addEventListener('click', () => {
          this.hideModal(name);
        });
      }

      // แสดง overlay และโมดัล
      overlay.style.display = 'block';
      modal.style.display = 'block';

      // เพิ่มคลาสที่ใช้งาน
      setTimeout(() => {
        overlay.classList.add('editor-modal-overlay-active');
        modal.classList.add('editor-modal-active');
      }, 10);

      // ส่งเหตุการณ์
      this.editor.emit('ui:modal-shown', {name, options});
    }

    /**
     * ซ่อนโมดัล
     * @param {string} name - ชื่อโมดัล
     */
    hideModal(name) {
      if (!this.modals[name]) {
        console.error(`Modal '${name}' is not registered`);
        return;
      }

      const modal = this.modals[name];
      const overlay = document.querySelector('.editor-modal-overlay');

      // ลบคลาสที่ใช้งาน
      modal.classList.remove('editor-modal-active');

      if (overlay) {
        overlay.classList.remove('editor-modal-overlay-active');
      }

      // ซ่อนหลังจากแอนิเมชัน
      setTimeout(() => {
        modal.style.display = 'none';

        if (overlay) {
          overlay.style.display = 'none';
        }
      }, 300);

      // ส่งเหตุการณ์
      this.editor.emit('ui:modal-hidden', {name});
    }

    /**
     * แสดงการแจ้งเตือน
     * @param {string} message - ข้อความแจ้งเตือน
     * @param {string} type - ประเภท (info, success, warning, error)
     * @param {number} duration - ระยะเวลาแสดง (ms)
     */
    showNotification(message, type = 'info', duration = 3000) {
      // สร้างอิลิเมนต์การแจ้งเตือน
      const notification = document.createElement('div');
      notification.className = `editor-notification editor-notification-${type}`;
      notification.textContent = message;

      // เพิ่มไอคอนตามประเภท
      const icon = document.createElement('i');
      icon.className = 'material-icons';

      switch (type) {
        case 'success':
          icon.textContent = 'check_circle';
          break;
        case 'warning':
          icon.textContent = 'warning';
          break;
        case 'error':
          icon.textContent = 'error';
          break;
        default:
          icon.textContent = 'info';
      }

      notification.insertBefore(icon, notification.firstChild);

      // เพิ่มปุ่มปิด
      const closeButton = document.createElement('button');
      closeButton.className = 'editor-notification-close';
      closeButton.innerHTML = '×';
      closeButton.addEventListener('click', () => {
        this.hideNotification(notification);
      });

      notification.appendChild(closeButton);

      // เพิ่มในคอนเทนเนอร์การแจ้งเตือน
      let container = document.querySelector('.editor-notifications-container');
      if (!container) {
        container = document.createElement('div');
        container.className = 'editor-notifications-container';
        document.body.appendChild(container);
      }

      container.appendChild(notification);

      // เพิ่มในรายการการแจ้งเตือน
      this.notifications.push(notification);

      // แสดงการแจ้งเตือน
      setTimeout(() => {
        notification.classList.add('editor-notification-show');
      }, 10);

      // ซ่อนอัตโนมัติหลังจากระยะเวลาที่กำหนด
      if (duration > 0) {
        setTimeout(() => {
          this.hideNotification(notification);
        }, duration);
      }

      // ส่งเหตุการณ์
      this.editor.emit('ui:notification-shown', {message, type});
    }

    /**
     * ซ่อนการแจ้งเตือน
     * @param {HTMLElement} notification - อิลิเมนต์การแจ้งเตือน
     */
    hideNotification(notification) {
      if (!notification || !notification.parentNode) return;

      // ลบคลาสที่ใช้งาน
      notification.classList.remove('editor-notification-show');

      // ลบหลังจากแอนิเมชัน
      setTimeout(() => {
        if (notification.parentNode) {
          notification.parentNode.removeChild(notification);
        }

        // ลบจากรายการ
        const index = this.notifications.indexOf(notification);
        if (index > -1) {
          this.notifications.splice(index, 1);
        }
      }, 300);
    }

    /**
     * ซ่อนการแจ้งเตือนทั้งหมด
     */
    hideAllNotifications() {
      const notifications = [...this.notifications];
      notifications.forEach(notification => {
        this.hideNotification(notification);
      });
    }

    /**
     * รับแผง
     * @param {string} name - ชื่อแผง
     * @returns {HTMLElement} อิลิเมนต์แผง
     */
    getPanel(name) {
      return this.panels[name] || null;
    }

    /**
     * รับแถบเครื่องมือ
     * @param {string} name - ชื่อแถบเครื่องมือ
     * @returns {HTMLElement} อิลิเมนต์แถบเครื่องมือ
     */
    getToolbar(name) {
      return this.toolbars[name] || null;
    }

    /**
     * รับโมดัล
     * @param {string} name - ชื่อโมดัล
     * @returns {HTMLElement} อิลิเมนต์โมดัล
     */
    getModal(name) {
      return this.modals[name] || null;
    }

    /**
     * รับแผงที่ใช้งานอยู่
     * @returns {string} ชื่อแผงที่ใช้งานอยู่
     */
    getActivePanel() {
      return this.activePanel;
    }
  }

  // เปิดเผยคลาส UIManager ทั่วโลก
  global.UIManager = UIManager;

})(typeof window !== 'undefined' ? window : this);