componentPanel.js

12.65 KB
12/10/2025 04:33
JS
componentPanel.js
/**
 * Component Panel Module
 * จัดการแผงคอมโพเนนต์และการเพิ่มคอมโพเนนต์
 */
(function(global) {
  'use strict';

  /**
   * คลาส ComponentPanel
   * จัดการแผงคอมโพเนนต์และการเพิ่มคอมโพเนนต์
   */
  class ComponentPanel {
    constructor(editor) {
      this.editor = editor;
      this.componentItems = {};
      this.categories = {};
      this.activeCategory = 'all';
    }

    /**
     * เริ่มต้นโมดูลแผงคอมโพเนนต์
     */
    init() {
      this.setupEventListeners();
      this.organizeComponents();

      if (this.editor.config.debug) {
        console.log('ComponentPanel เริ่มต้นแล้ว');
      }
    }

    /**
     * จัดระเบียบคอมโพเนนต์
     */
    organizeComponents() {
      // จัดกลุ่มคอมโพเนนต์ตามหมวดหมู่
      this.categories = {
        all: {name: 'ทั้งหมด', icon: 'apps'},
        layout: {name: 'เลย์เอาต์', icon: 'dashboard'},
        content: {name: 'เนื้อหา', icon: 'description'},
        media: {name: 'สื่อ', icon: 'perm_media'}, // แก้ไขแล้ว
        navigation: {name: 'การนำทาง', icon: 'menu'},
        forms: {name: 'ฟอร์ม', icon: 'input'}
      };

      // จัดกลุ่มรายการคอมโพเนนต์
      this.componentItems = {
        header: {
          id: 'header',
          name: 'ส่วนหัว',
          icon: 'header',
          description: 'ส่วนหัวของเว็บไซต์',
          category: 'layout'
        },
        footer: {
          id: 'footer',
          name: 'ส่วนท้าย',
          icon: 'footer',
          description: 'ส่วนท้ายของเว็บไซต์',
          category: 'layout'
        },
        hero: {
          id: 'hero',
          name: 'Hero Section',
          icon: 'view_carousel',
          description: 'ส่วนแสดงผลหลัก',
          category: 'layout'
        },
        section: {
          id: 'section',
          name: 'ส่วน',
          icon: 'view_module',
          description: 'ส่วนเนื้อหา',
          category: 'layout'
        },
        container: {
          id: 'container',
          name: 'คอนเทนเนอร์',
          icon: 'crop_square',
          description: 'คอนเทนเนอร์เนื้อหา',
          category: 'layout'
        },
        grid: {
          id: 'grid',
          name: 'กริด',
          icon: 'grid_on',
          description: 'เลย์เอาต์กริด',
          category: 'layout'
        },
        card: {
          id: 'card',
          name: 'การ์ด',
          icon: 'style',
          description: 'การ์ดเนื้อหา',
          category: 'content'
        },
        text: {
          id: 'text',
          name: 'ข้อความ',
          icon: 'text_fields',
          description: 'บล็อกข้อความ',
          category: 'content'
        },
        heading: {
          id: 'heading',
          name: 'หัวข้อ',
          icon: 'title',
          description: 'หัวข้อข้อความ',
          category: 'content'
        },
        list: {
          id: 'list',
          name: 'รายการ',
          icon: 'format_list_bulleted',
          description: 'รายการข้อความ',
          category: 'content'
        },
        quote: {
          id: 'quote',
          name: 'คำพูด',
          icon: 'format_quote',
          description: 'บล็อกคำพูด',
          category: 'content'
        },
        image: {
          id: 'image',
          name: 'รูปภาพ',
          icon: 'image',
          description: 'รูปภาพ',
          category: 'media'
        },
        video: {
          id: 'video',
          name: 'วิดีโอ',
          icon: 'videocam',
          description: 'วิดีโอ',
          category: 'media'
        },
        carousel: {
          id: 'carousel',
          name: 'Carousel',
          icon: 'slideshow',
          description: 'สไลด์โชว์รูปภาพ',
          category: 'media'
        },
        gallery: {
          id: 'gallery',
          name: 'แกลเลอรี',
          icon: 'collections',
          description: 'แกลเลอรีรูปภาพ',
          category: 'media'
        },
        nav: {
          id: 'nav',
          name: 'เมนูนำทาง',
          icon: 'menu',
          description: 'เมนูนำทาง',
          category: 'navigation'
        },
        breadcrumb: {
          id: 'breadcrumb',
          name: 'เส้นทาง',
          icon: 'arrow_right_alt',
          description: 'เส้นทางนำทาง',
          category: 'navigation'
        },
        pagination: {
          id: 'pagination',
          name: 'การแบ่งหน้า',
          icon: 'last_page',
          description: 'การแบ่งหน้า',
          category: 'navigation'
        },
        button: {
          id: 'button',
          name: 'ปุ่ม',
          icon: 'touch_app',
          description: 'ปุ่มคลิก',
          category: 'forms'
        },
        form: {
          id: 'form',
          name: 'ฟอร์ม',
          icon: 'input',
          description: 'ฟอร์มข้อมูล',
          category: 'forms'
        },
        input: {
          id: 'input',
          name: 'ช่องกรอก',
          icon: 'text_format',
          description: 'ช่องกรอกข้อมูล',
          category: 'forms'
        },
        textarea: {
          id: 'textarea',
          name: 'ช่องข้อความ',
          icon: 'subject',
          description: 'ช่องกรอกข้อความยาว',
          category: 'forms'
        },
        select: {
          id: 'select',
          name: 'เมนูเลือก',
          icon: 'arrow_drop_down',
          description: 'เมนูเลือกข้อมูล',
          category: 'forms'
        },
        checkbox: {
          id: 'checkbox',
          name: 'ช่องทำเครื่องหมาย',
          icon: 'check_box',
          description: 'ช่องทำเครื่องหมาย',
          category: 'forms'
        },
        radio: {
          id: 'radio',
          name: 'ปุ่มเลือก',
          icon: 'radio_button_checked',
          description: 'ปุ่มเลือกข้อมูล',
          category: 'forms'
        }
      };

      // สร้าง UI หมวดหมู่
      this.createCategoryUI();

      // สร้าง UI รายการคอมโพเนนต์
      this.createComponentUI();
    }

    /**
     * สร้าง UI หมวดหมู่
     */
    createCategoryUI() {
      const panel = document.getElementById('editor-component-panel');
      if (!panel) return;

      // สร้างแท็บหมวดหมู่
      const tabs = this.editor.domUtils.createElement('div', {
        'class': 'component-tabs'
      });

      Object.keys(this.categories).forEach(categoryId => {
        const category = this.categories[categoryId];
        const tab = this.editor.domUtils.createElement('button', {
          'class': 'component-tab',
          'data-category': categoryId
        }, `<i class="material-icons">${category.icon}</i> ${category.name}`);

        // เพิ่ม event listener
        tab.addEventListener('click', () => {
          this.setActiveCategory(categoryId);
        });

        tabs.appendChild(tab);
      });

      // เพิ่มแท็บในแผง
      const header = panel.querySelector('h3');
      header.insertAdjacentElement('afterend', tabs);

      // ตั้งค่าหมวดหมู่ที่ใช้งานอยู่
      this.setActiveCategory('all');
    }

    /**
     * สร้าง UI รายการคอมโพเนนต์
     */
    createComponentUI() {
      const panel = document.getElementById('editor-component-panel');
      if (!panel) return;

      // ค้นหาเนื้อหาแผง
      const content = panel.querySelector('.component-panel-content');
      if (!content) return;

      // ล้างเนื้อหาเก่า
      content.innerHTML = '';

      // สร้างรายการคอมโพเนนต์
      Object.keys(this.componentItems).forEach(componentId => {
        const component = this.componentItems[componentId];

        // สร้างรายการคอมโพเนนต์
        const item = this.editor.domUtils.createElement('div', {
          'class': 'editor-component-item',
          'data-component': componentId,
          'data-category': component.category,
          'draggable': 'true'
        });

        const icon = this.editor.domUtils.createElement('i', {
          'class': 'material-icons'
        }, component.icon);

        const name = this.editor.domUtils.createElement('h4', {}, component.name);
        const description = this.editor.domUtils.createElement('p', {}, component.description);

        item.appendChild(icon);
        item.appendChild(name);
        item.appendChild(description);

        // เพิ่ม event listeners
        item.addEventListener('dragstart', (e) => {
          this.handleComponentDragStart(e, componentId);
        });

        item.addEventListener('dragend', (e) => {
          this.handleComponentDragEnd(e);
        });

        content.appendChild(item);
      });
    }

    /**
     * ตั้งค่าหมวดหมู่ที่ใช้งานอยู่
     */
    setActiveCategory(categoryId) {
      this.activeCategory = categoryId;

      // อัปเดตแท็บ
      const tabs = document.querySelectorAll('.component-tab');
      tabs.forEach(tab => {
        if (tab.getAttribute('data-category') === categoryId) {
          tab.classList.add('active');
        } else {
          tab.classList.remove('active');
        }
      });

      // กรองรายการคอมโพเนนต์
      const items = document.querySelectorAll('.editor-component-item');
      items.forEach(item => {
        if (categoryId === 'all' || item.getAttribute('data-category') === categoryId) {
          item.style.display = 'flex';
        } else {
          item.style.display = 'none';
        }
      });
    }

    /**
     * จัดการการเริ่มลากคอมโพเนนต์
     */
    handleComponentDragStart(e, componentId) {
      // ตั้งค่าข้อมูลการลาก
      e.dataTransfer.effectAllowed = 'copy';
      e.dataTransfer.setData('text/html', componentId);

      // เพิ่มคลาสการลาก
      e.target.classList.add('editor-dragging');

      // ส่งเหตุการณ์
      this.editor.emit('component:drag-start', {
        component: componentId,
        element: e.target
      });
    }

    /**
     * จัดการสิ้นสุดการลากคอมโพเนนต์
     */
    handleComponentDragEnd(e) {
      // ลบคลาสการลาก
      e.target.classList.remove('editor-dragging');

      // ส่งเหตุการณ์
      this.editor.emit('component:drag-end');
    }

    /**
     * ตั้งค่า event listeners
     */
    setupEventListeners() {
      // ฟังเหตุการณ์การเปลี่ยนแปลงโหมดตัวแก้ไข
      this.editor.on('editor:mode-changed', (data) => {
        if (data.mode === 'edit') {
          this.showComponentPanel();
        } else {
          this.hideComponentPanel();
        }
      });
    }

    /**
     * แสดงแผงคอมโพเนนต์
     */
    showComponentPanel() {
      this.editor.uiManager.showPanel('component');
    }

    /**
     * ซ่อนแผงคอมโพเนนต์
     */
    hideComponentPanel() {
      this.editor.uiManager.hidePanel('component');
    }
  }

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

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