module_matrix-1.0.2/js/module-matrix/ui-generator.js

js/module-matrix/ui-generator.js
/**
 * @file ui-generator.js
 * UI creation and management functions
 */

window.ModuleMatrix = window.ModuleMatrix || {};

window.ModuleMatrix.UIGenerator = {

  /**
   * Generate complete sidebar navigation
   */
  generateSidebarNavigation(sidebarSelector, data) {
    const { DataManager } = window.ModuleMatrix;
    const sidebar = document.querySelector(sidebarSelector);
    if (!sidebar) return;

    sidebar.innerHTML = '';

    const stats = DataManager.getPackageStats(data);

    // Create "All Modules" link
    const allModulesLink = this.createSidebarLink(
      'All Modules',
      'all',
      ['package-link', 'package-link-all', 'active'],
      stats.totalModules,
      stats.totalEnabled,
      stats.totalDisabled
    );
    sidebar.appendChild(allModulesLink);

    // Create package-specific links
    Object.entries(data.packageCounts).forEach(([packageName, count]) => {
      const packageCounts = DataManager.getPackageCounts(data, packageName);

      const link = this.createSidebarLink(
        packageName,
        packageName,
        ['package-link'],
        packageCounts.total,
        packageCounts.enabled,
        packageCounts.disabled
      );
      sidebar.appendChild(link);
    });
  },

  /**
   * Create individual sidebar link element
   */
  createSidebarLink(label, packageName, classList, total, enabled, disabled) {
    const link = document.createElement('a');
    link.href = '#';
    link.dataset.package = packageName;

    classList.forEach(className => link.classList.add(className));

    const leftContainer = this.createLeftContainer(label);
    const rightContainer = this.createRightContainer(total, enabled, disabled);

    link.append(leftContainer, rightContainer);
    return link;
  },

  /**
   * Create left side of sidebar link (icon + label)
   */
  createLeftContainer(label) {
    const { CLASSES, DEFAULTS } = window.ModuleMatrix.Constants;
    const { Utils } = window.ModuleMatrix;

    const container = Utils.createElement('div', CLASSES.packageLinkLeft);

    const icon = Utils.createElement('span', CLASSES.materialIcons, DEFAULTS.categoryIcon);
    const labelSpan = Utils.createElement('span', CLASSES.packageLabel, label);

    container.append(icon, labelSpan);
    return container;
  },

  /**
   * Create right side of sidebar link (counts)
   */
  createRightContainer(total, enabled, disabled) {
    const { CLASSES } = window.ModuleMatrix.Constants;
    const { Utils } = window.ModuleMatrix;

    const container = Utils.createElement('div', CLASSES.packageLinkRight);
    const fragment = this.createCountFragment(total, enabled, disabled);

    container.appendChild(fragment);
    return container;
  },

  /**
   * Create count display fragment
   */
  createCountFragment(total, enabled, disabled) {
    const { CLASSES } = window.ModuleMatrix.Constants;
    const { Utils } = window.ModuleMatrix;

    const fragment = document.createDocumentFragment();

    fragment.append(
      Utils.createElement('span', CLASSES.totalCount, total),
      Utils.createElement('span', CLASSES.enabledCount, enabled),
      document.createTextNode('/'),
      Utils.createElement('span', CLASSES.disabledCount, disabled)
    );

    return fragment;
  },

  /**
   * Populate and sort module list
   */
  populateModuleList(containerSelector, modules) {
    const { Utils } = window.ModuleMatrix;
    const container = document.querySelector(containerSelector);
    if (!container) return;

    // Sort modules alphabetically
    const sortedModules = Utils.sortModuleDataByName(modules);

    // Extract elements and populate container
    const elements = sortedModules.map(module => module.element);
    Utils.clearAndAppend(container, elements);
  },

  /**
   * Create loading indicator
   */
  createLoadingIndicator() {
    const { Utils } = window.ModuleMatrix;

    const loader = Utils.createElement('div', 'module-matrix-loader');
    const spinner = Utils.createElement('div', 'spinner');
    const text = Utils.createElement('span', 'loading-text', 'Loading modules...');

    loader.append(spinner, text);
    return loader;
  },

  /**
   * Create empty state message
   */
  createEmptyState(message = 'No modules found') {
    const { Utils } = window.ModuleMatrix;

    const emptyState = Utils.createElement('div', 'module-matrix-empty');
    const icon = Utils.createElement('span', 'material-icons', 'inbox');
    const text = Utils.createElement('p', 'empty-text', message);

    emptyState.append(icon, text);
    return emptyState;
  },

  /**
   * Create filter summary display
   */
  createFilterSummary(visibleCount, totalCount) {
    const { Utils } = window.ModuleMatrix;

    const summary = Utils.createElement('div', 'filter-summary');
    const text = visibleCount === totalCount
      ? `Showing all ${totalCount} modules`
      : `Showing ${visibleCount} of ${totalCount} modules`;

    summary.textContent = text;
    return summary;
  },

  /**
   * Update filter summary
   */
  updateFilterSummary(container, visibleCount, totalCount) {
    const existingSummary = container.querySelector('.filter-summary');
    if (existingSummary) {
      existingSummary.remove();
    }

    const newSummary = this.createFilterSummary(visibleCount, totalCount);
    container.insertBefore(newSummary, container.firstChild);
  },

  /**
   * Create breadcrumb navigation
   */
  createBreadcrumb(activePackage) {
    const { Utils } = window.ModuleMatrix;
    const { DEFAULTS } = window.ModuleMatrix.Constants;

    const breadcrumb = Utils.createElement('nav', 'module-matrix-breadcrumb');
    const homeLink = Utils.createElement('a', 'breadcrumb-home', 'All Modules');
    homeLink.href = '#';
    homeLink.dataset.package = DEFAULTS.activePackage;

    breadcrumb.appendChild(homeLink);

    if (activePackage !== DEFAULTS.activePackage) {
      const separator = Utils.createElement('span', 'breadcrumb-separator', ' / ');
      const currentPage = Utils.createElement('span', 'breadcrumb-current', activePackage);
      breadcrumb.append(separator, currentPage);
    }

    return breadcrumb;
  },

  /**
   * Create action buttons container
   */
  createActionButtons() {
    const { Utils } = window.ModuleMatrix;

    const container = Utils.createElement('div', 'module-matrix-actions');

    const resetButton = Utils.createElement('button', 'btn btn-secondary', 'Reset Filters');
    resetButton.type = 'button';
    resetButton.id = 'reset-filters';

    const exportButton = Utils.createElement('button', 'btn btn-outline-secondary', 'Export List');
    exportButton.type = 'button';

    container.append(resetButton, exportButton);
    return container;
  },

  /**
   * Create tooltip element
   */
  createTooltip(text, targetElement) {
    const { Utils } = window.ModuleMatrix;

    const tooltip = Utils.createElement('div', 'module-matrix-tooltip', text);
    tooltip.style.position = 'absolute';
    tooltip.style.visibility = 'hidden';

    targetElement.addEventListener('mouseenter', () => {
      this.showTooltip(tooltip, targetElement);
    });

    targetElement.addEventListener('mouseleave', () => {
      this.hideTooltip(tooltip);
    });

    document.body.appendChild(tooltip);
    return tooltip;
  },

  /**
   * Show tooltip with positioning
   */
  showTooltip(tooltip, targetElement) {
    const rect = targetElement.getBoundingClientRect();
    tooltip.style.left = rect.left + (rect.width / 2) + 'px';
    tooltip.style.top = (rect.top - tooltip.offsetHeight - 5) + 'px';
    tooltip.style.visibility = 'visible';
  },

  /**
   * Hide tooltip
   */
  hideTooltip(tooltip) {
    tooltip.style.visibility = 'hidden';
  },

  /**
   * Create notification/alert
   */
  createNotification(message, type = 'info') {
    const { Utils } = window.ModuleMatrix;

    const notification = Utils.createElement('div', `alert alert-${type}`);
    notification.textContent = message;

    // Auto-dismiss after 5 seconds
    setTimeout(() => {
      if (notification.parentNode) {
        notification.remove();
      }
    }, 5000);

    return notification;
  },

  /**
   * Show notification
   */
  showNotification(message, type = 'info') {
    const notification = this.createNotification(message, type);

    // Insert at top of the main form
    const form = document.querySelector('form#system-modules');
    if (form) {
      form.insertBefore(notification, form.firstChild);
    }

    return notification;
  }
};

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc